Android 存储空间的最佳实践 (下)
分区存储
https://developer.android.google.cn/training/data-storage#scoped-storage
打开文档文件
ACTION_OPEN_DOCUMENT https://developer.android.google.cn/reference/android/content/Intent#ACTION_OPEN_DOCUMENT setType() https://developer.android.google.cn/reference/android/content/Intent#setType(java.lang.String) EXTRA_MIME_TYPES https://developer.android.google.cn/reference/android/content/Intent#EXTRA_MIME_TYPES
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
)
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);
从旧的存储位置迁移现有文件
保留对旧版存储位置的访问以进行数据迁移
如果您的应用目标平台为 Android 11
使用 preserveLegacyExternalStorage 标志来保留旧版存储模型,这样您的应用就可以在用户将应用升级为目标平台为 Android 11 的新版本时迁移用户数据。
注意: 如果您使用 preserveLegacyExternalStorage,保持旧存储模型的效果只会在用户卸载应用之前有效。如果用户在运行 Android 11 的设备上安装或重装您的应用,则无论 preserveLegacyExternalStorage 的值是什么,您的应用都无法停用分区存储模型。 继续停用分区存储,以便您的应用可以继续访问运行 Android 10 的设备上旧版存储位置中的文件。
保留旧版存储模型 https://developer.android.google.cn/preview/privacy/storage#migrate-data-for-scoped-storage 停用分区存储 https://developer.android.google.cn/training/data-storage/use-cases#opt-out-scoped-storage
如果您的应用目标平台为 Android 10
迁移应用数据
当您的应用已经做好迁移的准备时,使用以下方法:
检查您应用在工作中是否使用了位于 /sdcard/ 目录或其任何子目录中的文件; 将应用的所有私有文件从现在的 /sdcard/ 下的目录中移动至 getExternalFilesDir() 方法所返回的目录中; 将所有共享的非媒体文件从现在的 /sdcard/ 下的目录中移动至 Downloads/ 目录下的一个应用专用子目录; 从 /sdcard/ 目录移除应用程序的旧存储目录。
getExternalFilesDir() https://developer.android.google.cn/reference/android/content/Context#getExternalFilesDir(java.lang.String)
与其他应用共享内容
使用 FileProvider https://developer.android.google.cn/training/secure-file-sharing 内容提供程序 https://developer.android.google.cn/guide/topics/providers/content-provider-basics
缓存非媒体文件
您应使用的方法取决于需要缓存的文件类型。
小型文件或者包含敏感信息的文件: 使用 Context#getCacheDir()
https://developer.android.google.cn/reference/android/content/Context#getCacheDir() 大型文件或者不包含敏感信息的文件: 使用 Context#getExternalCacheDir()
https://developer.android.google.cn/reference/android/content/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 属性。所以您的应用必须为支持分区存储做好准备,并为使用该设备的用户迁移数据。
系统会忽略 requestLegacyExternalStorage 属性 https://developer.android.google.cn/preview/privacy/storage#scoped-storage 迁移数据 https://developer.android.google.cn/training/data-storage/use-cases#migrate-legacy-storage
应用兼容性标志 https://developer.android.google.cn/preview/privacy/storage#test-scoped-storage
数据和文件存储概览 https://developer.android.google.cn/training/data-storage
Android 存储用例和最佳做法 - Android 官方中文文档 https://developer.android.google.cn/training/data-storage/use-cases?hl=zh-CN
推荐阅读