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

为何通过PackageInfo获取权限时丢失WRITE_EXTERNAL_STORAGE?

为什么获取Manifest权限时WRITE_EXTERNAL_STORAGE丢失了?

我遇到一个奇怪的问题:我的AndroidManifest.xml里明明声明了8个权限,其中包含android.permission.WRITE_EXTERNAL_STORAGE,但用代码读取Manifest中的权限列表时,这个权限居然不见了!

先给大家看看我的配置和代码:

我的AndroidManifest.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.jiyuzhai.xxxx">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_SETTINGS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.vending.BILLING"/>
<!-- 应用组件部分省略 -->
</manifest>

SDK版本配置

ext {
    compileSdkVersion = 28
    minSdkVersion = 17
    targetSdkVersion = 28
    buildToolsVersion = '28.0.3'
}

获取权限的代码

try {
    PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
    String[] permissions = packageInfo.requestedPermissions;
    if (permissions == null || permissions.length == 0) {
        throw new IllegalStateException("You did not register any permissions in the manifest.xml.");
    }
    return Collections.unmodifiableList(Arrays.asList(permissions));
} catch (PackageManager.NameNotFoundException e) {
    throw new AssertionError("Package name cannot be found.");
}

运行这段代码后,返回的权限列表里确实没有android.permission.WRITE_EXTERNAL_STORAGE,这是为什么呢?


原因分析

这其实是Android系统的权限机制导致的:

从Android 4.4(API 19)开始,WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE属于同一个权限组(STORAGE)。当你的应用targetSdkVersion >= 19时,只要你在Manifest中声明了READ_EXTERNAL_STORAGE,系统会自动隐含授予WRITE_EXTERNAL_STORAGE权限,不需要单独请求。

而通过PackageManager.GET_PERMISSIONS获取的是应用显式请求且系统认为需要单独列出的权限,对于这种被隐含授予的关联权限,系统不会将其返回在requestedPermissions数组中。你的targetSdkVersion是28,完全符合这个规则,所以就出现了WRITE权限"丢失"的情况。

验证与解决方案

如果你想确认应用是否真的拥有WRITE_EXTERNAL_STORAGE权限,可以用Context.checkSelfPermission()来检查:

int writePermissionStatus = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (writePermissionStatus == PackageManager.PERMISSION_GRANTED) {
    // 应用确实拥有WRITE权限
}

你会发现返回的是PERMISSION_GRANTED,说明权限其实是存在的,只是没出现在获取的列表里而已。

如果你的业务逻辑必须要在权限列表中包含WRITE_EXTERNAL_STORAGE,其实没有必要——因为系统已经自动处理了权限关联。但如果你非要显式获取到它,可以尝试将targetSdkVersion降到18以下(不推荐,会影响其他功能的兼容性),不过这显然不是合理的解决方案。

正确的做法是理解这个权限机制,通过权限组的角度去处理存储权限,而不是依赖requestedPermissions数组中的每一个权限条目。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:51:15