要在 Google Play 上公布,开发者须要将利用的 指标 API 级别 (targetSdkVersion) 更新到 API 级别 30 (Android 11) 或者更高版本。针对新上架的利用,这个政策自 8 月开始失效;现有利用更新新的版本,这个政策的要求将自 11 月开始失效。
API 30 所带来的一个微小变更是,利用须要应用分区存储 (Scoped Storage)。
变更之大,对于大型利用来说堪称恐怖。更蹩脚的是,咱们在网上看到的无关如何适配分区存储的倡议,有一些倡议非常令人蛊惑,甚至会误导咱们。
为了帮您排忧解难,咱们收集了一些无关分区存储的常见问题,同时也为如何适配您的利用提供了一些倡议和可能的代替计划。
Q: android:requestLegacyStorage 会被移除吗?
A: 局部移除。
如果您的利用以后曾经设置了 android:requestLegacyStorage=”true”,就应该在 targetSdkVersion
设置为 30 后放弃现状。该标记在 Android 11 设施中没有任何成果,然而能够持续让利用在 Android 10 设施上以旧的形式拜访存储。
如果您须要针对 Android 10 设施在 AndroidManifest.xml 中设置 android:requestLegacyStorage="true"
,那在利用的指标版本改为 Android 11 后该当保留此设置。它仍会在 Android 10 设施上失效。
Q: android:preserveLegacyStorage 是如何工作的?
A: 如果您的利用装置在 Android 10 设施上,并设置了 android:requestLegacyStorage="true"
,那在设施降级至 Android 11 后,此设置会持续放弃旧的存储拜访形式。
⚠️ 如果利用被卸载,或者是第一次在 Android 11 上装置,那么就无奈应用旧的存储拜访形式。此标记仅实用于进一步帮忙设施从传统存储降级到分区存储。
Q: 如果我的利用没有拜访照片、视频或音频文件,是否依然须要申请 READ_EXTERNAL_STORAGE 权限?
A: 不须要,从 Android 11 开始,仅在拜访其余利用所属的媒体文件时才须要申请 READ_EXTERNAL_STORAGE
权限。如果您的利用仅应用本身创立的非媒体文件 (或本身创立的媒体文件),那么就不再须要申请该权限。
如需在 Android 11 后进行申请该权限,仅需批改利用 AndroidManifest.xml 文件中的 <uses-permission>
标签,增加 android:maxSdkVersion=”29″ 即可:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
Q: 我想要拜访不属于我利用的照片、视频或一段音频,我必须应用系统文件选择器吗?
A: 不。但如果您想用就能够用,ACTION_OPEN_DOCUMENT
最早可反对至 Android KitKat (API 19),而 ACTION_GET_CONTENT
则反对至 API 1,二者应用的都是系统文件选择器。因为不须要任何权限,这依然是首选的解决方案。
如果您不想应用系统文件选择器,您依然能够申请 READ_EXTERNAL_STORAGE
权限,它会使您的利用能够拜访所有的照片、视频以及音频文件, 同时也蕴含拜访 File API 的权限!
如果您须要应用 File API 拜访媒体内容,记得设置 android:requestLegacyStorage="true"
,否则 File API 在 Android 10 中将无奈工作。
Q: 我想保留非媒体文件,但我不想在卸载我的利用时删除它们。我须要应用 SAF 吗?
A: 兴许须要。
如果这些文件容许在利用外关上而无需通过您的利用,那么系统文件选择器是较好的抉择。您能够应用 ACTION_CREATE_DOCUMENT
创立文件。当然也能够应用 ACTION_OPEN_DOCUMENT
来关上一个现有文件。
如果利用已经创立了一个目录用于存储所有这些文件,那最好的抉择就是应用系统文件选择器和 ACTION_OPEN_DOCUMENT_TREE
,以便用户能够抉择要应用的特定文件夹。
如果这些文件只对您的利用有意义,能够思考在利用 AndroidManifest.xml 文件的 <application>
标签中设置 android:hasFragileUserData="true"
。这将使用户能够保留这些数据,即便在卸载利用时亦是如此。
△ 上图为领有 “ 软弱用户数据 ” 利用的卸载对话框。对话框中蕴含了一个复选框,用于批示零碎是否应该保留利用数据。
设置了该标记后,存储文件的最佳地位将取决于其内容。蕴含敏感或私人信息的文件该当存储在 Context#getFilesDir()
所返回的目录中;而不敏感的数据则应存储于 Context#getExternalFilesDir()
所返回的目录中。
Q: 我能够将非媒体文件搁置于其余文件夹中 (例如 Downloads 文件夹),而无需任何权限。这是一个 Bug 吗?
A: 不是。利用可能会向这类汇合提供文件,而且最好的形式是对非媒体文件同时应用 Downloads 和 Documents 汇合。不过请记得,默认状况下只有创立该文件的利用才能够拜访它们。其余利用须要通过系统文件选择器取得拜访权限或者领有对外部存储的宽泛拜访权限 (即: MANAGE_EXTERNAL_STORAGE
权限 ) 才行。
⚠️ 对 MANAGE_EXTERNAL_STORAGE
权限的拜访受到 Play 政策 监管。
Q: 如果我须要保留一个文档,是否须要应用 SAF?
A: 不必。利用能够向 Documents 与 Downloads 汇合提供非媒体文件,而无需任何非凡权限。只有没被卸载,那么向这些汇合提供文档的利用领有这些文档的齐全拜访权限。
💡 如果您的利用为了下面提到的形式保存文档而申请 READ_EXTERNAL_STORAGE
权限的话,在 Android 11 及更高版本中将不用再申请该权限。您能够参考上面的示例批改对该权限的申请 (设定 maxSdkVersion 为 API 版本 29):
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
如要拜访其余利用增加的文档,或者在您的利用卸载重装后拜访其卸载前增加的文档,就须要通过 ACTION_OPEN_DOCUMENT
Intent 来应用系统文件选择器。
Q: 我想要与其余利用共享文件,是否须要应用 SAF?
A: 不须要。如下是一些与其余利用共享文件的形式:
- 间接分享: 应用
Intent.ACTION_SEND
能够让您的用户通过各种格局与设施上的其余利用共享数据。如果您应用这种形式,应用 AndroidX 的 FileProvider 来将 file:// Uri 主动转换为 content:// Uri 可能会对您有所帮忙。 - 创立您本人的 DocumentProvider: 这能够让您的利用持续解决利用的公有目录 (Context#getFilesDirs() 或 Context#getExternalFilesDirs()) 中内容的同时,仍能够向应用系统文件选择器的其余利用提供拜访权限。(请留神,能够在卸载利用后持续保留这些文件——参阅上文中的 android:hasFragileUserData=”true” 设置来理解其应用形式。)
最初的思考
Scoped Storage 是一项旨在改善用户隐衷爱护的重大变更。不过依然有很多办法能够解决不依赖应用存储拜访框架 (Storage Access Framework) 的内容。
如果要存储的数据仅实用于您的利用,那么咱们强烈建议应用 利用特定目录。
如果数据是媒体文件,例如照片、视频或者音频,那么能够 应用 MediaStore。留神,从 Android 10 开始,提供内容 不再须要申请权限。
也别忘了能够通过 ACTION_SEND 来与 其余利用共享数据 (或容许它们 与您的利用共享数据)!