为了进步文件的规整水平并让用户能够更好地管制他们的文件,Android 10 为利用引入了名为 “[分区存储](https://developer.android.goo…
)” 的新范式。分区存储扭转了利用在外置存储中保留和拜访文件的形式,为了帮您迁徙利用并反对分区存储,咱们概括了常见用例的最佳实际并分享给大家。
解决媒体文件
这部分内容形容了解决媒体文件 (如视频、图片、音频文件) 的一些常见用例,并概要阐明了利用能够应用的办法。咱们制作了一个简略的图片,列出了每种用例以及其在不同零碎版本的实际总结:
展现多个文件夹中的图片和视频文件
应用 query()) API 查问媒体汇合。您能够通过调整 projection
、selection
、selectionArgs
与 sortOrder
参数来对媒体文件进行过滤和排序。
展现特定文件夹内的文件和视频
应用以下办法:
- 应用 “ 申请利用权限 ” 一文中形容的最佳实际来申请
READ_EXTERNAL_STORAGE
权限。 - 应用 MediaColumns.DATA 中的值来检索媒体文件,其中蕴含了磁盘中媒体文件的相对文件系统门路。
拜访照片内的地位信息
如果您的利用应用了分区存储,能够遵循媒体存储指南中的 “ 照片中的地位信息 ” 局部进行操作。
留神: 就算您抉择停用分区存储,在应用 MediaStore API 拜访图像并读取未修改的地位信息时,您也须要申请 ACCESS_MEDIA_LOCATION 权限。
在单个操作中批改或删除多个媒体文件
您须要依据运行利用的 Android 版本来整合逻辑。
在 Android 11 上运行
应用以下办法:
- 应用 MediaStore.createWriteRequest()) 或 MediaStore.createTrashRequest()) 为利用的写入或删除申请创立待定 intent,而后通过调用该 intent 提醒用户授予批改一组文件的权限。
- 评估用户的响应:
- 如果取得了权限,执行批改或删除操作;
- 如果未能取得权限,向用户解释为什么您的利用须要此权限。
具体理解如何应用 Android 11 引入的这些办法执行批量操作。
在 Android 10 上运行
如果您的利用指标 API 为 Android 10 (API level 29),[请停用分区存储](https://developer.android.goo…
)并持续应用 Android 9 及更低版本所应用的办法来执行这类操作。
在 Android 9 及更低版本上运行
应用以下办法:
- 应用 “ 申请利用权限 ” 一文中形容的最佳实际来申请 WRITE_EXTERNAL_STORAGE 权限。
- 应用 MediaStore API 来批改和删除媒体文件。
导入已存在的单个图片
如果您想要导入一张已存在的图片 (例如将照片用于用户个人资料),您的利用能够应用本人的 UI 或者零碎图片选择器来执行这一操作。
提供您本人的用户界面
应用以下办法:
- 应用 “ 申请利用权限 ” 一文中形容的最佳实际来申请
READ_EXTERNAL_STORAGE
权限。 - 应用 query()) API 查问媒体汇合。
- 将结果显示到您的 UI 上。
应用零碎选择器
应用 ACTION_GET_CONTENT intent 来要求用户抉择要导入的图片。如果您心愿过滤零碎选择器向用户展现的图片类型,能够应用 setType()) 或 EXTRA_MIME_TYPES。
拍摄单张图片
当您想要拍摄一张图片并用于您的利用时 (例如将照片用于用户个人资料),应用 ACTION_IMAGE_CAPTURE intent 来要求用户应用设施的相机拍摄一张照片。零碎会将拍摄的照片存储于 MediaStore.Images 表中。
与其余利用共享媒体文件
应用 insert()) 办法将记录间接退出 MediaStore。详细信息,能够参阅媒体存储指南中 “ 增加我的项目 ” 局部。
与特定利用共享媒体文件
应用 Android FileProvider 组件,相干内容在 “ 设置文件分享 ” 指南中有形容。
从代码或依赖库中应用间接文件门路拜访文件
您须要依据运行利用的 Android 版本来整合逻辑。
在 Android 11 上运行
应用以下办法:
- 应用 “ 申请利用权限 ” 一文中形容的最佳实际来申请 READ_EXTERNAL_STORAGE 权限。
- 应用间接文件门路拜访文件。
详细信息,请参阅 “ 应用原始门路拜访文件 ”。
在 Android 10 上运行
如果您的利用指标 API 为 Android 10 (API level 29),请停用分区存储并持续应用 Android 9 及更低版本所应用的办法来执行这类操作。
在 Android 9 及更低版本上运行
应用以下办法:
- 应用 “ 申请利用权限 ” 一文中形容的最佳实际来申请
WRITE_EXTERNAL_STORAGE
权限。 - 应用间接文件门路拜访文件。
打开文档文件
应用 ACTION_OPEN_DOCUMENT
intent 来要求用户通过零碎选择器抉择须要关上的文件。如果您想要过滤零碎选择器展现给用户的文件类型,能够应用 setType()
) 或 EXTRA_MIME_TYPES
。
举例来说,您能够通过以下代码找到所有的 PDF、ODT 和 TXT 文件:
Kotlin 代码
startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT).apply {addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*"
putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
"application/pdf", // .pdf
"application/vnd.oasis.opendocument.text", // .odt
"text/plain" // .txt
))
},
REQUEST_CODE
)
Java 代码
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
"application/pdf", // .pdf
"application/vnd.oasis.opendocument.text", // .odt
"text/plain" // .txt
});
startActivityForResult(intent, REQUEST_CODE);
从旧的存储地位迁徙现有文件
如果一个目录既不是特定利用的目录,也不是公开共享目录,那么它就会被视为旧版存储地位。如果您的利用创立或应用位于旧版存储地位的文件,咱们建议您将利用的文件迁徙至可被分区存储拜访的地位,同时对利用进行必要的批改,以应用分区存储中的文件。
保留对旧版存储地位的拜访以进行数据迁徙
您的利用须要保留对旧版存储地位的拜访,以便能够将任何文件迁徙至可被分区存储拜访的地位。您应该的应用的办法取决于您利用的指标 API 级别。
如果您的利用指标平台为 Android 11
- 应用
preserveLegacyExternalStorage
标记来 保留旧版存储模型,这样您的利用就能够在用户将利用降级为指标平台为 Android 11 的新版本时迁徙用户数据。
留神: 如果您应用 preserveLegacyExternalStorage,放弃旧存储模型的成果只会在用户卸载利用之前无效。如果用户在运行 Android 11 的设施上装置或重装您的利用,则无论 preserveLegacyExternalStorage 的值是什么,您的利用都无奈停用分区存储模型。
- 持续 停用分区存储,以便您的利用能够持续拜访运行 Android 10 的设施上旧版存储地位中的文件。
如果您的利用指标平台为 Android 10
停用分区存储,以便您能够更轻松地在多个 Android 版本间放弃利用行为不变。
迁徙利用数据
当您的利用曾经做好迁徙的筹备时,应用以下办法:
- 查看您利用在工作中是否应用了位于
/sdcard/
目录或其任何子目录中的文件; - 将利用的所有公有文件从当初的
/sdcard/
下的目录中挪动至getExternalFilesDir()
) 办法所返回的目录中; - 将所有共享的非媒体文件从当初的
/sdcard/
下的目录中挪动至/sdcard/
目录下的一个利用专用子目录; - 从
/sdcard/
目录移除应用程序的旧存储目录。
与其余利用共享内容
您能够应用 FileProvider 分享利用的文件给某个其余利用。而对于那些须要相互之间分享文件的所有利用,咱们举荐为每一个利用应用 内容提供程序,而后在将利用增加到汇合中时同步数据。
缓存非媒体文件
您应应用的办法取决于须要缓存的文件类型。
- 小型文件或者蕴含敏感信息的文件 : 应用 Context#getCacheDir())
- 大型文件或者不蕴含敏感信息的文件 : 应用 Context#getExternalCacheDir())
临时停用分区存储
在您的利用齐全兼容分区存储之前,您能够通过以下办法之一停用分区存储:
- 指标平台设置为 Android 9 (API level 28) 或更低。
- 如果您的指标平台为 Android 10 (API level 29) 或者更高版本,将您利用 manifest 中的 requestLegacyExternalStorage 属性设置为 “true”:
<manifest ... >
<!-- 该属性在指标 API 为 Android 10 或更高版本的利用中默认为 "false" -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
留神 : 在您将利用的指标 API 更新为 Android 11 (API level 30) 后,如果利用运行在 Android 11 的设施上, 零碎会疏忽 requestLegacyExternalStorage 属性。所以您的利用必须为反对分区存储做好筹备,并为应用该设施的用户 迁徙数据。
为了测试指标 API 为 Android 9 及更低版本的利用在应用分区存储时的行为,您能够通过设置 requestLegacyExternalStorage
的值设置为 false 来使利用抉择启用行为。如果要在 Android 11 设施上进行测试,则还能够应用 [利用兼容性标记](https://developer.android.goo…
) 在应用或不应用分区存储的状况下测试利用的行为。
理解无关 Android 平台文件存储与拜访的详细信息,请参阅以下资源:
- 数据和文件存储概览
如果您想理解更多最新对于应用存储空间的最佳实际,请查阅 Android 官网中文文档网站中 Android 存储用例和最佳做法 局部。