CACS351 Mobile Programming

Mobile ProgrammingUnit 920 min read

Maps, APIs, External Services: Google Maps, REST APIs, Web Services & Location-Based Apps

Unit 9 of Mobile Programming: Covers how Android apps integrate Google Maps API, RESTful APIs, location services, and external web services (e.g., weather, payment gateways) to fetch data, display maps, and enable real-world functionality—with hands-on examples for API key generation, marker placement, and data exchang

TAKEAWAYS

  • APIs (Application Programming Interfaces) act as messengers between apps and external services (e.g., Google Maps, payment gateways), enabling data exchange without exposing source code.
  • Google Maps API lets apps display maps, markers, and directions using a unique API key tied to your project’s credentials.
  • REST APIs (e.g., JSON-based weather data) allow apps to fetch structured data from web services (e.g., OpenWeatherMap) for features like live updates.
  • Location services (GPS, network providers) provide real-time coordinates, which apps use for navigation (e.g., Pathao) or geotagging (e.g., Instagram).
  • Web services (e.g., eSewa’s payment API) handle transactions securely by validating requests via API keys and tokens.
  • Error handling in APIs (e.g., invalid keys, network failures) requires robust checks to avoid crashes (e.g., retry logic or user feedback).

1. Introduction to APIs in Mobile Development

APIs are contracts that define how software components communicate. In mobile apps, they bridge:

  • Client-side (your Android app) ↔ Server-side (Google Maps, eSewa, OpenWeatherMap).
  • Data sources (databases, sensors) ↔ App logic (UI, processing).

Types of APIs

flowchart TD
    A["API Types"] --> B["REST API"]
    A --> C["SOAP API"]
    A --> D["GraphQL"]
    A --> E["Google Maps API"]
    A --> F["Location API"]
    B --> B1["HTTP/HTTPS-based\n(Stateless, JSON/XML)\n*e.g., OpenWeatherMap*"]
    C --> C1["XML-based\n(WSDL contracts)\n*Legacy systems*"]
    D --> D1["Query-based\n(Fast, flexible)\n*e.g., Facebook Graph API*"]
    E --> E1["Maps, directions,\nmarkers\n*e.g., Google Maps SDK*"]
    F --> F1["GPS/network-based\n*e.g., FusedLocationProvider*"]
    E1 -->|"Example"| G["Android App\nDisplays TU Location"]
    F1 -->|"Example"| H["Pathao Live Tracking"]

Key Differences:

Feature REST API SOAP API Google Maps API
Protocol HTTP/HTTPS SOAP over HTTP/HTTPS HTTP/HTTPS
Data Format JSON/XML XML JSON
State Stateless Stateful Stateless
Use Case Weather, payments Enterprise systems Maps, navigation
Example GET /weather?city=KTM Complex business logic GET /maps?lat=27.7172

Why Use APIs in Android?

  1. Reusability: Avoid reinventing wheels (e.g., use Google Maps instead of building a custom map engine).
  2. Scalability: Handle large datasets (e.g., Daraz’s product catalog via API).
  3. Offline Support: Cache API responses (e.g., NTC’s offline route planner).
  4. Security: APIs enforce authentication (e.g., eSewa’s API requires API keys + tokens).
  5. Real-Time Data: Fetch live updates (e.g., stock prices from NEPSE via API).

2. Google Maps API: Integration & Key Generation

How Google Maps API Works

  1. Request: Your app sends a GET/POST request to Google’s servers with:
    • Latitude/longitude (e.g., 27.7172, 85.3240 for TU).
    • API key (to authenticate your app).
  2. Response: Google returns a map tile (image) or JSON data (e.g., directions).
  3. Rendering: Android’s MapView or SupportMapFragment displays the map.

Step-by-Step: Generating a Google Maps API Key

Enable Google Maps JavaScript APIGenerate API KeyIntegrate API KeyVerify Package NameGoogle Cloud ConsoleAPI CredentialsMaps SDKAndroid App
Workflow for generating and integrating a Google Maps API key in Android development

Prerequisites

Steps

  1. Create a Project in GCP:

    • Go to GCP Console → Create Project → Name it (e.g., TU_MapsDemo).
  2. Enable Google Maps SDK for Android:

    • Navigate to APIs & Services → Library → Search for "Maps SDK for Android" → Enable it.
  3. Get Your API Key:

    • Go to APIs & Services → Credentials → Create Credentials → API Key.
    • Copy the generated key (e.g., AIzaSyD123abc456def7890).
  4. Restrict the Key (Security):

    • Click the key → Restrict Key → Add:
      • Application Restrictions: Select "Android apps" → Add your app’s SHA-1 fingerprint (from keystore).
      • API Restrictions: Enable "Maps SDK for Android".
  5. Use the Key in Android:

    • Add the dependency in build.gradle:
      implementation 'com.google.android.gms:play-services-maps:18.2.0'
      
    • Declare permissions in AndroidManifest.xml:
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      
    • Initialize the map in MainActivity.java:
      public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
          private GoogleMap mMap;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              // Initialize the map
              SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                  .findFragmentById(R.id.map);
              mapFragment.getMapAsync(this);
          }
      
          @Override
          public void onMapReady(GoogleMap googleMap) {
              mMap = googleMap;
              // Add a marker at TU's location
              LatLng tuLocation = new LatLng(27.7172, 85.3240);
              mMap.addMarker(new MarkerOptions()
                  .position(tuLocation)
                  .title("Tribhuvan University"));
              mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(tuLocation, 15f));
          }
      }
      

Visual: Google Maps API Flow

sequenceDiagram
    participant App as Android App
    participant GoogleMaps as Google Maps API
    participant User as User

    App->>GoogleMaps: GET /maps?lat=27.7172&lon=85.3240&key=AIza...
    GoogleMaps-->>App: JSON (Map tiles + Marker data)
    App->>User: Displays map with TU marker

Worked Example: Displaying TU on Google Maps

Goal: Show a marker at TU’s location (27.7172, 85.3240) with a popup title.

Steps:

  1. Add map.xml (layout):
    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
  2. Initialize Map (as shown above).
  3. Result: Google Maps with TU Marker (A map centered on TU with a red marker labeled "Tribhuvan University.")

3. REST APIs: Fetching Data from Web Services

REST APIs are stateless HTTP-based interfaces that return JSON/XML. Example: Fetching weather data.


How REST APIs Work

  1. HTTP Methods:

    • GET: Retrieve data (e.g., GET /weather?city=Kathmandu).
    • POST: Send data (e.g., login credentials).
    • PUT/PATCH: Update data.
    • DELETE: Remove data.
  2. Response Formats:

    • JSON: Lightweight (e.g., OpenWeatherMap).
    • XML: Legacy systems.
  3. Authentication:

    • API Keys: Embedded in requests (e.g., ?api_key=12345).
    • OAuth 2.0: For sensitive data (e.g., eSewa transactions).

Example: Fetching Weather Data (OpenWeatherMap)

API Endpoint: https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}

Java Code to Fetch Weather:

// Add Retrofit dependency in build.gradle
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

// Define API interface
public interface WeatherApi {
    @GET("weather")
    Call<WeatherResponse> getWeather(@Query("q") String city, @Query("appid") String apiKey);
}

// Call the API
WeatherApi api = RetrofitClient.getClient().create(WeatherApi.class);
Call<WeatherResponse> call = api.getWeather("Kathmandu", "YOUR_API_KEY");
call.enqueue(new Callback<WeatherResponse>() {
    @Override
    public void onResponse(Call<WeatherResponse> call, Response<WeatherResponse> response) {
        if (response.isSuccessful()) {
            WeatherResponse weather = response.body();
            Log.d("Weather", "Temp: " + weather.main.temp + "°C");
        }
    }
    @Override
    public void onFailure(Call<WeatherResponse> call, Throwable t) {
        Log.e("Weather", "Error: " + t.getMessage());
    }
});

Sample JSON Response:

{
  "name": "Kathmandu",
  "main": {
    "temp": 25.5,
    "humidity": 65
  }
}

Visual: REST API Request/Response

sequenceDiagram
    participant App as Android App
    participant Server as OpenWeatherMap API
    participant User as User

    App->>Server: GET /weather?q=Kathmandu&appid=YOUR_KEY
    Server-->>App: JSON {"name":"Kathmandu","main":{"temp":25.5}}
    App->>User: Displays "Kathmandu: 25.5°C"

4. Location Services in Android

Android provides Fused Location Provider to fetch GPS/network-based coordinates.


Key Components

Component Description
GPS Provider High-accuracy location (battery-intensive).
Network Provider Lower accuracy (uses cell towers/Wi-Fi).
Fused Location API Combines GPS/network for optimal performance.
LocationListener Callback for real-time updates (e.g., Pathao’s live tracking).

Code: Requesting Location Permissions & Fetching Coordinates

// 1. Add permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

// 2. Request runtime permissions (Android 6.0+)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
        LOCATION_PERMISSION_REQUEST);
}

// 3. Fetch location (in onRequestPermissionsResult)
private void getCurrentLocation() {
    FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        fusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, location -> {
                if (location != null) {
                    double lat = location.getLatitude();
                    double lon = location.getLongitude();
                    Log.d("Location", "Lat: " + lat + ", Lon: " + lon);
                    // Update Google Map with this location
                }
            });
    }
}

Visual: Location Services Flow

flowchart TD
    A["User Opens App"] --> B["Check Permissions\n(ACCESS_FINE_LOCATION)"]
    B -->|"Granted"| C["Request Location\n(FusedLocationProvider)"]
    C --> D["GPS/Network\nProvider"]
    D --> E["Return Coordinates\n(lat, lon)\n(e.g., 27.7172, 85.3240)"]
    E --> F["Update Map\n(Google Maps API)"]
    B -->|"Denied"| G["Show Error\n(No Location Access)"]
    F --> H["Display on UI\n(Real-time marker)"]

Real-World Example: Pathao’s Live Tracking

  • API Used: Google Maps API (for directions) + Fused Location API (for rider location).
  • How It Works:
    1. Pathao’s backend sends the driver’s live coordinates via a REST API.
    2. The app fetches these coordinates every 5 seconds using LocationListener.
    3. Google Maps API updates the marker in real-time on the map.

5. Integrating External Services (eSewa, Daraz, NEPSE)

Example 1: eSewa Payment API

  • API Used: eSewa REST API (for transactions).
  • How It Works:
    1. User selects eSewa as payment method in Daraz.
    2. Daraz sends a POST request to eSewa’s API with:
      {
        "amount": 1000,
        "product_id": "DZ12345",
        "api_key": "eSewa_API_KEY"
      }
      
    3. eSewa validates the request, processes payment, and returns:
      {
        "status": "success",
        "transaction_id": "TXN67890"
      }
      
    4. Daraz updates the order status to "Paid".

Example 2: Daraz Product Catalog via API

  • API Used: Daraz Product API (REST).
  • How It Works:
    1. User searches for "laptop" in Daraz.
    2. Daraz’s backend calls Daraz’s internal API (or a third-party API like Jumia).
    3. The API returns JSON data like:
      [
        {
          "id": "P1001",
          "name": "Dell XPS 15",
          "price": 120000,
          "image": "url_to_image"
        },
        {
          "id": "P1002",
          "name": "MacBook Pro",
          "price": 150000,
          "image": "url_to_image"
        }
      ]
      
    4. Daraz’s app displays these products in a RecyclerView.

Example 3: NEPSE Stock Data via API

  • API Used: NEPSE REST API (for real-time stock prices).
  • How It Works:
    1. A stock app (e.g., Nepal Stock Exchange Mobile App) calls: GET /api/stocks?symbol=NEPSE
    2. NEPSE returns:
      {
        "symbol": "NEPSE",
        "price": 1250.50,
        "last_updated": "2023-10-01T10:30:00Z"
      }
      
    3. The app updates the UI in real-time.

6. Error Handling in APIs

APIs can fail due to:

  • Network issues (no internet).
  • Invalid API keys.
  • Server errors (e.g., 404 Not Found).
  • Rate limits (too many requests).

Best Practices

  1. Check Network Connectivity:
    if (!isNetworkAvailable()) {
        showError("No internet connection");
        return;
    }
    
  2. Handle HTTP Errors:
    if (response.code() == 401) {
        showError("Invalid API key");
    } else if (response.code() == 404) {
        showError("Resource not found");
    }
    
  3. Retry Mechanism:
    int maxRetries = 3;
    for (int i = 0; i < maxRetries; i++) {
        try {
            call.execute();
            break;
        } catch (IOException e) {
            if (i == maxRetries - 1) {
                showError("Failed after retries");
            }
        }
    }
    
  4. Show User-Friendly Messages:
    • Instead of 500 Internal Server Error, show: "Failed to fetch data. Please try again later."

7. Security in API Integration

Threat Mitigation Strategy
API Key Leakage Restrict API keys to specific IPs/apps.
Man-in-the-Middle Use HTTPS (TLS encryption).
Invalid Data Validate all inputs (e.g., check lat/lon ranges).
Brute Force Implement rate limiting (e.g., 100 requests/min).
API Key0OAuth Token1JWT2Encrypted Payload3
Security layers for API integration (OAuth Token highlighted as primary)

In the Real World

  1. Google Maps API in Pathao

    • Idea Used: Google Maps API for real-time driver tracking and route optimization.
    • How: Pathao’s app fetches the driver’s live location via GPS and displays it on a map using Google Maps SDK. Users can also see ETA (Estimated Time of Arrival) based on traffic data from Google Maps.
  2. eSewa’s Payment API in Daraz

    • Idea Used: REST API + OAuth 2.0 for secure transactions.
    • How: When a user selects eSewa to pay for an order, Daraz sends a signed request to eSewa’s API. eSewa validates the request, processes the payment, and returns a transaction ID. Daraz then marks the order as "Paid" in its database.
  3. NEPSE Stock Data in Trading Apps

    • Idea Used: REST API for real-time data.
    • How: Apps like Nepal Stock Exchange Mobile App call NEPSE’s API every 5 seconds to fetch live stock prices. The app then updates the UI dynamically, showing price changes, volume, and trends in real-time.

Exam Tip

Common Exam Patterns

  1. API Types & Use Cases (20-25 marks):

    • Explain REST vs. SOAP vs. Google Maps API with a comparison table.
    • Example: "Compare REST API and SOAP API in terms of protocol, data format, and use cases."
  2. Google Maps API Implementation (25-30 marks):

    • Steps to generate an API key (10 marks).
    • Code snippet to display a marker (10 marks).
    • Screenshot/description of the output (5 marks).
    • Example question: "Develop an Android app to display Google Maps with a marker at NTC’s headquarters (27.6899° N, 85.3240° E)."
  3. REST API Integration (20-25 marks):

    • Fetch data from OpenWeatherMap (10 marks).
    • Handle JSON response (5 marks).
    • Error handling (5 marks).
    • Example question: "Write a program to fetch and display the current temperature of Kathmandu using OpenWeatherMap API."
  4. Location Services (15-20 marks):

    • Code to request permissions and fetch location (10 marks).
    • Explanation of Fused Location Provider (5 marks).
    • Example question: "How would you implement live location tracking in an app like Pathao? Explain with code."
  5. Security & Error Handling (10-15 marks):

    • Discuss threats like API key leakage (5 marks).
    • Code for retry mechanism (5 marks).
    • Example question: "An app fails to fetch data from an API. Explain how you would handle this scenario with code."

Key Tips for Full Marks

✅ Show Code Snippets: Always include Retrofit/Volley code for API calls and Google Maps initialization. ✅ Draw Diagrams: Use sequence diagrams for API flows and state diagrams for location updates. ✅ Explain Real-World Apps: Tie examples to Pathao, eSewa, Daraz, or NEPSE to score extra marks. ✅ Handle Errors Gracefully: Mention network checks, retry logic, and user feedback. ✅ Use Visuals: Include screenshots of maps, JSON responses, and flowcharts to make answers clear.


Sample Exam Question Answer (Full Marks)

Question: "Explain the procedure for generating a Google Maps API key. Develop an Android application to display a Google Map with a marker at NTC’s headquarters (27.6899° N, 85.3240° E)."

Answer:

Step 1: Generating Google Maps API Key (10 marks)

  1. Create a GCP Project:
    • Go to GCP Console → Create Project → Name it NTC_Maps.
  2. Enable Maps SDK:
    • Navigate to APIs & Services → Library → Enable "Maps SDK for Android".
  3. Get API Key:
    • Go to APIs & Services → Credentials → Create API Key.
    • Copy the key (e.g., AIzaSyD123abc456def7890).
  4. Restrict the Key:
    • Click the key → Restrict Key → Add:
      • Android apps → SHA-1 fingerprint (your_app_sha1).
      • API restrictions → Enable "Maps SDK for Android".

Step 2: Android App Development (20 marks)

1. Add Dependencies (build.gradle):

implementation 'com.google.android.gms:play-services-maps:18.2.0'

2. Declare Permissions (AndroidManifest.xml):

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

3. Layout (activity_main.xml):

<fragment
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

4. Java Code (MainActivity.java):

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        LatLng ntchq = new LatLng(27.6899, 85.3240);
        mMap.addMarker(new MarkerOptions()
            .position(ntchq)
            .title("NTC Headquarters"));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(ntchq, 15f));
    }
}

5. Output: (A map centered on NTC’s headquarters with a red marker labeled "NTC Headquarters.")


Why This Scores Full Marks

✔ Complete Steps: All 4 steps for API key generation are covered. ✔ Code Snippets: Includes build.gradle, AndroidManifest.xml, layout, and Java code. ✔ Visual: Describes the expected output (map with marker). ✔ Real-World Tie: Uses NTC’s actual coordinates (27.6899, 85.3240).

Based on the TU BCA syllabus for Mobile Programming (CACS351), unit 9.

Discussion

Loading…