Android 30及以上版本申请位置权限时页面崩溃求助
Android 30+版本定位权限申请时页面崩溃的解决方案
一、修复代码顺序导致的空指针崩溃
你的onCreate方法中,getSupportActionBar().hide();调用时机错误,必须放在super.onCreate(savedInstanceState);和setContentView(R.layout.backup_main);之后——只有执行super.onCreate完成初始化,ActionBar实例才会存在,提前调用hide()会触发NullPointerException导致崩溃。修正后的代码:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.backup_main); getSupportActionBar().hide(); // 移到此处 mDashboardActivity = this; getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) checkPermissions(); else permissionOK(); }
二、完善AndroidManifest权限声明(针对Android 30+)
确保Manifest中正确声明定位权限,若targetSdkVersion >=30,还需注意前台服务定位的配置:
<!-- 前台定位必备权限 --> <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" /> --> <!-- 如果使用前台服务进行定位,需指定foregroundServiceType --> <service android:name=".YourLocationForegroundService" android:foregroundServiceType="location" />
三、补充权限申请结果回调处理
当前代码仅发起权限申请,但未处理用户的授权结果,需重写onRequestPermissionsResult方法,根据授权状态执行对应逻辑:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 10) { boolean allPermissionsGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allPermissionsGranted = false; break; } } if (allPermissionsGranted) { permissionOK(); } else { handlePermissionDenied(); } } } private void handlePermissionDenied() { // 检查是否需要引导用户到设置页开启权限(Android 11+特性) boolean shouldShowRationale = false; for (String permission : new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { shouldShowRationale = true; break; } } if (!shouldShowRationale) { // 用户勾选了"不再询问",跳转应用设置页 Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); settingsIntent.setData(uri); startActivity(settingsIntent); } else { Toast.makeText(this, "定位权限被拒绝,部分功能无法使用", Toast.LENGTH_SHORT).show(); } }
四、权限申请逻辑优化(可选)
针对Android 11+,建议先向用户说明权限用途,再发起申请,提升用户授权意愿:
private void checkPermissions() { String[] locationPermissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}; List<String> neededPermissions = new ArrayList<>(); for (String p : locationPermissions) { if (ContextCompat.checkSelfPermission(this, p) != PackageManager.PERMISSION_GRANTED) { neededPermissions.add(p); } } if (!neededPermissions.isEmpty()) { // 先展示权限说明弹窗 new AlertDialog.Builder(this) .setTitle("需要定位权限") .setMessage("应用需要获取定位信息以完成XX功能,请授权") .setPositiveButton("确定", (dialog, which) -> { ActivityCompat.requestPermissions(this, neededPermissions.toArray(new String[0]), 10); }) .setNegativeButton("取消", null) .show(); } else { permissionOK(); } }
内容的提问来源于stack exchange,提问作者Aqilah Mokhtarudin
相关产品推荐
相关产品推荐

