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

Android应用未请求READ_EXTERNAL_STORAGE权限问题排查

解决WallpaperManager获取壁纸时权限请求异常问题

一、核心问题:API版本的权限适配错误

Android 13(API 33)及以上版本中,READ_EXTERNAL_STORAGE已被废弃,系统不再处理该权限的弹框请求,取而代之的是READ_MEDIA_IMAGES权限。你虽然在清单中声明了READ_MEDIA_IMAGES,但权限检查和请求逻辑仍在针对旧版本的READ_EXTERNAL_STORAGE,导致API33+设备上不会弹出存储权限请求框。

二、最优解决方案:使用无需权限的WallpaperManager API

从Android 8.0(API 26)开始,WallpaperManager提供了更直接的壁纸获取方法,不需要任何存储权限,完全可以规避权限问题:

val wallpaperManager = WallpaperManager.getInstance(this)
// 获取系统桌面壁纸
val systemWallpaper = wallpaperManager.getDrawable(WallpaperManager.FLAG_SYSTEM)
// 获取锁屏壁纸
val lockWallpaper = wallpaperManager.getDrawable(WallpaperManager.FLAG_LOCK)

这个方法直接从系统壁纸服务获取资源,绕过了外部存储访问,是官方推荐的实现方式。

三、如果必须兼容旧版本:修正权限申请逻辑

若需适配API23到API32的设备,需按版本分支处理权限请求,同时注意特殊权限的申请方式:

fun isStoragePermissionGranted(): Boolean {
    return when {
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> { // API33+
            if (checkSelfPermission(Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED) {
                Log.v(TAG, "权限已授予")
                true
            } else {
                Log.v(TAG, "权限未授予,发起请求")
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(Manifest.permission.READ_MEDIA_IMAGES),
                    1
                )
                false
            }
        }
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> { // API23-32
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                Log.v(TAG, "权限已授予")
                true
            } else {
                Log.v(TAG, "权限未授予,发起请求")
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                    1
                )
                false
            }
        }
        else -> { // API<23,安装时自动授予权限
            Log.v(TAG, "权限已授予")
            true
        }
    }
}

另外注意:MANAGE_EXTERNAL_STORAGE是特殊权限,无法通过requestPermissions弹框申请,必须跳转到系统设置页单独申请:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
    intent.data = Uri.parse("package:" + packageName)
    startActivity(intent)
}

四、为什么相机权限会弹框而存储权限不会?

相机权限属于Android标准的危险权限,无论哪个版本都需要弹框请求;而READ_EXTERNAL_STORAGE在API33+被标记为过时,系统会直接忽略该权限的请求,因此不会弹出对应的权限对话框。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:30:26