GoogleMaps in Jetpack Compose: Marking the Device?Location
Sagar Malhotra
Android dev by day, Creator by night.???? Sharing my passion through videos, blogs and conferences.??
In this article, we will be using android-maps-compose library and implementing GoogleMaps in Jetpack compose. Additionally, we will be also using Android’s Places SDK to get your device's last known location and mark it on Map.
There was no dedicated documentation to get this thing done in Jetpack compose and many folks can face difficulties in implementing this simple feature. So, I will be showing you a step-by-step guide to do so.
Output:
Before Starting:
implementation 'com.google.maps.android:maps-compose:2.11.1'
implementation 'com.google.android.gms:play-services-maps:18.1.0'
implementation 'com.google.android.libraries.places:places:3.0.0'
4. Add API KEY in AndroidManifest.xml.
Inside your application block add this..
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/MAPS_API_KEY" />//This will be your API KEY
Implementing:
First, we need to get all the required permissions.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
2. In your MainActivity, make a request and show the Map accordingly…
private val locationPermissionGranted = mutableStateOf(false)
companion object {
const val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1234
}
private fun getLocationPermission() {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
== PackageManager.PERMISSION_GRANTED
) {
locationPermissionGranted.value = true//we already have the permission
} else {
ActivityCompat.requestPermissions(
this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION
)
}
}
@Deprecated("Deprecated in Java")
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode== PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
locationPermissionGranted.value=true
}
}
Places.initialize(applicationContext, getString(R.string.MAPS_API_KEY))
领英推荐
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Places.initialize(applicationContext, getString(R.string.MAPS_API_KEY))
setContent {
getLocationPermission()//Check for permission before showing anything
if (locationPermissionGranted.value) {
HomeScreen()
}else{
Text("Need permission")
}
}
}
Full code for MainActivity?:
class MainActivity : ComponentActivity() {
companion object {
const val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1234
}
private val locationPermissionGranted = mutableStateOf(false)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Places.initialize(applicationContext, getString(R.string.MAPS_API_KEY))
setContent {
getLocationPermission()
if (locationPermissionGranted.value) {
MapScreen()
}else{
Text("Need permission")
}
}
}
@Deprecated("Deprecated in Java")
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode== PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
locationPermissionGranted.value=true
}
}
private fun getLocationPermission() {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
== PackageManager.PERMISSION_GRANTED
) {
locationPermissionGranted.value = true
} else {
ActivityCompat.requestPermissions(
this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION
)
}
}
}
3. In your MapScreen composable, we will be using GoogleMap composable.
val context = LocalContext.current
val fusedLocationProviderClient =
remember { LocationServices.getFusedLocationProviderClient(context) }
lastKnownLocation — Last known location of device.
var lastKnownLocation by remember {
mutableStateOf<Location?>(null)
}
deviceLatLng- Latitude Longitude value of device location
var deviceLatLng by remember {
mutableStateOf(LatLng(0.0, 0.0))
}
cameraPositionState- To be used for camera position in our GoogleMap.
val cameraPositionState = rememberCameraPositionState {
position = CameraPosition.fromLatLngZoom(deviceLatLng, 18f)
}
val locationResult = fusedLocationProviderClient.lastLocation
locationResult.addOnCompleteListener(context as MainActivity) { task ->
if (task.isSuccessful) {
// Set the map's camera position to the current location of the device.
lastKnownLocation = task.result
deviceLatLng = LatLng(lastKnownLocation!!.latitude, lastKnownLocation!!.longitude)
cameraPositionState.position = CameraPosition.fromLatLngZoom(deviceLatLng, 18f)
} else {
Log.d(TAG, "Current location is null. Using defaults.")
Log.e(TAG, "Exception: %s", task.exception)
}
}
GoogleMap(cameraPositionState = cameraPositionState) {
MarkerInfoWindowContent(
state = MarkerState(position = deviceLatLng)
) { marker ->
Text(marker.title ?: "You", color = Color.Red)
}
}
Full code:
@Composable
fun MapScreen() {
val context = LocalContext.current
val fusedLocationProviderClient =
remember { LocationServices.getFusedLocationProviderClient(context) }
var lastKnownLocation by remember {
mutableStateOf<Location?>(null)
}
var deviceLatLng by remember {
mutableStateOf(LatLng(0.0, 0.0))
}
val cameraPositionState = rememberCameraPositionState {
position = CameraPosition.fromLatLngZoom(deviceLatLng, 18f)
}
val locationResult = fusedLocationProviderClient.lastLocation
locationResult.addOnCompleteListener(context as MainActivity) { task ->
if (task.isSuccessful) {
// Set the map's camera position to the current location of the device.
lastKnownLocation = task.result
deviceLatLng = LatLng(lastKnownLocation!!.latitude, lastKnownLocation!!.longitude)
cameraPositionState.position = CameraPosition.fromLatLngZoom(deviceLatLng, 18f)
} else {
Log.d(TAG, "Current location is null. Using defaults.")
Log.e(TAG, "Exception: %s", task.exception)
}
}
GoogleMap(
cameraPositionState = cameraPositionState
) {
MarkerInfoWindowContent(
state = MarkerState(
position = deviceLatLng
)
) { marker ->
Text(marker.title ?: "You", color = Color.Red)
}
}
}
Output:
I hope you found this helpful. If yes, then do FOLLOW ‘Sagar Malhotra’ for more Android-related content.