Android GPSTracker调用定位API报权限检查错误如何解决
错误原因
这个报错是Android 6.0(API 23)以上运行时权限机制的要求:定位属于危险权限,即便你在清单文件中声明了权限,调用定位相关API前也必须主动检查权限是否已被用户授予,否则Lint会抛出该编译错误,未做处理的话运行时还会触发崩溃。你代码中报错的4处分别对应两次requestLocationUpdates、两次getLastKnownLocation调用,都是需要定位权限的API。
修复步骤
1. 添加清单权限
首先在AndroidManifest.xml中添加必要的定位权限声明:
<!-- 网络定位权限 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- GPS定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 12及以上版本如果在前台服务中使用定位,需要额外添加 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
2. 导入依赖类
在GPSTracker.java顶部添加以下导入:
import android.content.pm.PackageManager; import androidx.core.content.ContextCompat; import android.annotation.SuppressLint;
3. 修改getLocation方法添加权限检查
在调用定位API前先判断是否已拿到权限,修改后的完整getLocation方法如下:
public Location getLocation() { try { locationManager = (LocationManager) mContext .getSystemService(LOCATION_SERVICE); // 先检查权限是否已授予 boolean hasLocationPermission = ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; if (!hasLocationPermission) { // 权限未授予时直接返回,建议此处添加回调通知调用方申请权限 canGetLocation = false; return null; } // getting GPS status isGPSEnabled = locationManager .isProviderEnabled(LocationManager.GPS_PROVIDER); // getting network status isNetworkEnabled = locationManager .isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { // no network provider is enabled } else { this.canGetLocation = true; if (isNetworkEnabled) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } // if GPS Enabled get lat/long using GPS Services if (isGPSEnabled) { if (location == null) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } } } } catch (Exception e) { e.printStackTrace(); } return location; }
4. 补充stopUsingGPS方法的权限检查
stopUsingGPS中的removeUpdates同样需要定位权限,也要同步修改:
public void stopUsingGPS(){ if(locationManager != null){ if (ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { locationManager.removeUpdates(GPSTracker.this); } } }
注意事项
- 运行时权限申请需要在Activity或Fragment中触发,GPSTracker作为Service无法直接弹出权限申请弹窗,建议你在初始化GPSTracker之前,先在跳转的页面向用户申请定位权限,用户同意后再初始化GPSTracker,逻辑会更顺畅。
- 如果你已经确认调用GPSTracker前一定会先拿到权限,可以在getLocation方法上添加
@SuppressLint("MissingPermission")注解直接消除编译报错,但生产环境不建议只靠注解绕开检查,避免运行时崩溃。
内容的提问来源于stack exchange,提问作者Pranay Sadani
相关产品推荐
相关产品推荐

