androidandroid-locationandroid-gpsfusedlocationproviderclient

Does FusedLocationProviderClient need to initialize? location often null


I am using FusedLocationProviderClient to get GPS location but I've noticed that it is often null, especially on the first couple of location pulls. Does it need to initialize for it to pull the location on the first try? Here is the code I'm using which works sometimes but never the first time it seems.

val locationManager: LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
if((ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) && (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) == PackageManager.PERMISSION_GRANTED) {
    var fusedLocationProviderClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
    fusedLocationProviderClient.lastLocation.addOnCompleteListener(this) { task ->
        val location: Location? = task.result
            if(location != null) {
                latitude = location.latitude.toString()
                longitude = location.longitude.toString()
            } else {
                val locationRequest = LocationRequest()
                locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
                locationRequest.interval = 0
                locationRequest.fastestInterval = 0
                locationRequest.numUpdates = 1
                fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
                fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallBack, Looper.myLooper())
            }
        }
    }
}

private val locationCallBack = object : LocationCallback() {
    override fun onLocationResult(p0: LocationResult) {
        val location: Location? = p0?.lastLocation

        if(location != null) {
            latitude = location.latitude.toString()
            longitude = location.longitude.toString()
        }    
    }
}

Solution

  • I can't find the tutorial I used now, but was able to get this to work with the following code. Below code is for the future lonely stackoverflow traveler.

    build.gradle
    ...
    dependencies {
        implementation 'com.google.android.gms:play-services-location:17.0.0'
    }
    ...
    
    Androidmanifest.xml
    ...
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <!-- I think this is required for Android 10 (API 29) + -->
    ...
    
    class ClassName : AppCompatActivity() {
        private lateinit var fusedLocationClient: FusedLocationProviderClient
        private val locationCallBack: LocationCallback = object : LocationCallback() {
            override fun onLocationResult(p0: LocationResult?) {
                val location: Location? = p0?.lastLocation
                if(location != null) {
                    latitude = location.latitude.toString()
                    longitude = location.longitude.toString()
                }
            }
        }
        override fun onCreate(savedInstanceState: Bundle?) {
            ...
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
            getLocation()
            ...
        }
        private fun getLocation() {
            if(ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                val locationManager: LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
                if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                    fusedLocationClient.lastLocation.addOnCompleteListener(this) { task ->
                        val location: Location? = task.result
                        if(location == null)
                            requestLocation()
                        else {
                            latitude = location.latitude.toString()
                            longitude = location.longitude.toString()
                        }
                    }
                }
            }
        }
        private fun requestLocation() {
            val locationRequest = LocationRequest()
            locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            locationRequest.interval = 0
            locationRequest.fastestInterval = 0
            locationRequest.numUpdates = 1
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
            fusedLocationClient.requestLocationUpdates(locationRequest, locationCallBack, Looper.myLooper())
        }
    }