IT272 Mobile Application Development

Mobile Application DevelopmentUnit 818 min read

Location & Maps: GPS, Geocoding, Maps SDKs, Directions & Real-World Apps

Unit 8 of Mobile Application Development covers how mobile apps determine user location (GPS, network-based), convert addresses to coordinates (geocoding/reverse geocoding), display maps (Google Maps SDK, Mapbox), calculate routes (distance, duration, traffic), and handle location permissions—with real-world examples f

TAKEAWAYS:

  • Location services rely on GPS (satellite), Wi-Fi/Cell towers, or sensors (magnetometer/gyroscope), each with trade-offs in accuracy and battery use.
  • Geocoding converts human-readable addresses (e.g., "Kathmandu, Nepal") to coordinates (latitude/longitude) and vice versa (reverse geocoding).
  • Maps SDKs (Google Maps, Mapbox) provide tiles, markers, polygons, and custom overlays, but require API keys and handle offline maps via vector tiles.
  • Route calculation uses algorithms like Dijkstra’s (for shortest path) or A* (for heuristic-based optimization), with traffic data from Google Maps or OpenStreetMap.
  • Permissions (ACCESS_FINE_LOCATION, ACCESS_BACKGROUND_LOCATION) must be declared and requested at runtime, with rationale for each.
  • Battery optimization is critical: frequent location updates drain power, so use FusedLocationProvider and adjust request intervals dynamically.

1. How Mobile Devices Determine Location

Mobile apps access location via sensors and network signals. The Android framework combines these sources to provide the most accurate result.

Location Sources and Their Trade-offs

pie
    title Location Sources in Android
    "GPS (Satellite)" : 30
    "Network (Wi-Fi/Cell)" : 40
    "Sensor Fusion (Accelerometer/Magnetometer)" : 20
    "IP Address (Approximate)" : 10
  • GPS (Global Positioning System)

    • How it works: Uses signals from at least 4 satellites to triangulate position (latitude, longitude, altitude).
    • Accuracy: 2–10 meters (better outdoors, worse indoors).
    • Battery impact: High (GPS chip consumes ~50–100 mA).
    • Example: Pathao uses GPS to track rider/driver locations in real time.
  • Network-Based Location

    • How it works: Uses nearby Wi-Fi access points or cell tower IDs. Android compares these against a database (Google’s Wi-Fi database or operator data).
    • Accuracy: 10–100 meters (worse than GPS but works indoors).
    • Battery impact: Low (~5–10 mA).
    • Example: Ncell’s "Find My Device" app uses network location when GPS is unavailable.
  • Sensor Fusion

    • How it works: Combines accelerometer (movement), gyroscope (rotation), and magnetometer (compass) to estimate position when GPS/network fails (e.g., indoors).
    • Accuracy: Low (error accumulates over time).
    • Use case: Shopping apps like Daraz use this to track movement within a mall.
  • IP Address Geolocation

    • How it works: Maps the device’s public IP to a rough location (city/country level).
    • Accuracy: 1–10 km (useless for precise apps).
    • Use case: Weather apps (e.g., Weather.com) show approximate forecasts.

Android’s Location Fusion

Android’s FusedLocationProvider combines these sources dynamically:

  1. High-accuracy mode: Uses GPS + network + sensors (best accuracy, highest battery drain).
  2. Balanced mode: Prioritizes battery (uses network first, falls back to GPS).
  3. No-power mode: Uses only network or IP (worst accuracy).

Worked Example: Pathao’s Rider Location

  • Scenario: A rider opens Pathao to start a trip. The app needs their location every 5 seconds.
  • Steps:
    1. Request ACCESS_FINE_LOCATION permission.
    2. Use FusedLocationProvider with REQUEST_PRIORITY_HIGH_ACCURACY.
    3. Set a LocationRequest with:
      • INTERVAL_FASTEST = 5000 ms
      • FASTEST_INTERVAL = 2000 ms (minimum delay between updates)
    4. Handle location updates in onLocationChanged().
  • Code:
    LocationRequest locationRequest = LocationRequest.create()
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
        .setInterval(5000)
        .setFastestInterval(2000);
    
    FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(context);
    client.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
    
  • Trace:
    Step Location Source Latitude Longitude Battery Impact
    1 GPS 27.7172 85.3240 High
    2 Network 27.7170 85.3242 Medium
    3 GPS 27.7173 85.3239 High

2. Geocoding: Address ↔ Coordinates

Geocoding converts between human-readable addresses and geographic coordinates (latitude/longitude).

Types of Geocoding

  1. Forward Geocoding

    • Input: Address (e.g., "Thapathali, Kathmandu, Nepal")
    • Output: Coordinates (e.g., 27.7172° N, 85.3240° E)
    • Use case: Daraz’s "Store Locator" finds the nearest branch.
  2. Reverse Geocoding

    • Input: Coordinates (e.g., 27.7172, 85.3240)
    • Output: Address (e.g., "Thapathali, Kathmandu Metropolitan City, Nepal")
    • Use case: Pathao shows rider/driver addresses when they accept a trip.

How It Works

  • Google Maps Geocoding API:
    • Free tier: 40,000 requests/day.
    • Endpoint: https://maps.googleapis.com/maps/api/geocode/json?address=...&key=API_KEY
    • Response includes results[0].geometry.location (coordinates) and formatted_address.
  • OpenStreetMap (Nominatim):
    • Free alternative: https://nominatim.openstreetmap.org/search?format=json&q=...
    • Slower but privacy-friendly.

Worked Example: Daraz Store Locator

  • Scenario: User searches for "Daraz store near me."
  • Steps:
    1. Get device location using FusedLocationProvider.
    2. Use Google Geocoding API to convert coordinates to address.
    3. Query Daraz’s database for stores within 5 km.
    4. Display results on a map with markers.
  • Code:
    // Step 1: Get location
    Location currentLocation = getLastKnownLocation();
    
    // Step 2: Reverse geocode
    String url = "https://maps.googleapis.com/maps/api/geocode/json?"
        + "latlng=" + currentLocation.getLatitude() + "," + currentLocation.getLongitude()
        + "&key=YOUR_API_KEY";
    // Parse JSON response to get address
    
  • Trace:
    Step Input Output API Used
    1 Device location Lat: 27.7172, Lon: 85.3240 FusedLocation
    2 Coordinates "Thapathali, Kathmandu, Nepal" Google Geocode
    3 Address + radius ["Daraz Hub, Thapathali", "Daraz Outlet, Lalitpur"] Daraz DB

3. Displaying Maps in Android

Android provides two main ways to display maps:

  1. Google Maps SDK
    • Pros: High-quality tiles, real-time traffic, indoor maps, 3D buildings.
    • Cons: Requires API key, paid for high usage, privacy concerns.
  2. Mapbox
    • Pros: Open-source friendly, customizable styles, offline maps.
    • Cons: Smaller community than Google Maps.

Google Maps SDK Setup

  1. Add dependency to build.gradle:
    implementation 'com.google.android.gms:play-services-maps:18.2.0'
    
  2. Get an API key from Google Cloud Console.
  3. Add <meta-data> to AndroidManifest.xml:
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="YOUR_API_KEY" />
    
  4. Add a MapView or SupportMapFragment to your layout:
    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    

Adding Markers and Custom Overlays

Worked Example: Ncell’s "Emergency Contact" Map

  • Scenario: User reports an emergency. The app shows their location on a map and shares it with contacts.
  • Steps:
    1. Add SupportMapFragment to layout.
    2. Enable myLocationEnabled() to show user’s blue dot.
    3. Add a marker at the location:
      LatLng userLocation = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
      mMap.addMarker(new MarkerOptions()
          .position(userLocation)
          .title("Emergency Location")
          .snippet("Shared with contacts"));
      
    4. Share the location via intent:
      Intent shareIntent = new Intent(Intent.ACTION_SEND);
      shareIntent.setType("text/plain");
      shareIntent.putExtra(Intent.EXTRA_TEXT, "Help! I'm at: " + userLocation);
      startActivity(Intent.createChooser(shareIntent, "Share Location"));
      
  • State After Step 3:

4. Calculating Routes and Directions

Apps like Pathao or Google Maps need to calculate the fastest route between two points, considering traffic.

Key Algorithms

Algorithm Use Case Time Complexity Notes
Dijkstra’s Shortest path (no traffic) O(V²) or O(E log V) Works for static graphs.
A* Shortest path with heuristics O(b^d) Uses f(n) = g(n) + h(n) (cost + heuristic).
Floyd-Warshall All-pairs shortest paths O(V³) Overkill for mobile apps.
Google’s Contraction Hierarchies Real-time traffic-aware routing Optimized Used by Google Maps.

Google Directions API

  • Endpoint: https://maps.googleapis.com/maps/api/directions/json?origin=...&destination=...&key=API_KEY
  • Parameters:
    • mode: driving, walking, bicycling, transit
    • departure_time: For traffic-aware routes.
    • avoid: tolls, highways, ferries.
  • Response: Includes routes[0].overview_polyline (encoded path) and legs[0].duration.

Worked Example: Pathao’s Route Optimization

  • Scenario: Rider requests a trip from Thapathali to Pulchowk.
  • Steps:
    1. Get origin/destination coordinates (via geocoding).
    2. Call Directions API with mode=driving and departure_time=now.
    3. Decode the polyline to draw the route on the map.
    4. Estimate ETA from legs[0].duration.value (seconds).
  • Code:
    String url = "https://maps.googleapis.com/maps/api/directions/json?"
        + "origin=" + originLat + "," + originLng
        + "&destination=" + destLat + "," + destLng
        + "&mode=driving"
        + "&departure_time=now"
        + "&key=YOUR_API_KEY";
    
    // Parse JSON to get polyline and duration
    
  • Trace:
    Step Input Output API Response Field
    1 "Thapathali" → "Pulchowk" Lat/Lon pairs geocode
    2 Coordinates + departure_time Encoded polyline, duration routes[0].overview_polyline
    3 Polyline Drawn route on map decodePolyline()

Visualizing Dijkstra’s Algorithm for Kathmandu Traffic Assume a simplified grid of Kathmandu with 5 intersections (A–E) and roads with weights (traffic delays in minutes):

A ---3--- B
| \     / |
4   2   5  |
|   \ /   |
E ---1--- C ---2--- D
  • Goal: Find shortest path from A to D.
  • Steps:
    1. Initialize distances: A=0, B=3, C=∞, D=∞, E=4.
    2. Visit A → update neighbors: B=3, E=4.
    3. Visit B (smallest unvisited) → update C: C=min(∞, 3+2)=5.
    4. Visit E → update C: C=min(5, 4+1)=5 (no change).
    5. Visit C → update D: D=5+2=7.
    6. Final path: A → B → C → D (total time = 7 minutes).
34212ABCDE
Dijkstra's algorithm steps for finding the shortest path from A to D (total time = 7 minutes).

5. Handling Location Permissions

Android requires explicit permissions for location access. Missteps here cause crashes or security warnings.

Permission Types

Permission Runtime Request Needed? Use Case
ACCESS_FINE_LOCATION Yes GPS + network (high accuracy)
ACCESS_COARSE_LOCATION Yes Network-only (low accuracy)
ACCESS_BACKGROUND_LOCATION Yes Location updates when app is closed (e.g., tracking)
ACCESS_LOCATION_EXTRA_COMMANDS Yes Advanced features (e.g., Wi-Fi scan)

Best Practices

  1. Declare permissions in AndroidManifest.xml:
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    
  2. Request at runtime (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},
            REQUEST_LOCATION_PERMISSION);
    }
    
  3. Explain why in the permission rationale:
    if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
        new AlertDialog.Builder(this)
            .setMessage("This app needs location to show nearby stores.")
            .setPositiveButton("OK", (dialog, which) -> requestPermissions(...))
            .show();
    }
    
  4. Handle background location carefully:
    • Android 10+ restricts background location unless justified (e.g., "tracking lost devices").
    • Use FOREGROUND_SERVICE for location updates in the background.

Worked Example: NEPSE App’s Location Permission

  • Scenario: NEPSE’s "Nearby Share Market" feature needs location to show stock prices of nearby branches.
  • Steps:
    1. Declare ACCESS_FINE_LOCATION in manifest.
    2. Request permission when user opens the "Nearby" tab.
    3. If denied, show a tooltip: "Enable location to find the nearest NEPSE branch."
    4. Use FusedLocationProvider with PRIORITY_BALANCED_POWER_ACCURACY.

6. Optimizing for Battery and Performance

Frequent location updates drain battery. Use these techniques:

Techniques

Technique Description When to Use
Adjust LocationRequest interval Increase setInterval() for less critical apps. Background sync (e.g., weather updates).
Use FusedLocationProvider Combines sensors/network/GPS intelligently. Always preferred over raw GPS.
Disable location when idle Call removeLocationUpdates() when not needed. Avoid memory leaks.
Use getLastKnownLocation() Faster than continuous updates. One-time lookups (e.g., opening app).
Offline maps Cache map tiles using Mapbox or Google’s offline mode. Areas with poor connectivity.

Worked Example: Daraz’s Battery Optimization

  • Scenario: Daraz’s "Store Locator" needs location only when the user opens the feature.
  • Steps:
    1. Request location only when the "Nearby Stores" button is clicked.
    2. Use getLastKnownLocation() first (fast, no battery drain).
    3. If stale (>5 mins), request a one-time update with PRIORITY_BALANCED_POWER_ACCURACY.
    4. Disable updates immediately after fetching stores.

In the Real World

  1. Pathao (Ride-Hailing)

    • Idea Used: Real-time GPS tracking + geocoding.
    • How: Uses FusedLocationProvider to update rider/driver locations every 2–5 seconds. Geocodes addresses for pickup/drop locations. Calculates ETA using Google Directions API with live traffic data.
    • Example: When you accept a trip in Pathao, the app shows your live location on a map and estimates arrival time based on current traffic (e.g., "5 mins due to Kathmandu traffic").
  2. Ncell’s "Find My Device"

    • Idea Used: Network-based location + reverse geocoding.
    • How: If your phone is lost, Ncell’s app uses cell tower/Wi-Fi data to approximate your location (even if GPS is off). It then reverse-geocodes to show the nearest landmark (e.g., "Near Thamel, Kathmandu").
    • Example: You lose your phone near the garden of Kathmandu. Ncell’s app shows: "Last known location: 50m from Garden of Dreams, Thamel."
  3. Daraz (E-Commerce)

    • Idea Used: Geocoding + offline maps.
    • How: Daraz’s "Store Locator" uses Google Geocoding to find the nearest branch when you search "near me." For offline use, it caches map tiles for major cities (e.g., Kathmandu, Pokhara) so users can navigate stores without internet.
    • Example: You’re in Lalitpur with no data. Daraz’s offline map shows the nearest Daraz Hub with directions: "Walk 3 mins north on Putalisadak."
  4. NTC (Electricity Board) Outage Tracker Apps

    • Idea Used: Reverse geocoding + user-reported data.
    • How: Apps like "NTC Outage Map" use your location to show nearby outages. When you report an outage, the app reverse-geocodes your address to display it on a map for NTC teams.
    • Example: You report an outage at "Balkhu, Lalitpur." The app shows this on a live map with other reports, helping NTC prioritize fixes.

Exam Tip

This unit is heavily practical in exams. Expect:

  1. Code snippets: Write 3–5 lines to:
    • Request location permissions.
    • Get user location using FusedLocationProvider.
    • Add a marker to Google Maps.
    • Decode a polyline from Directions API.
  2. Short-answer questions:
    • Difference between ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION.
    • When to use geocoding vs. reverse geocoding.
    • Pros/cons of GPS vs. network location.
  3. Scenario-based questions:
    • "Design a flow for a food delivery app to show the nearest restaurant using location services."
    • "How would you optimize battery life for an app that tracks user location every 10 minutes?"
  4. Diagrams:
    • Draw the state of a map after adding markers/lines.
    • Sketch Dijkstra’s algorithm steps for a simple graph (3–4 nodes).
  5. API usage:
    • Write the URL for a Directions API call from Kathmandu to Pokhara.
    • Explain how to handle a SecurityException when location permission is denied.

Common Pitfalls to Avoid:

  • Forgetting to declare permissions in AndroidManifest.xml.
  • Using raw GPS instead of FusedLocationProvider (wastes battery).
  • Not handling onPermissionDenied() gracefully (e.g., showing a fallback).
  • Ignoring background location restrictions on Android 10+.

High-Score Strategy:

  • Always trace code examples step-by-step (show variable states).
  • Relate answers to real apps (Pathao, Daraz, Ncell) for context.
  • For algorithms (Dijkstra/A*), draw the graph and highlight visited nodes.
  • Mention battery optimization wherever location is used continuously.

Based on the TU BITM syllabus for Mobile Application Development (IT272), unit 8.

Discussion

Loading…