无法通过removeLocationUpdates()停止Fused Location Provider问题求助
问题解决:位置更新无法停止且新Activity重复启动的修复方案
问题根源分析
- 每次调用
startLocationUpdates()都会创建新的LocationCallback实例,stopLocationUpdates()只能移除当前持有的回调,之前注册的回调仍在后台运行,导致位置更新停不下来。 onResume()中无条件调用startLocationUpdates(),会重复注册多个位置回调,形成多份活跃监听。- 触发跳转逻辑时,未先停止位置更新就启动新Activity并结束当前页面,残留的回调会持续触发距离判断,导致
ExerciseActivity被重复启动。
修复方案及代码调整
1. 类级别初始化回调,添加状态标记
在类中提前初始化LocationCallback,并增加布尔变量标记位置更新状态,避免重复注册:
class MapActivity : AppCompatActivity() { private val requestPermissionsRequestCode = 1 private lateinit var fusedLocationClient: FusedLocationProviderClient // 提前初始化回调,确保始终操作同一个实例 private val locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { for (location in locationResult.locations) { // 更新用户位置标记 mUserMarker.position = GeoPoint(location.latitude, location.longitude) mUserMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) mUserMarker.title = getString(R.string.your_position) // 优化:避免重复添加Marker,先判断是否已存在 val existingMarker = map.overlays.find { it == mUserMarker } if (existingMarker == null) { map.overlays.add(mUserMarker) } map.controller.setCenter(mUserMarker.position) if (nextCheckpoints.isNotEmpty()) { // 标记是否已触发跳转,避免多个checkpoint同时满足条件时重复启动 var hasTriggeredJump = false for (checkpoint in nextCheckpoints) { if (hasTriggeredJump) break val results = FloatArray(3) Location.distanceBetween( checkpoint.latitude, checkpoint.longitude, location.latitude, location.longitude, results ) val distance = results[0] Log.d("Distance: ", distance.toString()) if (distance <= 15) { // 先停止位置更新,再执行跳转 stopLocationUpdates() val i = Intent(this@MapActivity, ExerciseActivity::class.java) i.putExtra("exerciseId", checkpoint.exercise.exerciseId) startActivity(i) finish() hasTriggeredJump = true } } } } } } private lateinit var locationRequest: LocationRequest private var allCheckpoints: List<CheckpointResult> = ArrayList() private val mAdapterNextCheckpoints = NextCheckpointAdapter() private var nextCheckpoints: ArrayList<CheckpointResult> = ArrayList() // 标记位置更新是否已启动,防止重复注册 private var isLocationUpdatesStarted = false
2. 修改startLocationUpdates()方法,增加状态判断
private fun startLocationUpdates() { if (isLocationUpdatesStarted) return // 已启动则直接返回,避免重复注册 locationRequest = LocationRequest.create().apply { interval = 4000 priority = Priority.PRIORITY_HIGH_ACCURACY } fusedLocationClient.requestLocationUpdates( locationRequest, locationCallback, Looper.getMainLooper() ) isLocationUpdatesStarted = true }
3. 修改stopLocationUpdates()方法,更新状态标记
private fun stopLocationUpdates() { fusedLocationClient.removeLocationUpdates(locationCallback) isLocationUpdatesStarted = false }
4. 调整onResume()逻辑,避免重复启动
override fun onResume() { super.onResume() if (!isLocationUpdatesStarted) { startLocationUpdates() } }
额外优化点
- 移除了
onCreate()中重复添加Marker的逻辑,改为判断是否已存在,避免地图上堆积大量重复标记。 - 增加
hasTriggeredJump标记,防止多个checkpoint同时满足距离条件时,重复启动新Activity。
内容的提问来源于stack exchange,提问作者jpsf
相关产品推荐
相关产品推荐

