Android | 如何申请 android.permission.MANAGE_EXTERNAL_STORAGE 权限 以便在 Android 11 之后管理设备上的所有文件

一、问题背景

当在开发 Android 应用期望访问存储的文件时,对于标准应用来说,应该使用 SAF 框架以便用户选择文件进行访问:https://developer.android.com/guide/topics/providers/document-provider

但是,如果开发的应用是文件管理器等需要访问整个存储,则通过SAF会不方便。

Android 10 中引入分区存储前,如果一个应用想访问设备上的文件时,只需要申请读写外部存储的权限即可,即在 AndroidManifest.xml 文件中声明,随后申请运行时权限即可。:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application>
    </application>
</manifest>

但是在 Android 10 之后,直接申请权限之后仍然不能读写所有外部存储,需要在 application 中声明 android:requestLegacyExternalStorage="true",以便过渡。

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application android:requestLegacyExternalStorage="true">
    </application>
</manifest>

Android 11 之后,引入了 android.permission.MANAGE_EXTERNAL_STORAGE 权限,申请此权限可以管理存储设备上的所有文件,以满足业务需求,但是此权限需要用户手动授予。本文将详细介绍此权限的申请和使用。

参考:https://developer.android.com/training/data-storage/manage-all-files?hl=zh-cn

二、MANAGE_EXTERNAL_STORAGE 权限声明

首先,我们在 AndroidManifest.xml 文件中声明权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

    <application>
    </application>
</manifest>

此时应用就声明了 管理存储设备上的所有文件 的权限。

三、MANAGE_EXTERNAL_STORAGE 权限申请

此权限需要用户手动授予,可以通过Intent引导用户到设置页面,授予应用所有文件的管理权限。

我们使用 Environment.isExternalStorageManager() 方法可以先检查应用是否被授予了 所有文件访问权限:

Environment.isExternalStorageManager()

如果还未授予所有文件的管理权限,则需要在 ActivityonCreate 方法中 使用 AppCompact.registerForActivityResult() 跳转到设置页面 进行申请权限:

val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
    // 这里是用户从权限授予页面返回到应用页面的回调,需要查询是否授予
    if (Environment.isExternalStorageManager()) {
        // 用户授予所有文件访问权限
    } else {
        // 用户未授予所有文件访问权限
    }
}
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
// 这里需要指定应用的包名
intent.data = "package:${packageName}".toUri()
launcher.launch(intent)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值