在 Android 中从 File Api 迁移到 Storage Access Framework (SAF)
Posted
技术标签:
【中文标题】在 Android 中从 File Api 迁移到 Storage Access Framework (SAF)【英文标题】:Migration from File Api to Storage Access Framework (SAF) in Android 【发布时间】:2021-07-19 23:49:07 【问题描述】:由于 android 11 和范围存储,我必须开始使用存储访问框架 (SAF),但我有很多源代码可以使用 File API
。 问题 1:我是否必须重写所有内容才能使用 DocumentFile
?
伪用例:
用户创建并选择自己的目录,系统返回Uri
:
//Start pick a directory
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
startActivityForResult(intent, requestCode)
...
onActivityResult
//check requestCode + resultCode
...
//get Uri
val selectedDir = data.getData();
if (selectedDir == null)
return;
//take persist permission for later use
getContentResolver().takePersistableUriPermission(selectedDir, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
现在我有Uri
用户选择的具有读/写持久权限的文件夹。
来自Android doc
为帮助您的应用更顺畅地与第三方媒体库配合使用,Android 11 允许您使用除 MediaStore API 之外的 API 来使用直接文件路径从共享存储访问媒体文件。这些 API 包括以下内容: 文件 API。 原生库,例如 fopen()。
问题2:好吧,当我有来自ACTION_OPEN_DOCUMENT_TREE
的Uri
时,我该如何使用File API
?
问题 3:这是否意味着我必须复制所有代码才能使用 File API
复制到 Android 9(或使用 requestLegacyExternalStorage
的 10)以及使用 @ 复制到 Android 11+ 987654334@和Uri
?
目标是:保留File API
的代码,但获得用户选择目录的读/写权限。
更新
经过大量测试DocumentFile
在实践中不适用。可能只针对几个文件。DocumentFile
创建了不必要的复杂源代码,而且很慢related topic。
例如,在通过File API
~350ms 和通过DocumentFile
~2300ms 期间创建 1000 个目录。删除和检查文件是否存在总是很慢。
来自Scoped Storage Recap
太棒了!如果有某种支持库或 Androidx 库来处理文件,那就太好了。
Google 开发者的回答是:
我们正在探索这个选项作为一个实验,敬请期待????
【问题讨论】:
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
这对 ACTION_GET_DOCUMENT_TREE 毫无意义。最好删除。
I need: Create a file if it does not exist. With File API:
否。为此使用 SAF。有什么问题?
Write to file. With File API:
当然不是。如果您有文件的 uri,则打开该 uri 的输出流并写入该流。
Get Uri of parent with child. With File API:
一个人不会试图让父母一开始。
Goal is: keep the code with the File API,
目标错误。使用 SAF。
【参考方案1】:
请注意,startActivityForResult() 已被弃用。而是应使用 registerForActivityResult()。不幸的是,我还没有为这种机制找到任何可用的 Java 示例。甚至 Google 的示例代码仍在使用已弃用的功能。如果有任何提示,我会很高兴。
PS:还有一些 ActivityResultContracts.OpenDocumentTree() 函数可能会有所帮助,但我也找不到如何使用它的示例。
【讨论】:
以上是关于在 Android 中从 File Api 迁移到 Storage Access Framework (SAF)的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 3 中从 URLSession 迁移到 Alamofire 4.3,编码问题
Cordova [Android 平台] 从 API 29 迁移到 API 30