查看原文
其他

Android 11 开发者常见问题: 存储 | FAQ・第二期

Android 谷歌开发者 2020-09-20
我们在 Android 10 中首次引入了 "分区存储" 的概念,旨在保护应用和用户数据并减少文件混乱。自此之后我们收到了开发者们的宝贵建议,这些建议有助于我们对该功能的持续优化,非常感谢大家!基于反馈,我们在 Android 11 上做了一些值得注意的改进。例如,我们启用了对媒体文件的直接文件路径访问功能,用于改善现有代码和程序库的兼容性。我们理解许多应用在采取分区存储方案前需要有周密的方案,以便持续支撑现有用户的访问,确保符合当前存储方案的最佳实践以及向后兼容性。

基于与开发者们的探讨和在开发者论坛上的活跃讨论,我们准备了这份有关存储的常见问题和解答,以帮助您更好地了解分区存储的各种能力、行为变化和一些限制等。我们在过去的文章推送里发布过关于 Android 存储方案的最佳实践,您可以先回顾一下最佳实践的上篇下篇


注: 由于部分问题答案较长,可上下滑动以查看完整内容

  • 分区存储
    https://developer.android.google.cn/training/data-storage#scoped-storage
  • 直接文件路径访问
    https://developer.android.google.cn/preview/privacy/storage#media-direct-file-native


分区存储允许应用通过 File API 使用文件路径访问文件吗?

我们意识到某些应用会通过代码或程序库直接访问媒体文件路径。因此,在 Android 11 上,拥有可读取外部存储权限的应用,均可在分区存储环境中通过文件路径访问文件。在 Android 10 的设备上,除非在 manifest 中通过主动声明 requestLegacyExternalStorage 属性来选择停用分区存储,否则上述方法是无效的。
为了确保不同 Android 版本间的连续性,如果您应用的目标版本是 Android 10 或者是更高版本,您应该选择不启用。更多详细信息,请参阅文末相关阅读 Android 存储方案的最佳实践上下篇。

与媒体存储 API 相比,文件路径访问的性能表现如何?

 

性能表现非常依赖具体应用场景。对于像视频播放这样的拥有顺序读取的操作,文件路径访问的性能表现与媒体存储相差无几。但是在随机读写的情境下,采取文件路径的方法最多可慢一倍。为了最快、最稳定的读写,我们推荐您使用 Media Store API。

我的应用需要广泛地访问共享存储,存储访问框架是我唯一的选择吗?
 
存储访问框架 (简称 "SAF") 用于用户授予对目录和文件的访问权限,但是需要您注意的是,SAF 对某些目录的授权仍存在限制,例如根目录和 Android/data 目录。虽说大多数应用在存储访问时都可以通过我们最佳实践的方式去实现,例如使用 SAF 或媒体存储 API,但在某些应用场景下可能会需要更广泛地访问共享存储,亦或是无法通过最佳实践来有效地访问。针对上述情况,我们增加了 MANAGE_EXTERNAL_STORAGE 权限,允许程序访问外部存储上的所有文件 (除了 Android/data 和 Android/obb 目录)。我们在 7 月发布了一个 Google Play 政策更新,提到了关于存储的相关内容,请点击这篇微信文章查看。
  • MANAGE_EXTERNAL_STORAGE

    https://developer.android.google.cn/preview/privacy/storage#all-files-access


哪些类别的应用应该申请 MANAGE_EXTERNAL_STORAGE 权限?
 
MANAGE_EXTERNAL_STORAGE 权限适用于核心应用场景需要广泛地访问设备上的文件的情况,但使用分区存储的最佳实践无法高效地实现此功能的那些应用。当然,列出所有可能的应用场景是不切实际的,但其包括了文件管理器、备份和还原、反病毒程序或生产力文件编辑器等使用场景。

使用 Storage Access Framework (存储访问框架),是否需要 Google Play 的政策批准?

 

Storage Access Framework (存储访问框架,简称 SAF) 从 Android 4.4 开始就已经存在。通过 SAF 访问文件时,会让用户参与文件选择,从而使用户可以更好地控制文件的访问。Google Play 上没有与之相关的政策。

与 Android 10 相比,在 Android 11 上使用 SAF 会有其他限制吗?

 

目标版本为 Android 11 (API 级别为 30) 并使用 SAF 的应用,将不会被授予某些目录访问权限,例如 SD 卡上的根目录和下载目录。无论是哪个目标 SDK,都无法在 Android 11 上通过存储访问框架访问 Android/data 和 Android/obb 目录。访问官方文档了解关于这些限制和测试相关行为的方法。


  • 官方文档

    https://developer.android.google.cn/preview/privacy/storage#file-directory-restrictions


应用该如何测试分区存储的变化?

通过这些兼容性标志,应用可以测试与直接文件路径访问或媒体存储 API 相关的分区存储行为。还有另一个兼容性标志,也可用来测试使用存储访问框架访问某些路径时的限制。
  • 兼容性标志

    https://developer.android.google.cn/preview/privacy/storage#test-scoped-storage

  • 另一个兼容性标志

    https://developer.android.google.cn/preview/privacy/storage#test-file-directory-access


分区存储中的应用,是否仅限于将文件写入其应用 data 目录上?

在分区存储中,应用可以将媒体项添加到媒体存储集合。媒体存储会根据文件类型,将文件放置于组织有序的文件夹中,例如 DCIM、Movies 和 Download 等。对于所有此类文件,应用可以继续通过文件 API 来访问。得益于系统为每个媒体存储文件赋予了应用属性,应用不需要有存储权限也可以读写到它们最初提供给媒体存储的文件。


  • 媒体项添加

    https://developer.android.google.cn/training/data-storage/shared/media#add-item


Data Column 弃用之后,有没有对此功能的其他使用建议?

在 Android 10 上,位于分区存储环境中的应用无法通过文件路径访问文件。为了与这一设计保持一致,我们随后废弃了 DATA column。根据大家的反馈,即需要使用已有的 native 代码或程序库,Android 11 现已支持在分区存储中的应用访问文件路径的功能。相应地,DATA Column 实际上在某些情况下其实是有用的。为了在媒体存储中插入和更新,使用分区存储的应用应使用 DISPLAY_NAME 和 RELATIVE_PATH Column,它们不再需要使用 DATA Column 来完成此功能。当读取磁盘中文件的媒体存储实例时,DATA Column 将具备有效的文件路径,该路径可被文件 API 或 NDK 文件程序库使用。但应用要准备处理任何关于此类操作带来的 I/O 错误,而且不应该假设文件始终是可用的。
  • DATA Column
    https://developer.android.google.cn/reference/android/provider/MediaStore.MediaColumns#DATA

对于选择退出分区存储的应用,它们何时开始必须兼容分区存储?

在运行 Android 11 或更高版本的设备上。当目标版本被设置为 Android 11 或更高版本时,应用便会被放入到分区存储中。

建议使用什么方法来迁移分区存储之外的数据?

preserveLegacyExternalStorage 标记允许应用在升级系统时保留原有存储权限,即使是升级至 Android 11。需要注意的是,在 Android 11 上这个标记对新安装的应用起不到任何作用。将目标版本设为 Android 11 之前,请修改代码以适配分区存储。请参阅文末相关阅读 Android 存储方案的最佳实践上下篇,来获取数据迁移最佳实践的相关信息吧。

针对某些软件包安装程序 (例如应用商店) 需要访问 Android/obb 目录,是否有任何例外情况?

持有 REQUEST_INSTALL_PACKAGES 权限的应用可以访问其他应用的 Android/obb 目录。请注意,此权限享有签名级别的保护。
  • REQUEST_INSTALL_PACKAGES

    https://developer.android.google.cn/reference/android/Manifest.permission#REQUEST_INSTALL_PACKAGES


我们希望您计划适配分区存储时这份 FAQ 能为您提供一些帮助。请点击阅读原文或查看文末相关阅读文章,了解我们的最佳实践文档。


推荐阅读






 点击屏末 | 阅读原文 | 进一步了解 Android 存储用例和最佳做法



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存