Android使用Mapbox获取当前位置遇LocationListener类找不到错误
嘿,我之前也踩过这个坑!你遇到的这个LocationListener找不到的错误,其实是依赖缺失+旧API弃用的双重问题,我来给你捋清楚怎么解决:
解决Mapbox Android SDK定位的LocationListener找不到问题
1. 先搞懂错误根源
这个com.google.android.gms.location.LocationListener找不到的报错,核心原因是你的项目没引入Google Play Services的定位依赖库——Mapbox当前的定位实现部分依赖它。另外你提到旧方法全弃用了,刚好趁这个机会换成Mapbox官方现在主推的新定位方案,一步到位解决两个问题。
2. 第一步:补全必要依赖
打开Module级别的build.gradle,确保添加以下依赖(版本号可以根据你当前的Mapbox SDK版本微调,尽量保持兼容):
// Mapbox官方定位组件(替代弃用的旧API) implementation 'com.mapbox.mapboxsdk:mapbox-android-location:5.0.0' // Google Play Services定位库(解决LocationListener找不到的问题) implementation 'com.google.android.gms:play-services-location:21.0.1'
3. 第二步:改用Mapbox推荐的最新定位实现
直接上可运行的示例代码,替换你之前的旧逻辑:
import android.Manifest import android.content.pm.PackageManager import android.os.Bundle import android.os.Looper import android.util.Log import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.mapbox.android.core.location.LocationEngineCallback import com.mapbox.android.core.location.LocationEngineResult import com.mapbox.mapboxsdk.Mapbox import com.mapbox.mapboxsdk.location.CameraMode import com.mapbox.mapboxsdk.location.LocationComponent import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions import com.mapbox.mapboxsdk.location.RenderMode import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.Style class LocationActivity : AppCompatActivity() { private lateinit var mapView: MapView private lateinit var locationComponent: LocationComponent private val LOCATION_PERMISSION_REQUEST_CODE = 1001 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 初始化Mapbox(记得把token放到strings.xml里) Mapbox.getInstance(this, getString(R.string.mapbox_access_token)) setContentView(R.layout.activity_location) mapView = findViewById(R.id.mapView) mapView.onCreate(savedInstanceState) mapView.getMapAsync { mapboxMap -> mapboxMap.setStyle(Style.MAPBOX_STREETS) { style -> // 激活Mapbox定位组件 locationComponent = mapboxMap.locationComponent val activationOptions = LocationComponentActivationOptions.builder(this, style) .useDefaultLocationEngine(true) .build() locationComponent.activateLocationComponent(activationOptions) // 检查并请求定位权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ) { // 开启定位追踪,设置为跟随模式 locationComponent.isLocationComponentEnabled = true locationComponent.cameraMode = CameraMode.TRACKING locationComponent.renderMode = RenderMode.COMPASS // 获取当前位置的回调 locationComponent.locationEngine?.requestLocationUpdates( locationComponent.locationEngineRequest, object : LocationEngineCallback<LocationEngineResult> { override fun onSuccess(result: LocationEngineResult?) { result?.lastLocation?.let { location -> Log.d("MY_LOCATION", "当前位置:${location.latitude}, ${location.longitude}") } } override fun onFailure(exception: Exception) { Log.e("MY_LOCATION", "定位失败:${exception.message}") } }, Looper.getMainLooper() ) } else { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE ) } } } } // 处理权限请求结果 override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == LOCATION_PERMISSION_REQUEST_CODE && grantResults.isNotEmpty()) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED && ::locationComponent.isInitialized) { locationComponent.isLocationComponentEnabled = true } } } // 必须重写MapView的生命周期方法 override fun onStart() { super.onStart() mapView.onStart() } override fun onResume() { super.onResume() mapView.onResume() } override fun onPause() { super.onPause() mapView.onPause() } override fun onStop() { super.onStop() mapView.onStop() } override fun onDestroy() { super.onDestroy() // 移除定位监听,避免内存泄漏 locationComponent.locationEngine?.removeLocationUpdates(object : LocationEngineCallback<LocationEngineResult> { override fun onSuccess(result: LocationEngineResult?) {} override fun onFailure(exception: Exception) {} }) mapView.onDestroy() } }
4. 第三步:配置Manifest权限
别忘了在AndroidManifest.xml里添加必要的权限:
<!-- 定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Mapbox网络权限 --> <uses-permission android:name="android.permission.INTERNET" />
5. 额外小提示
- 如果还是遇到依赖问题,试试清理项目缓存(Build -> Clean Project,再Rebuild Project)
- 如果你不想依赖Google Play Services,可以在初始化
LocationComponentActivationOptions时设置useDefaultLocationEngine(false),自己实现离线定位逻辑,但这种方式需要处理更多细节
这样既解决了LocationListener找不到的错误,也用上了Mapbox最新的非弃用API,完美适配现在的版本~
内容的提问来源于stack exchange,提问作者Dimitar Georgiev
相关产品推荐
相关产品推荐

