Android 13及以上READ_EXTERNAL_STORAGE权限请求不显示问题求助
Android 13+ WebView文件上传权限问题解决方法
问题根源拆解
- Android 13权限规则变更:
READ_EXTERNAL_STORAGE在Android 13(API 33)及以上被废弃,系统会自动将该权限标记为"已授予",不会触发弹窗请求。此时应使用READ_MEDIA_IMAGES/READ_MEDIA_VIDEO等细分媒体权限。 - 权限请求与结果的索引对应错误:你请求权限的数组顺序是
[READ_EXTERNAL_STORAGE, CAMERA],但在onRequestPermissionsResult里错误地将grantResults[0]判定为相机权限、grantResults[1]判定为存储权限,完全搞反了顺序。 - 权限判断逻辑未适配版本:没有针对Android 13+调整权限检查的条件,导致错误判断权限状态,进而触发错误的Toast提示。
修复后的代码实现
1. 权限请求方法修正
private boolean file_permission(){ if(Build.VERSION.SDK_INT >= 23){ // 区分Android版本处理权限检查 boolean hasCameraPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; boolean hasStoragePerm; if(Build.VERSION.SDK_INT >= 33){ // Android 13+ 使用媒体权限替代READ_EXTERNAL_STORAGE hasStoragePerm = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED; } else { // Android 12及以下 使用READ_EXTERNAL_STORAGE hasStoragePerm = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; } if(!hasCameraPerm || !hasStoragePerm){ // 根据版本构建请求权限数组 ArrayList<String> permList = new ArrayList<>(); if(!hasCameraPerm) permList.add(Manifest.permission.CAMERA); if(Build.VERSION.SDK_INT >=33){ if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) != PackageManager.PERMISSION_GRANTED){ permList.add(Manifest.permission.READ_MEDIA_IMAGES); } if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO) != PackageManager.PERMISSION_GRANTED){ permList.add(Manifest.permission.READ_MEDIA_VIDEO); } } else { if(!hasStoragePerm) permList.add(Manifest.permission.READ_EXTERNAL_STORAGE); } ActivityCompat.requestPermissions(MainActivity.this, permList.toArray(new String[0]), 1); return false; } else { return true; } } else { return true; } }
2. 权限结果回调修正
@Override public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(permsRequestCode, permissions, grantResults); if(permsRequestCode != 1) return; boolean allGranted = true; boolean cameraDeniedPermanently = false; boolean mediaDeniedPermanently = false; // 遍历所有请求的权限,逐个检查状态 for(int i=0; i<permissions.length; i++){ String perm = permissions[i]; int result = grantResults[i]; if(result == PackageManager.PERMISSION_GRANTED){ if(perm.equals(Manifest.permission.CAMERA)){ Log.d("Permissions", "Camera permission granted"); } else if(perm.equals(Manifest.permission.READ_EXTERNAL_STORAGE)){ Log.d("Permissions", "Read external storage permission granted"); } else if(perm.equals(Manifest.permission.READ_MEDIA_IMAGES)){ Log.d("Permissions", "Read media images permission granted"); } else if(perm.equals(Manifest.permission.READ_MEDIA_VIDEO)){ Log.d("Permissions", "Read media video permission granted"); } } else { allGranted = false; // 判断是否永久拒绝 if(!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, perm)){ if(perm.equals(Manifest.permission.CAMERA)){ cameraDeniedPermanently = true; } else { mediaDeniedPermanently = true; } } } } // 根据权限状态显示对应提示 if(allGranted){ Toast.makeText(getApplicationContext(), "You can now upload images/files.", Toast.LENGTH_LONG).show(); } else { if(cameraDeniedPermanently || mediaDeniedPermanently){ Toast.makeText(getApplicationContext(), "You have permanently blocked image/file upload.", Toast.LENGTH_LONG).show(); } else { Toast.makeText(getApplicationContext(), "Your permission is required to upload images/files.", Toast.LENGTH_LONG).show(); } } }
关键修复说明
- 版本适配:Android 13+不再请求
READ_EXTERNAL_STORAGE,转而请求对应的媒体权限,避免系统自动标记该权限为已授予的问题。 - 索引对应:遍历权限数组和结果数组,直接通过权限字符串匹配,彻底解决索引顺序错误的问题。
- 状态判断:分别检查每个权限的授予状态和是否永久拒绝,避免单一权限判断导致的错误提示。
内容的提问来源于stack exchange,提问作者perps4214213
相关产品推荐
相关产品推荐

