You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13模拟器中READ_EXTERNAL_STORAGE权限请求不显示问题

权限请求在Android 13(API 33)模拟器上无响应的解决方案

我通过Map<Integer, Runnable>实现了Activity权限请求的结果处理器:请求权限时生成随机请求码,将请求码与对应的处理逻辑绑定,权限回调时执行对应逻辑。该实现在Android 12(API 31)真机上运行正常,但在Android 13(API 33)模拟器上出现异常:权限请求无弹窗,权限始终未授予,且Manifest中声明的权限未在应用信息中显示。

一、权限处理实现代码

private final HashMap<Integer, Runnable> onPermission = new HashMap<>();

// 从其他类调用此方法请求权限并注册处理器
public void requestPermission(Runnable onGranted, String...permissions) {
    int code = Permissions.permissionRequestCode();
    onPermission.put(code, onGranted);
    requestPermissions(permissions, code);
}

// 重写此方法检查是否有对应请求码的处理器
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    Runnable handler = onPermission.get(requestCode);
    if (handler != null && isGranted(grantResults)) {
        handler.run();
        onPermission.remove(requestCode);
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

// 检查所有请求权限是否被授予的工具方法
private boolean isGranted(int[] results) {
    for (int i : results) {
        if (i != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
    }
    return true;
}

二、使用示例

private void readImages() {
    if (ContextCompat.checkSelfPermission(owner, Manifest.permission.READ_EXTERNAL_STORAGE)
            == PackageManager.PERMISSION_GRANTED) {
        loadImages();
    } else {
        owner.requestPermission(this::loadImages, Manifest.permission.READ_EXTERNAL_STORAGE);
    }
}

三、Manifest配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Mesa"
        android:roundIcon="@mipmap/ic_launcher"
        android:supportsRtl="true"
        android:theme="@style/Theme.Mesa.NoActionBar"
        android:usesCleartextTraffic="true">
        <activity
            android:name=".app.Mesa"
            android:configChanges="uiMode|screenSize|colorMode"
            android:exported="true"
            android:theme="@style/Theme.Mesa.NoActionBar"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

四、build.gradle配置

android {
    compileSdk 33

    defaultConfig {
        applicationId "org.luke.mesa"
        minSdk 24
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        proguardFiles 'proguard-rules.pro'
    }

    buildTypes {
        release {
            minifyEnabled true
        }

        debug {
            minifyEnabled false
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
        allprojects {
            tasks.withType(JavaCompile){
                options.compilerArgs <<"-Xlint:deprecation"
            }
        }
    }
    buildFeatures {
        viewBinding true
        dataBinding true
    }
    packagingOptions {
        resources {
            merges += ['META-INF/DEPENDENCIES']
        }
    }
    namespace 'org.luke.mesa'
    dependenciesInfo {
        includeInApk true
        includeInBundle true
    }
    buildToolsVersion '33.0.0'
}

解决方案

1. 适配Android 13存储权限变更

Android 13(API 33)彻底重构了存储权限体系,READ_EXTERNAL_STORAGE被标记为废弃,系统不再为该权限触发弹窗请求,直接返回拒绝状态,且该权限不会在应用信息中展示。需根据媒体类型使用新权限:

  • 读取图片/照片:android.permission.READ_MEDIA_IMAGES
  • 读取视频:android.permission.READ_MEDIA_VIDEO
  • 读取音频:android.permission.READ_MEDIA_AUDIO

2. 更新Manifest权限声明

保留旧权限兼容Android 12及以下版本,添加新权限适配Android 13+:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>

3. 修改动态权限请求逻辑

根据系统版本选择对应权限请求:

private void readImages() {
    String permission;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        permission = Manifest.permission.READ_MEDIA_IMAGES;
    } else {
        permission = Manifest.permission.READ_EXTERNAL_STORAGE;
    }

    if (ContextCompat.checkSelfPermission(owner, permission) == PackageManager.PERMISSION_GRANTED) {
        loadImages();
    } else {
        owner.requestPermission(this::loadImages, permission);
    }
}

4. 验证请求码合法性

确保Permissions.permissionRequestCode()生成的请求码为0-65535之间的整数,超出范围会导致权限请求无法正确回调。

5. 模拟器环境校验

  • 使用官方稳定版Android 13模拟器镜像,避免预览版或自定义镜像
  • 清除应用数据并重启模拟器后重新测试

内容的提问来源于stack exchange,提问作者SDIDSA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:35:26