Android 14:用户拒绝照片视频权限后如何再次请求?需用shouldShowPermissionRationale
修复权限拒绝后无法再次发起请求的问题
核心逻辑补充
当用户首次拒绝权限后,系统会根据用户是否勾选「不再询问」,决定是否允许再次弹出权限请求。我们需要通过shouldShowRequestPermissionRationale方法区分两种拒绝场景:临时拒绝(可再次请求)、永久拒绝(需引导至设置页),同时在请求前添加权限用途解释的逻辑。
修改后的完整代码
1. 权限请求方法(添加Rationale检查)
public void requestPhotoAndVideoPermissions() { List<String> permissions = new ArrayList<>(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { permissions.add(Manifest.permission.READ_MEDIA_IMAGES); permissions.add(Manifest.permission.READ_MEDIA_VIDEO); } else { permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); } // 筛选需要显示权限说明的权限 List<String> needRationalePerms = new ArrayList<>(); for (String perm : permissions) { if (ContextCompat.checkSelfPermission(requireContext(), perm) != PackageManager.PERMISSION_GRANTED && shouldShowRequestPermissionRationale(perm)) { needRationalePerms.add(perm); } } if (!needRationalePerms.isEmpty()) { // 弹出弹窗解释权限用途,用户确认后再发起请求 new AlertDialog.Builder(requireContext()) .setTitle("需要媒体权限") .setMessage("应用需要访问您的照片和视频以完成相关功能,请授予权限。") .setPositiveButton("确定", (dialog, which) -> { dialog.dismiss(); requestPermissionLauncher.launch(permissions.toArray(new String[0])); }) .setNegativeButton("取消", (dialog, which) -> { dialog.dismiss(); onPermissionDenied(); }) .show(); } else { // 无需要解释的权限,直接发起请求 requestPermissionLauncher.launch(permissions.toArray(new String[0])); } }
2. 权限回调(区分拒绝类型)
private ActivityResultLauncher<String[]> requestPermissionLauncher = registerForActivityResult( new ActivityResultContracts.RequestMultiplePermissions(), permissionsMap -> { boolean allGranted = true; boolean isPermanentlyDenied = false; for (Map.Entry<String, Boolean> entry : permissionsMap.entrySet()) { String perm = entry.getKey(); Boolean granted = entry.getValue(); if (!granted) { allGranted = false; // 判断是否永久拒绝(用户勾选了「不再询问」) if (!shouldShowRequestPermissionRationale(perm)) { isPermanentlyDenied = true; } } } if (allGranted) { Toast.makeText(requireContext(), "权限已授予", Toast.LENGTH_LONG).show(); onPermissionGranted(); } else { if (isPermanentlyDenied) { // 永久拒绝,引导用户去设置页开启权限 new AlertDialog.Builder(requireContext()) .setTitle("权限被永久拒绝") .setMessage("您已关闭媒体权限的请求提示,请前往应用设置开启权限以使用相关功能。") .setPositiveButton("去设置", (dialog, which) -> { dialog.dismiss(); Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", requireContext().getPackageName(), null); settingsIntent.setData(uri); startActivity(settingsIntent); }) .setNegativeButton("取消", (dialog, which) -> { dialog.dismiss(); onPermissionDenied(); }) .show(); } else { // 临时拒绝,提示用户可再次请求 Toast.makeText(requireContext(), "权限被拒绝,您可以再次发起请求", Toast.LENGTH_LONG).show(); onPermissionDenied(); } } } );
关键逻辑说明
- 请求前的Rationale检查:
shouldShowRequestPermissionRationale返回true时,说明用户之前拒绝过权限但未勾选「不再询问」,此时必须先向用户解释权限用途,再发起请求,否则系统会拦截后续请求。 - 回调中的拒绝类型区分:在权限回调中,再次调用
shouldShowRequestPermissionRationale,若返回false则表示用户永久拒绝了权限,此时只能引导用户前往应用设置页手动开启;若返回true则是临时拒绝,用户可再次触发权限请求。
内容的提问来源于stack exchange,提问作者Asif Hussain
相关产品推荐
相关产品推荐

