My android project needs the users last / current location upon launching but I am not getting a valid location for some reason.
My Main activity checks for the permissions like this:
 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        permissionHelper = PermissionHelper(this)
        val drawerLayout: DrawerLayout = binding.drawerLayout
        val navView: NavigationView = binding.navView
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_home) as NavHostFragment
        val navController = navHostFragment.navController
        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.nav_home,
                R.id.nav_account, R.id.nav_pictures, R.id.nav_settings
            ), drawerLayout
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
        NavigationUI.setupWithNavController(binding.navView, navController)
        navController.addOnDestinationChangedListener { _, destination, _ ->
            isCurrentLocationFragmentVisible = destination.id == R.id.nav_home
            if (isCurrentLocationFragmentVisible) {
                invalidateOptionsMenu()
            }
        }
        handleLocationAndWeather()
        currentLocationViewModel.weather.observe(this){
            currentLocation = LocationDto(it.location.cityName, it.location.locationIndex)
        }
    }
    private fun handleLocationAndWeather() {
        // Check if location permission is granted
        if (permissionHelper.isPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION)) {
            // Permission is granted, load weather data
            viewModel.updatePermissionState(LocationPermissionState.Granted)
            viewModel.loadCurrentLocationWeather()
        } else {
            // Permission not granted, request it
            permissionHelper.requestPermission(
                Manifest.permission.ACCESS_COARSE_LOCATION,
                "Location permission is required to get weather data for your current location.",
                LOCATION_PERMISSION_REQUEST_CODE
            )
        }
    }
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            LOCATION_PERMISSION_REQUEST_CODE -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission granted, update state and load weather data
                    viewModel.updatePermissionState(LocationPermissionState.Granted)
                    viewModel.loadCurrentLocationWeather()
                } else {
                    // Permission denied, update state and handle accordingly
                    viewModel.updatePermissionState(LocationPermissionState.Denied)
                    viewModel.loadCurrentLocationWeather()
                    //TODO show toast here
                }
            }
        }
    }
and it uses this class for the permission related stuff:
class PermissionHelper(private val activity: Activity) {
    fun isPermissionGranted(permission: String): Boolean {
        return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED
    }
    fun requestPermission(permission: String, rationale: String, requestCode: Int) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
            showRationaleDialog(rationale) { _, _ ->
                ActivityCompat.requestPermissions(
                   activity,
                    arrayOf(permission),
                    requestCode
                )
            }
        } else {
            ActivityCompat.requestPermissions(
               activity,
                arrayOf(permission),
                requestCode
            )
        }
    }
    private fun showRationaleDialog(message: String, onPositiveClick: (DialogInterface, Int) -> Unit) {
        AlertDialog.Builder(activity)
            .setTitle("Location permission Required")
            .setMessage(message)
            .setPositiveButton("OK", onPositiveClick)
            .setNegativeButton("Cancel", null)
            .show()
    }
}
The main activity calls the viewmodel to fetch the data based on the location:
private val _locationPermissionState = MutableStateFlow<LocationPermissionState>(LocationPermissionState.Granted)
val locationPermissionState: StateFlow<LocationPermissionState> = _locationPermissionState
fun updatePermissionState(state : LocationPermissionState){
    _locationPermissionState.value = state
}
@SuppressLint("MissingPermission")
fun loadCurrentLocationWeather() {
    viewModelScope.launch {
        when (locationPermissionState.value) {
            LocationPermissionState.Granted -> {
                Log.d(TAG, "permission granted")
                locationGetter.client.lastLocation
                    .addOnSuccessListener { location ->
                        // Check if the location is not null before proceeding
                        if (location != null) {
                            Log.d(TAG, "location not null")
                            viewModelScope.launch {
                                weatherRepository.getWeather(
                                    location.latitude,
                                    location.longitude
                                )
                                    .map { locationWithWeatherDataDto ->
                                        val weatherData =
                                            convertWeatherDtoToWeatherModel(
                                                locationWithWeatherDataDto.weather
                                            )
                                        val locationData = LocationModel(
                                            locationWithWeatherDataDto.location.cityName,
                                            locationWithWeatherDataDto.location.locationIndex
                                        )
                                        LocationWeatherModel(
                                            location = locationData,
                                            weather = weatherData
                                        )
                                    }
                                    .collect {
                                        _weather.value = it
                                        Log.d(TAG, it.weather.cityName)
                                    }
                            }
                        } else {
                            // location is null show seattle
                            Log.d(TAG, "location is null")
                            viewModelScope.launch {
                                weatherRepository.getWeather("Chicago")
                                    .map { locationWithWeatherDataDto ->
                                        val weatherData =
                                            convertWeatherDtoToWeatherModel(locationWithWeatherDataDto.weather)
                                        val locationData = LocationModel(
                                            locationWithWeatherDataDto.location.cityName,
                                            locationWithWeatherDataDto.location.locationIndex
                                        )
                                        LocationWeatherModel(location = locationData, weather = weatherData)
                                    }
                                    .collect {
                                        _weather.value = it
                                        Log.d(TAG, it.weather.cityName)
                                    }
                            }
                        }
                    }
            }
            else -> {
                //location permission is denied
                viewModelScope.launch {
                    weatherRepository.getWeather("Seattle")
                        .map { locationWithWeatherDataDto ->
                            val weatherData =
                                convertWeatherDtoToWeatherModel(locationWithWeatherDataDto.weather)
                            val locationData = LocationModel(
                                locationWithWeatherDataDto.location.cityName,
                                locationWithWeatherDataDto.location.locationIndex
                            )
                            LocationWeatherModel(location = locationData, weather = weatherData)
                        }
                }
            }
        }
    }
}
I have figured out that
  locationGetter.client.lastLocation
                        .addOnSuccessListener { location ->
                            // Check if the location is not null before proceeding
                            if (location != null) {
is always null which leads me to believe that I am not getting a valid location. I have set a location in the emulator so I doubt that it just doesn't have a last location. Any feeback would be greatly appreciated!
 
                        
Lastlocation doesn't turn on the location subsystem. It only returns a result if the location already is known by the OS. It will return null 99%+ of the time. It's an optimization, and was probably a design mistake by the OS to add it at all. Use requestLocationUpdates or requestSingleLocation to actually turn on location detection in the OS.