FusedLocationProviderClient 是否需要初始化?位置通常为空

Does FusedLocationProviderClient need to initialize? location often null

我正在使用 FusedLocationProviderClient 获取 GPS 位置,但我注意到它通常是 null,尤其是在前几次拉取位置时。是否需要初始化才能在第一次尝试时拉出位置?这是我正在使用的代码,它有时会起作用,但似乎不是第一次。

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()
        }    
    }
}

最后一个已知位置是一个缓存值,它会不时被擦除(例如 phone 重启后)。如果您想以更持久的方式获取 GPS 位置,request location updates 并在获得第一个结果后立即取消订阅。

我找不到我现在使用的教程,但可以使用以下代码使其正常工作。以下代码适用于未来孤独的 Whosebug 旅行者。

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())
    }
}