2024- zhanglulu
本文总阅读量次,本站总访问量次
分区存储
Android 在 Android 10 (API level 29) 开始引入了分区存储(Scoped Storage)机制。这种机制旨在提高用户文件的隐私性和安全性,限制应用对用户文件的访问权限。
分区存储介绍
在分区存储下,每个应用只能访问自己的应用专属目录(即应用的私有存储),对共享存储(如照片、音频、视频、下载文件)的访问需要特别授权。此外,分区存储将公共的共享存储分为多个类别,应用只能访问自己创建的文件和特定类型的媒体文件。
适配现有应用的方法
对于现有应用,要适配分区存储,可以按照以下步骤进行:
-
检查文件访问需求:
- 审查应用中所有对文件系统的访问,确定哪些是需要继续访问公共存储的,哪些是可以迁移到应用专属目录的。
-
申请适当的权限:
- 在
AndroidManifest.xml
中,申请所需的权限,如READ_EXTERNAL_STORAGE
和WRITE_EXTERNAL_STORAGE
。 - 如果需要访问特定类型的媒体文件(如图片、视频),可以使用
MediaStore
API。 - 对于Android 11及以上系统,考虑使用
MANAGE_EXTERNAL_STORAGE
权限,但需要注意这是一个敏感权限,通常只有在应用无法正常运行的情况下才申请。
- 在
-
迁移到分区存储 API:
- 使用
Context.getExternalFilesDir()
获取应用的专属目录。 - 使用
MediaStore
API 访问公共媒体文件。 - 使用
Storage Access Framework
(SAF) 提供给用户选择文件和目录的能力。
- 使用
-
测试和优化:
- 在不同的 Android 版本上测试应用,确保在启用分区存储后应用功能正常。
- 针对不同版本的 Android 系统,可以通过条件编译或运行时检查来处理不同的存储方式。
代码示例
以下是一些典型的代码示例,展示了如何访问不同的存储区域:
-
访问应用专属目录:
File appSpecificExternalDir = context.getExternalFilesDir(null);
-
使用 MediaStore 访问公共媒体文件:
ContentResolver resolver = context.getContentResolver(); Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; Cursor cursor = resolver.query(uri, null, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { // 获取媒体文件的路径或其他信息 } cursor.close(); }
-
使用 Storage Access Framework 选择文件:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("*/*"); startActivityForResult(intent, REQUEST_CODE);
-
处理
onActivityResult
返回的文件:@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) { Uri uri = null; if (data != null) { uri = data.getData(); // 使用 ContentResolver 读取文件内容 } } }
通过以上步骤和代码示例,现有应用可以逐步适配 Android 10 及以上版本的分区存储机制。