Android应用请求存储权限以下载bundle.txt问题排查
解决Android存储权限请求不弹出的问题
你只在Manifest里声明存储权限是不够的——Android 6.0(API 23)及以上版本中,存储权限属于危险权限,必须通过代码动态向用户申请,系统才会弹出权限请求对话框。以下是具体解决步骤:
1. 确认目标SDK版本
检查Module级别的build.gradle文件,确保targetSdkVersion的值≥23。如果低于23,系统会自动授予Manifest中声明的权限(无需弹窗),但这不符合现代Android权限规范。
2. 动态申请存储权限的代码实现
推荐方式:使用AndroidX ActivityResultContracts
这是Google推荐的替代旧requestPermissions的方法,代码更简洁且生命周期安全:
// Kotlin 示例,在Activity/Fragment中实现 private val requestStoragePermissions = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> val allGranted = permissions.values.all { it } if (allGranted) { // 权限已授予,执行bundle文件下载逻辑 downloadBundleFile() } else { // 权限被拒绝,提示用户前往设置开启 Toast.makeText(this, "需要存储权限才能下载文件", Toast.LENGTH_SHORT).show() } } // 在需要触发下载的时机调用(如按钮点击、页面初始化) private fun checkAndRequestPermissions() { val hasWritePerm = ContextCompat.checkSelfPermission( this, Manifest.permission.WRITE_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED val hasReadPerm = ContextCompat.checkSelfPermission( this, Manifest.permission.READ_EXTERNAL_STORAGE ) == PackageManager.PERMISSION_GRANTED if (!hasWritePerm || !hasReadPerm) { // 发起权限请求 requestStoragePermissions.launch( arrayOf( Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE ) ) } else { // 已有权限,直接下载 downloadBundleFile() } }
兼容旧版本:使用requestPermissions方法
如果未使用AndroidX,可采用传统回调方式:
// Java 示例 private static final int STORAGE_PERMISSION_REQUEST_CODE = 100; private void checkStoragePermission() { boolean hasWritePerm = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; boolean hasReadPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; if (!hasWritePerm || !hasReadPerm) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE); } else { downloadBundleFile(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == STORAGE_PERMISSION_REQUEST_CODE) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { downloadBundleFile(); } else { Toast.makeText(this, "需要存储权限才能下载文件", Toast.LENGTH_SHORT).show(); } } }
3. 高版本Android适配注意事项
- Android 10(API 29)+:默认启用分区存储,即使拥有
WRITE_EXTERNAL_STORAGE权限,也只能访问应用专属目录或通过MediaStore操作公共文件。若需下载到公共目录(如Downloads),可在Manifest中临时添加兼容标记(不推荐长期使用):<application android:requestLegacyExternalStorage="true"> - Android 13(API 33)+:存储权限拆分,访问文档类文件需额外声明
READ_MEDIA_DOCUMENTS权限,动态申请时也要包含该权限:<uses-permission android:name="android.permission.READ_MEDIA_DOCUMENTS" />
4. 验证Manifest权限声明
确保Manifest中的权限无拼写错误,完整声明如下:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 13+ 额外添加 --> <uses-permission android:name="android.permission.READ_MEDIA_DOCUMENTS" />
内容的提问来源于stack exchange,提问作者Italiana Computer
相关产品推荐
相关产品推荐

