Android 10存储权限请求无弹窗问题排查(适配5-13版本)
Android 10设备存储权限请求无弹窗问题排查与解决
问题背景
使用NativeVue+Java开发应用,需实现设备内部存储读写操作,但在Android 10设备运行时,权限请求未弹出任何弹窗。
已配置的Manifest权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
Java端实现代码
权限检查方法
public static boolean checkStoragePermissions(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // Android 11 (R) 及以上 Log.d("createDir", "Android est 11 (R) ou supérieur"); return Environment.isExternalStorageManager(); } else { // Android 11以下 Log.d("createDir", "Inférieur à Android 11"); int write = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE); int read = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE); return read == PackageManager.PERMISSION_GRANTED && write == PackageManager.PERMISSION_GRANTED; }
权限请求方法
public static boolean requestForStoragePermissions(Activity activity, ActivityResultLauncher<Intent> storageActivityResultLauncher) { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { Intent intent = new Intent(); intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); Uri uri = Uri.fromParts("package", activity.getPackageName(), null); intent.setData(uri); if (storageActivityResultLauncher != null) { storageActivityResultLauncher.launch(intent); } else { activity.startActivity(intent); } return true; // 请求成功 } else { Log.d("createDir", "Inférieur à Android 11"); Log.d("createDir", activity.toString()); ActivityCompat.requestPermissions( activity, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }, STORAGE_PERMISSION_CODE); return true; // 请求成功 } } catch (Exception e) { e.printStackTrace(); return false; // 请求出错 }
Vue端调用代码
requestStoragePermissions() { const activity = Application.android.foregroundActivity || Application.android.startActivity; let ctx = Utils.android.getApplicationContext(); let execc = com.ecodev.Mifi.MyUtils.requestForStoragePermissions(activity, null); let exec = com.ecodev.Mifi.MyUtils.checkStoragePermissions(ctx); console.log('requestForStoragePermissions' + execc); console.log(exec); },
问题原因及解决方案
1. 核心原因:Android 10分区存储机制
Android 10(API 29)默认启用分区存储,此时即使Manifest中声明了WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE,系统也不会弹出权限请求弹窗——因为分区存储模式下,这两个权限的弹窗逻辑被屏蔽了。
2. 具体修复步骤
步骤一:启用旧版存储模型
在Manifest的<application>标签下添加android:requestLegacyExternalStorage="true",强制Android 10设备使用旧版存储权限逻辑,触发弹窗:
<application ... android:requestLegacyExternalStorage="true"> ... </application>
步骤二:优化权限请求逻辑
避免重复请求已授予的权限,修改Vue端调用代码,先检查权限状态再发起请求:
requestStoragePermissions() { const activity = Application.android.foregroundActivity || Application.android.startActivity; let ctx = Utils.android.getApplicationContext(); // 先判断权限未授予时再发起请求 if (!com.ecodev.Mifi.MyUtils.checkStoragePermissions(ctx)) { let execc = com.ecodev.Mifi.MyUtils.requestForStoragePermissions(activity, null); console.log('requestForStoragePermissions result: ' + execc); } else { console.log('Storage permissions already granted'); } },
步骤三:清理冗余权限
MANAGE_EXTERNAL_STORAGE是Android 11+专属权限,Android 10设备无需配置,直接移除该权限声明:
<!-- 移除该权限,仅在Android 11+版本保留 --> <!-- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/> -->
3. 额外注意事项
- 若应用目标SDK为30及以上,Android 11+设备仍会强制启用分区存储,此时需通过
MANAGE_EXTERNAL_STORAGE权限申请全存储访问,但不影响Android 10设备的修复效果。 - 确保
STORAGE_PERMISSION_CODE是唯一整数常量,避免与其他权限请求码冲突。
内容的提问来源于stack exchange,提问作者Vebama Wanematou
相关产品推荐
相关产品推荐

