我有一个KMM项目,需要访问用户的位置.我的LocationClient是用Kotlin 编写的.
一切正常,但在将Kotlin从1.8.20更新到1.9.20之后,我看到了奇怪的行为.
我像预期的那样得到了最初的几个位置,但随后代理就停止将位置发回.我通常在它停止之前得到5到6个位置,从来不会超过10个.我已经在模拟器和真实设备上测试过了,得到了同样的结果.
在SWIFT端,开始发送位置的触发器在一个"onspecar"块中,来回导航会触发另几个位置通过,但随后它们会再次停止.
当位置停止时,手机仍然认为应用程序正在监听位置,并继续显示适当的隐私通知.当我导航离开并停止监听位置时,这将被正确删除.
位置客户端:
actual class LocationProviderImpl : LocationProvider {
private val locationManager = CLLocationManager()
private class LocationDelegate : NSObject(), CLLocationManagerDelegateProtocol {
var onLocationUpdate: ((Location?) -> Unit)? = null
override fun locationManager(manager: CLLocationManager, didUpdateLocations: List<*>) {
//This is correctly called for the first few locations then stops
didUpdateLocations.firstOrNull()?.let {
val location = it as CLLocation
location.coordinate.useContents {
onLocationUpdate?.invoke(Location(latitude, longitude, it.altitude))
}
}
}
override fun locationManager(manager: CLLocationManager, didFailWithError: NSError) {
//This never gets called
onLocationUpdate?.invoke(null)
}
}
override fun getCurrentLocationAsFlow(): Flow<Location?> = callbackFlow {
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
val locationDelegate = LocationDelegate()
locationDelegate.onLocationUpdate = { location ->
trySend(
location
).isSuccess
}
locationManager.delegate = locationDelegate
locationManager.startUpdatingLocation()
awaitClose {
//This is never called
locationManager.stopUpdatingLocation()
}
}.flowOn(Dispatchers.IO)
fun requestBackground() {
locationManager.allowsBackgroundLocationUpdates = true
}
fun stopBackground() {
locationManager.allowsBackgroundLocationUpdates = false
}
fun stopLocationUpdates() {
locationManager.stopUpdatingLocation()
}
}
它的用法如下:
object GpsService {
private lateinit var locationClient: LocationProviderImpl
private var initialized = false
private var serviceScope = CoroutineScope(Dispatchers.IO)
fun initialize(appModule: AppModule) {
if (!initialized) {
locationClient = LocationProviderImpl()
}
}
fun startLocationListener() {
locationClient.getCurrentLocationAsFlow().cancellable()
.catch { e ->
e.printStackTrace()
}
.mapNotNull { it }
.onEach { location ->
// send location to view
_state.update {
it.copy(
currentLocation = location,
formattedAltitude = getFormattedAltitude(location.altitude)
)
}
}.launchIn(serviceScope)
}
我没有收到任何错误或警告(并且到处都设置了断点/println()S),也没有命中任何错误或CATCH块,我只是在前几个位置之后停止获取任何位置.这一切都在Kotlin 1.8.20上运行得很好!