android存储方式选择,Android 存储用例和最佳做法

为了让用户更好地控制自己的文件并减少混乱,Android 10 针对应用推出了一种新的存储范例,称为分区存储。分区存储改变了应用在设备的外部存储设备中存储和访问文件的方式。为了帮助您迁移应用以支持分区存储,请遵循本指南中有关常见存储用例的最佳做法。这些用例分为两类:处理媒体文件和处理非媒体文件。

如需详细了解如何在 Android 平台中存储和访问文件,请参阅存储培训指南。

处理媒体文件

本部分介绍了处理媒体文件(视频、图片和音频文件)的一些常见用例,并概要说明了应用可以使用的方法。下表对其中每个用例进行了总结,并列出了包含更多详细介绍的各个部分的链接。

用例

摘要

在所有 Android 版本中均使用相同的方法。

在所有 Android 版本中均使用相同的方法。

如果应用使用分区存储,请使用一种方法。如果应用停用分区存储,请使用不同方法。

在 Android 11 中,请使用一种方法。在 Android 10 中,请停用分区存储并改用适用于 Android 9 及更低版本的方法。

在所有 Android 版本中均使用相同的方法。

在所有 Android 版本中均使用相同的方法。

在所有 Android 版本中均使用相同的方法。

在所有 Android 版本中均使用相同的方法。

在 Android 11 中,请使用一种方法。在 Android 10 中,请停用分区存储并改用适用于 Android 9 及更低版本的方法。

显示多个文件夹中的图片或视频文件

使用 query() API 查询媒体集合。如需对媒体文件进行过滤或排序,请调整 projection、selection、selectionArgs 和 sortOrder 参数。

显示特定文件夹中的图片或视频

请使用以下方法:

根据 MediaColumns.DATA 的值检索媒体文件,该值包含磁盘上的媒体项的绝对文件系统路径。

访问照片中的位置信息

如果应用使用分区存储,请按照媒体存储指南的照片中的位置信息部分的步骤操作。

注意:即使停用分区存储,您也需要 ACCESS_MEDIA_LOCATION 权限才能读取使用 MediaStore API 访问的图片中的未编辑位置信息。

在一次操作中修改或删除多个媒体文件

根据应用在哪个 Android 版本上运行来纳入逻辑。

在 Android 11 上运行

请使用以下方法:

评估用户的响应:

如果授予了权限,请继续修改或删除操作。

如果未授予权限,请向用户说明您的应用中的功能为何需要该权限。

详细了解如何使用 Android 11 中提供的这些方法执行批量操作。

在 Android 10 上运行

如果您的应用以 Android 10(API 级别 29)为目标平台,请停用分区存储,继续使用适用于 Android 9 及更低版本的方法来执行此操作。

在 Android 9 或更低版本上运行

请使用以下方法:

导入已经存在的单张图片

当您要导入已经存在的单张图片(例如,用作用户个人资料的照片)时,应用可以将自己的界面用于此操作,也可以使用系统选择器。

提供您自己的界面

请使用以下方法:

使用系统选择器

使用 ACTION_GET_CONTENT intent,它会要求用户选择要导入的图片。

如果您想过滤系统选择器提供给用户选择的图片类型,您可以使用 setType() 或 EXTRA_MIME_TYPES。

拍摄单张图片

当您想拍摄单张图片在应用中使用(例如,用作用户个人资料的照片)时,请使用 ACTION_IMAGE_CAPTURE intent 要求用户使用设备的摄像头拍照。系统会将拍摄的照片存储在 MediaStore.Images 表中。

与其他应用共享媒体文件

使用 insert() 方法将记录直接添加到 MediaStore 中。如需了解详情,请参阅媒体存储指南的添加项目部分。

与特定应用共享媒体文件

按照设置文件共享指南中所述,使用 Android FileProvider 组件。

从代码或依赖库中使用直接文件路径访问文件

根据应用在哪个 Android 版本上运行来纳入逻辑。

在 Android 11 上运行

请使用以下方法:

使用直接文件路径访问文件。

如需了解详情,请参阅使用原始路径访问文件。

在 Android 10 上运行

如果您的应用以 Android 10(API 级别 29)为目标平台,请停用分区存储,继续使用适用于 Android 9 及更低版本的方法来执行此操作。

在 Android 9 或更低版本上运行

请使用以下方法:

使用直接文件路径访问文件。

处理非媒体文件

本部分介绍了处理非媒体文件的一些常见用例,并概要说明了应用可以使用的方法。下表对其中每个用例进行了总结,并列出了包含更多详细介绍的各个部分的链接。

用例

摘要

在所有 Android 版本中均使用相同的方法。

请尽可能将文件迁移到分区存储。在 Android 10 中,请根据需要停用分区存储。

在所有 Android 版本中均使用相同的方法。

在所有 Android 版本中均使用相同的方法。

打开文档文件

使用 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/ 下的当前位置移至 Downloads/ 目录的应用专用子目录。

从 /sdcard/ 目录中移除应用的旧存储目录。

与其他应用共享内容

如需与一个其他应用共享应用的文件,请使用 FileProvider。对于全部需要在彼此之间共享文件的应用,我们建议您对每个应用使用内容提供程序,然后在将应用添加到集合中时同步数据。

缓存非媒体文件

您应该使用的方法取决于您需要缓存的文件类型。

暂时停用分区存储

在您的应用与分区存储完全兼容之前,您可以使用以下方法之一暂时停用分区存储:

以 Android 9(API 级别 28)或更低版本为目标平台。

如果您以 Android 10(API 级别 29)或更高版本为目标平台,请在应用的清单文件中将 requestLegacyExternalStorage 的值设置为 true:

...

注意:当您将应用更新为以 Android 11(API 级别 30)为目标平台后,如果应用在搭载 Android 11 的设备上运行,系统会忽略 requestLegacyExternalStorage 属性,因此您的应用必须做好支持分区存储并为这些设备上的用户迁移应用数据的准备。

如需测试以 Android 9 或更低版本为目标平台的应用在使用分区存储时的行为,您可以通过将 requestLegacyExternalStorage 的值设置为 false,选择启用该行为。如果在搭载 Android 11 的设备上进行测试,您还可以使用应用兼容性标记来测试应用在使用和不使用分区存储时的行为。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值