升级Android targetSdkVersion至33时位置权限异常求助
升级targetSdkVersion至33后触发位置权限SecurityException问题
原配置信息
build.gradle配置
compileSdkVersion 19 buildToolsVersion '26.0.2' defaultConfig { minSdkVersion 14 targetSdkVersion 19 }
AndroidManifest.xml配置
android:minSdkVersion="14" android:targetSdkVersion="19" uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
升级后的异常信息
升级compileSdkVersion、targetSdkVersion到33,适配更新buildToolsVersion后,在Android13设备上触发以下异常:
java.lang.RuntimeException: Unable to start activity ComponentInfo{activity.MainActivity}: java.lang.SecurityException: uid 10159 does not have android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION. at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3645) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3782) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7872) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) Caused by: java.lang.SecurityException: uid 10159 does not have android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION.
补充场景说明
- targetSdkVersion=19在Android13上启动:系统先弹出权限申请界面,再提示旧版本兼容信息,最后进入登录界面
- targetSdkVersion=33在Android13上启动:直接进入登录界面,无权限申请弹窗;输入登录凭证后触发上述异常
异常触发代码
异常抛出在GPSManager构造方法的这一行:
Location gpsLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
相关代码片段
public abstract class MyActivity extends AnaliticsActivity implements OnRefreshListener { private GPSManager gpsManager; private Context mContext; @Override protected void onCreate(Bundle arg0) { super.onCreate(arg0); mContext = this; initActivity(); initHelpers(); initActionBar(); } private void initActivity() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } private void initHelpers() { gpsManager = new GPSManager(getApplicationContext()); // ...其他初始化逻辑 } // ...其他代码 } public class GPSManager implements LocationListener { private LocationManager mLocationManager; public GPSManager(Context context) { mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); Location gpsLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); // ...后续逻辑 } // ...其他代码 }
解决方案
1. 更新AndroidManifest权限声明
针对Android13(API33),若仅需前台位置访问,保留原有权限即可;若需后台位置访问,需额外添加对应权限:
<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" android:maxSdkVersion="33" />
2. 实现动态权限申请逻辑
targetSdkVersion>=23开始,系统不再自动弹出权限申请,必须由应用主动发起。修改MyActivity逻辑,在初始化GPSManager前先检查并申请权限:
public abstract class MyActivity extends AnaliticsActivity implements OnRefreshListener { private GPSManager gpsManager; private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001; private String[] REQUIRED_LOCATION_PERMISSIONS = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }; @Override protected void onCreate(Bundle arg0) { super.onCreate(arg0); mContext = this; initActivity(); checkLocationPermissions(); // 先检查权限,再初始化Helpers initActionBar(); } private void checkLocationPermissions() { boolean hasFineLocation = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; boolean hasCoarseLocation = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; if (hasFineLocation && hasCoarseLocation) { // 权限已获取,初始化GPSManager initHelpers(); } else { // 申请权限 ActivityCompat.requestPermissions(this, REQUIRED_LOCATION_PERMISSIONS, LOCATION_PERMISSION_REQUEST_CODE); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { initHelpers(); } else { // 处理权限被拒绝的情况,比如提示用户开启权限 Toast.makeText(this, "需要位置权限才能正常使用功能", Toast.LENGTH_SHORT).show(); } } } private void initHelpers() { gpsManager = new GPSManager(getApplicationContext()); // ...其他初始化逻辑 } // ...其他代码 }
3. 优化GPSManager初始化逻辑
避免在构造方法中直接调用需要权限的API,改为提供初始化方法,在权限获取后再执行位置相关操作:
public class GPSManager implements LocationListener { private LocationManager mLocationManager; private Context mContext; public GPSManager(Context context) { mContext = context; mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); } // 新增初始化方法,在权限获取后调用 public void initLocation() { if (checkPermission()) { Location gpsLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); // ...后续逻辑 } } private boolean checkPermission() { boolean hasFine = ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; boolean hasCoarse = ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; return hasFine || hasCoarse; } // ...其他代码 }
然后在initHelpers中调用:
private void initHelpers() { gpsManager = new GPSManager(getApplicationContext()); gpsManager.initLocation(); // ...其他初始化逻辑 }
内容的提问来源于stack exchange,提问作者api
相关产品推荐
相关产品推荐

