Search code examples
androidkotlingoogle-mapsnull

Can't set the zoom to my map without the app crashing


I'm developing an Android app using Jetpack Compose that uses Google Maps, and I'm trying to set the zoom of the map to my location. However, when the cameraPositionState is invoked, the app crashes. So, I asked Copilot, and it says that the location is probably null, which is why the app is crashing. I've been trying to solve this error for two days and couldn't make it work. I've checked the location variable to ensure it wasn't null multiple times.

Here is my code. I'm skipping some parts of the code and just focusing on the important ones. Please let me know if you need other parts.:

fun HomeView(
    viewModel: LocationViewModel,
    context: Context,
    locationUtils: LocationUtils){

    //getting the location from the viewModel
    val location = viewModel.location.value

    //transforming the coordinates into an address with geocode
    val address = location?.let {
        locationUtils.reverseGeocodeLocation(location)
    }

    //declaring this variable to use it at cameraPosition
    val userLocation = remember {
        mutableStateOf(LatLng(location!!.latitude, location.longitude))
    }

    //declaring the cameraPosition
    // this is when the error occurs, because if I comment out this line the Exception doesn´t     appers
    val cameraPositionState = rememberCameraPositionState{
        position = CameraPosition.fromLatLngZoom(userLocation.value, 10f)
    }

Scaffold(
        topBar = { AppTopBar(title = "Map")},
    ){ innerPadding ->
        Column(
            modifier = Modifier.padding(innerPadding)) {


            GoogleMap(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 16.dp)
                    .height(600.dp),
                cameraPositionState = cameraPositionState
            )

LocationData :

data class LocationData( val latitude: Double, val longitude: Double )

ViewModel :

class LocationViewModel: ViewModel() {

    private val _location = mutableStateOf<LocationData?>(null)
    val location : State<LocationData?> = _location


    fun updateLocation(newLocation : LocationData){
        _location.value = newLocation
    }

}

Error : PID: 25814 java.lang.NullPointerException

I would be very gratefull if someone helps me know why is this happening and understand how to avoid it.

Adding ? or !! Doesn't work.

I've try making latitude: Double?, longitude: Double? and changing in the UI like this:

 val userLocation = remember {
        mutableStateOf(location?.latitude?.let { location.longitude?.let { it1 -> LatLng(it, it1) } })
    }


    val cameraPositionState = rememberCameraPositionState{
        position = userLocation.value?.let { CameraPosition.fromLatLngZoom(it, 10f) }!!
    }

Doesn't work neither


Solution

  • First of all set a default location like:

    const val defaultLocation = LatLng(23.626352, 82.478563)
    

    Now you can observe changes in your location like:

    val location by viewModel.location
    val cameraPositionState = remember {
        CameraPositionState(
            position = CameraPosition.fromLatLngZoom(defaultLocation, 6f)
        )
    }
    var hasMapLoaded by remember { mutableStateOf(false) }
    
    LaunchedEffect(location, hasMapLoaded) {
        if (hasMapLoaded && location != null) {
            cameraPositionState.animate(
                CameraUpdateFactory.newLatLngZoom(LatLng(location!!.latitude, location!!.longitude), 15f),
                durationMs = 500
            )
        }
    }
    
    
    Scaffold(
        topBar = { AppTopBar(title = "Map")},
    ){ innerPadding ->
        Column(
            modifier = Modifier.padding(innerPadding)) {
    
    
            GoogleMap(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 16.dp)
                    .height(600.dp),
                cameraPositionState = cameraPositionState,
                onMapLoaded = {
                   hasMapLoaded = true
                }
            ) { ... }
    }
    

    }

    So basically I'm waiting for my Google map to load and then I'm observing the changes of both map load and location (if it changes as well). And I update the camera position based on the current location and handling the null check as well. I hope this works.