Dexter请求READ_EXTERNAL_STORAGE权限自动拒绝,求解决方案
权限未弹出询问即自动拒绝的解决办法
问题描述
我编写了请求READ_EXTERNAL_STORAGE权限的代码,获取权限后会执行displayAudios()函数,但权限未弹出询问窗口就自动被拒绝,导致函数无法运行。参考过相关问题的解决方案但无效,寻求其他解决办法。
现有代码
权限请求函数
private void checkPermission() { Dexter.withContext(getContext()) .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE) .withListener(new PermissionListener() { @Override public void onPermissionGranted(PermissionGrantedResponse response) { displayAudios(); } @Override public void onPermissionDenied(PermissionDeniedResponse response) { Toast.makeText(getContext(), "Permission Denied...", Toast.LENGTH_SHORT).show(); } @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) { new AlertDialog.Builder(getContext()) .setTitle("Permission Required") .setMessage("This app requires permission to read external storage to display audio files.") .setPositiveButton("OK", (dialog, which) -> token.continuePermissionRequest()) .setNegativeButton("Cancel", (dialog, which) -> token.cancelPermissionRequest()) .show(); } }) .check(); }
Manifest.xml代码
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.tts"> <!-- Other permissions and features --> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:installLocation="preferExternal" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.TTS" tools:targetApi="34"> <activity android:name=".PlayerActivity" android:exported="false" /> <!-- Activities, services, etc. --> <activity android:name=".MainActivity" android:exported="true" android:theme="@style/Theme.TTS.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="replace" /> </manifest>
解决方案
1. 适配Android 13+的媒体权限
Android 13(API 33)及以上版本废弃了READ_EXTERNAL_STORAGE,访问音频文件需要使用READ_MEDIA_AUDIO权限:
- 更新Manifest权限声明:
<!-- 适配Android 12及以下版本 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" tools:node="replace" /> <!-- 适配Android 13+版本 --> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> - 修改权限请求代码,根据系统版本动态选择权限:
private void checkPermission() { String permission; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { permission = Manifest.permission.READ_MEDIA_AUDIO; } else { permission = Manifest.permission.READ_EXTERNAL_STORAGE; } Dexter.withContext(getContext()) .withPermission(permission) .withListener(new PermissionListener() { @Override public void onPermissionGranted(PermissionGrantedResponse response) { displayAudios(); } @Override public void onPermissionDenied(PermissionDeniedResponse response) { if (response.isPermanentlyDenied()) { // 引导用户前往设置页开启权限 Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getContext().getPackageName(), null); intent.setData(uri); getContext().startActivity(intent); Toast.makeText(getContext(), "权限已被永久拒绝,请在设置中开启", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getContext(), "权限被拒绝...", Toast.LENGTH_SHORT).show(); } } @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) { new AlertDialog.Builder(getContext()) .setTitle("需要权限") .setMessage("此应用需要读取音频文件的权限才能显示音频内容。") .setPositiveButton("确定", (dialog, which) -> token.continuePermissionRequest()) .setNegativeButton("取消", (dialog, which) -> token.cancelPermissionRequest()) .show(); } }) .check(); }
2. 移除tools:node="replace"的影响
tools:node="replace"会覆盖合并后的权限配置,若有依赖库也声明了该权限,可能导致权限被意外替换。尝试去掉该属性,改为普通权限声明:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
3. 处理永久拒绝的情况
如果用户之前勾选了“不再询问”并拒绝权限,系统会直接拒绝请求。此时需要引导用户到应用设置页手动开启权限,代码已包含在上面的权限请求函数中。
4. 更新Dexter库版本
确保使用最新版的Dexter库,旧版本可能对高API版本适配存在问题。在build.gradle中更新依赖:
implementation 'com.karumi:dexter:6.2.3' // 可前往官方确认最新版本
5. 调整应用安装位置
Manifest中设置的android:installLocation="preferExternal"可能导致权限请求异常,尝试移除该属性,默认安装到内部存储后测试。
内容的提问来源于stack exchange,提问作者AKD2022
相关产品推荐
相关产品推荐

