0
0
Android Kotlinmobile~20 mins

Location services in Android Kotlin - Mini App: Build & Ship

Choose your learning style9 modes available
Build: LocationTrackerScreen
This screen shows the user's current latitude and longitude using Android location services.
Target UI
-------------------------
| Location Tracker      |
|-----------------------|
| Latitude:             |
| Longitude:            |
|                       |
| [Get Current Location]|
-------------------------
Display two TextViews for latitude and longitude.
Add a button labeled 'Get Current Location'.
When the button is tapped, request location permission if not granted.
If permission granted, get the last known location and update the TextViews.
Handle permission denial gracefully with a Toast message.
Starter Code
Android Kotlin
package com.example.locationapp

import android.Manifest
import android.content.pm.PackageManager
import android.location.Location
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices

class LocationTrackerScreen : AppCompatActivity() {
    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var latitudeTextView: TextView
    private lateinit var longitudeTextView: TextView
    private lateinit var getLocationButton: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_location_tracker)

        latitudeTextView = findViewById(R.id.latitudeTextView)
        longitudeTextView = findViewById(R.id.longitudeTextView)
        getLocationButton = findViewById(R.id.getLocationButton)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        getLocationButton.setOnClickListener {
            // TODO: Add permission check and get location
        }
    }
}
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
Android Kotlin
package com.example.locationapp

import android.Manifest
import android.content.pm.PackageManager
import android.location.Location
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices

class LocationTrackerScreen : AppCompatActivity() {
    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var latitudeTextView: TextView
    private lateinit var longitudeTextView: TextView
    private lateinit var getLocationButton: Button

    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            getLastLocation()
        } else {
            Toast.makeText(this, "Location permission denied", Toast.LENGTH_SHORT).show()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_location_tracker)

        latitudeTextView = findViewById(R.id.latitudeTextView)
        longitudeTextView = findViewById(R.id.longitudeTextView)
        getLocationButton = findViewById(R.id.getLocationButton)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        getLocationButton.setOnClickListener {
            when {
                ContextCompat.checkSelfPermission(
                    this,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) == PackageManager.PERMISSION_GRANTED -> {
                    getLastLocation()
                }
                else -> {
                    requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
                }
            }
        }
    }

    private fun getLastLocation() {
        fusedLocationClient.lastLocation
            .addOnSuccessListener { location: Location? ->
                if (location != null) {
                    latitudeTextView.text = "Latitude: ${location.latitude}"
                    longitudeTextView.text = "Longitude: ${location.longitude}"
                } else {
                    Toast.makeText(this, "Location not available", Toast.LENGTH_SHORT).show()
                }
            }
            .addOnFailureListener {
                Toast.makeText(this, "Failed to get location", Toast.LENGTH_SHORT).show()
            }
    }
}

This solution uses Android's FusedLocationProviderClient to get the last known location.

We check if the app has permission to access fine location. If not, we request it using the Activity Result API, which is the modern way to handle permissions.

When permission is granted, we call getLastLocation() to fetch the location and update the UI TextViews with latitude and longitude.

If permission is denied or location is unavailable, we show a friendly Toast message to inform the user.

Final Result
Completed Screen
-------------------------
| Location Tracker      |
|-----------------------|
| Latitude: 37.4219983  |
| Longitude: -122.084  |
|                       |
| [Get Current Location]|
-------------------------
User taps 'Get Current Location' button.
If permission not granted, app asks for location permission.
If user grants permission, latitude and longitude appear in the TextViews.
If permission denied, a Toast message 'Location permission denied' appears.
If location is unavailable, a Toast message 'Location not available' appears.
Stretch Goal
Add a loading indicator while fetching the location.
💡 Hint
Use a ProgressBar and show it when starting to get location, hide it after location is received or on failure.