当前位置: 首页> 游戏> 网游 > Android R及以上版本中APP外部存储实现

Android R及以上版本中APP外部存储实现

时间:2025/7/13 16:39:20来源:https://blog.csdn.net/netwalk/article/details/139407356 浏览次数:0次

背景:

从 Android R开始,Google 引入了一些新的限制,以增强用户数据的隐私保护。其中之一是对外部存储的访问限制。如果APP的target>30,之前的WRITE_EXTERNAL_STORAGE/READ_EXTERNAL_STORAGE授权方案就完全不能使用了。本文将说明如何在 Android R及以上版本中实现外部存储空间的读写。

APP中实现在Android R及以上版本中外部存储路径下的读写方案,步骤概述如下:

步骤描述
1检查应用是否运行在 Android 11 上
2请求 MANAGE_EXTERNAL_STORAGE 权限
3检查是否已获得 MANAGE_EXTERNAL_STORAGE 权限
4获取外部存储路径

详细步骤如下:

步骤 1: 检查应用是否运行在 Android 11 上

在 AndroidManifest.xml 文件中添加以下代码,以指定应用的目标 SDK 版本为 30(Android 11):

<uses-sdk android:minSdkVersion="..." android:targetSdkVersion="30" />

步骤 2: 请求 MANAGE_EXTERNAL_STORAGE 权限

在 AndroidManifest.xml 文件中添加以下代码,以请求 MANAGE_EXTERNAL_STORAGE 权限:

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

为了兼容Android R之前的版本,完整的配置代码如下:

<!-- 操作sd卡权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"tools:ignore="SelectedPhotoAccess" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"tools:ignore="SelectedPhotoAccess" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion="32"tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE"tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"tools:ignore="ScopedStorage" />

步骤 3: 检查是否已获得 MANAGE_EXTERNAL_STORAGE 权限

在你需要访问外部存储路径的地方,添加以下代码,以检查是否已获得 MANAGE_EXTERNAL_STORAGE 权限:

if (Environment.isExternalStorageManager()) {// 已获得权限,可以访问外部存储路径
} else {// 未获得权限,需要请求权限Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).setData(Uri.parse("package:"+getPackageName()));startActivityForResult(intent, 0);
}

步骤 4: 获取外部存储路径

在你需要获取外部存储路径的地方,添加以下代码,以获取外部存储路径:

File externalStorageDirectory = Environment.getExternalStorageDirectory();
String externalStoragePath = externalStorageDirectory.getAbsolutePath();

总结

通过以上步骤,就可以在 Android 11 中实现外部存储路径的访问。首先,需要检查应用的目标 SDK 版本是否为 Android 11及以上版本,然后请求 MANAGE_EXTERNAL_STORAGE 权限并检查是否已获得该权限,最后可以使用 Environment.getExternalStorageDirectory() 方法获取外部存储路径。

需要注意的是:从 Android 11 开始,外部存储路径不再是应用的专属目录,而是共享的目录。因此,对于敏感数据,建议将其存储在应用的内部目录中,而不是外部存储路径。

补充:

如何出现两种不同的文件权限选项?

  • --允许管理所有文件
  • --仅允许访问媒体文件

1. 前提是 targetSdkVersion 大于等于 30. (build.gradle)
2. 当声明了 READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE
   --仅允许访问媒体文件
3. 当声明了 MANAGE_EXTERNAL_STORAGE 会增加允许管理所有文件
4. targetSdkVersion <= 28 时, 只有允许管理所有文件拒绝 选项.
 

20240606更新---调试适配手记

按这个操作调试不出意外的出了意外,允许管理所有文件的授权操作,在Android 14手机系统及模拟器上,是可以正常授权,APP也能获取到读写权限,没有问题。

但是,在高通8775的Android 14设备上运行,测试APP却出现闪退,不能授权的现象,日志中报错如下:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION dat=package: }

这是找不到Settings授权这个界面;

<category android:name="android.intent.category.DEFAULT" />

AndroidManest.xml中Default项也已经添加,报这个错,也就意味着设备中当前的Settings中应该是没有这个界面,真是有些不能理解;

跟着MANAGE_APP_ALL_FILES_ACCESS_PERMISSION这个关键字,一路查找

正常的Settings应用中

MANAGE_ALL_FILES_ACCESS_PERMISSION和MANAGE_APP_ALL_FILES_ACCESS_PERMISSION 都是有对应界面的,具体如下:

<!--MANAGE_APP_ALL_FILES_ACCESS_PERMISSION --><activityandroid:name="Settings$AppManageExternalStorageActivity"android:exported="true"android:label="@string/manage_external_storage_title"><intent-filter android:priority="1"><action android:name="android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION" /><category android:name="android.intent.category.DEFAULT" /><data android:scheme="package" /></intent-filter><meta-data android:name="com.android.settings.FRAGMENT_CLASS"android:value="com.android.settings.applications.appinfo.ManageExternalStorageDetails" /><meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"android:value="@string/menu_key_apps"/></activity><!--MANAGE_ALL_FILES_ACCESS_PERMISSION--><activityandroid:name="Settings$ManageExternalStorageActivity"android:knownActivityEmbeddingCerts="@array/config_known_host_certs"android:exported="true"android:label="@string/manage_external_storage_title"><intent-filter android:priority="1"><action android:name="android.settings.MANAGE_ALL_FILES_ACCESS_PERMISSION" /><category android:name="android.intent.category.DEFAULT" /></intent-filter><meta-data android:name="com.android.settings.FRAGMENT_CLASS"android:value="com.android.settings.applications.manageapplications.ManageApplications" /><meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"android:value="@string/menu_key_storage"/><meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"android:value="true" /></activity>

而高通8775设备中的Settings是CarSetings不是Google原生的Setting, 到CarSettings代码中,查看,果然是没有这个界面的配置;至此原因找到,剩下的是应对处理,车机软件还是要在车机上调试,呵呵呵

关键字:Android R及以上版本中APP外部存储实现

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: