如何在 Android 11 中实现 New Storage API?

Posted

技术标签:

【中文标题】如何在 Android 11 中实现 New Storage API?【英文标题】:How to implement New Storage API in Android 11? 【发布时间】:2021-08-11 04:41:42 【问题描述】:

场景

我有两个应用程序,一个是Tracker App,它记录来电和去电并压缩这些文件,并将文件路径通过Inter-Process Communication发送到主应用程序,然后将这些文件上传到服务器。

现在我将这两个应用程序升级到 android 11。在 Tracker 应用程序中,我使用 MediaStore.Files API 保存文件并尝试使用主应用程序中的文件路径读取这些文件。在主应用程序中读取文件File.canRead() 时返回false。即使我尝试MediaStore API 来读取这些文件,它也会返回空的Cursor

这里我有几个问题。

    我可以在 Android 11 上读取由其他应用程序创建的文件吗?我在某处看到您无法在 Android 11 中访问其他应用文件。 我的应用是否有资格获得MANAGE_EXTERNAL_STORAGE 访问存储中所有文件的权限? 处理这种情况的最佳方法是什么? ``` 存储访问框架 `` 能否帮助我处理这种情况?

我将文件保存在公共目录Documents/AppData/Audio 中。请给我有关此的工作链接。任何帮助将不胜感激。谢谢

【问题讨论】:

在这里阅读我的问题和答案 - ***.com/q/60360368/5550161 @HB 我已经尝试过了,但它对我没有帮助。我可以访问 Documents 文件夹中其他应用创建的文件吗? , I'm using MediaStore.Files API to save files and trying to read these files using the file path 错误。你也应该使用 MediaStore api。 Is my app eligible for MANAGE_EXTERNAL_STORAGE permission to access all files in storage? 你应该问谷歌。 @blackapps 我也试图通过 MediaStore 在选定的文件夹中访问它在主应用程序中返回空光标。但是当我尝试在 Tracker App 中访问时,光标不为空。 【参考方案1】:

我有两个app,一个是Tracker App,它记录呼入和呼出并压缩这些文件,并通过进程间通信将文件路径发送到主App,主App将这些文件上传到服务器。

这似乎过于复杂。

我可以在 Android 11 上读取由 Others 应用创建的文件吗?

从技术上讲,您不是在编写文件。您正在MediaStore.Files 中创建一个条目。其他应用无法读取您在MediaStore.Files 中创建的条目。

我的应用是否有资格获得访问存储中所有文件的 MANAGE_EXTERNAL_STORAGE 权限?

我们不是谷歌。我们没有办法回答这个问题。不过,如果他们认为您的应用符合此条件,我会感到非常惊讶。

处理这种情况的最佳方法是什么?

好吧,恕我直言,目前最好的方法是拥有一个应用程序,而不是两个。但我假设你目前无法改变这一点。

如果是,那么:

让“跟踪器”应用将内容写入应用可以写入的文件系统目录中的文件。大多数情况下,这将通过Context 上的方法实现,例如getFilesDir()getExternalCacheDir()

让“跟踪器”应用使用FileProvider 提供该目录中的文件,并使用FileProvider.getUriForFile() 获取指向该文件的Uri

让“跟踪器”应用通过一些基于Intent 的机制(startActivity()startService()sendBroadcast() 等)调用您的“主”应用。将上一个项目符号中的Uri 放入该Intent,并将FLAG_GRANT_READ_URI_PERMISSION 添加到该Intent

让“主”应用使用ContentResolveropenInputStream() 读取内容,传入从Intent 的副本中提取的Uri

``` 存储访问框架 `` 能帮我处理这种情况吗?

您可以让用户在每个应用程序中使用存储访问框架。例如,您可以在每个应用程序中使用ACTION_OPEN_DOCUMENT_TREE,希望用户在每个应用程序中选择相同的树。就个人而言,我会使用FileProvider,因为它不需要用户交互,也不需要用户做出好的选择。

【讨论】:

感谢您的回答。正如你所建议的,我现在正在实施 SAF 框架。稍后我会将上传任务转移到“Tracker App”中。【参考方案2】:

与 Android 11 MediaStore API 一样,仅返回媒体文件。

所以,我会回答你的相关问题。

我可以在 Android 11 上读取由“其他”应用创建的文件吗?一世 在 Android 11 中您无法访问其他应用程序文件的地方阅读。

不!您无法访问由其他应用程序创建的、存储在该特定应用程序的个人存储中的文件。

我的应用是否有资格获得 MANAGE_EXTERNAL_STORAGE 访问权限 存储中的所有文件?

据我了解,您的应用不需要外部存储来存储数据,也可以在可以读取或写入数据的私有存储中完成。如果您的应用程序仍然有资格获得此权限,那么您现在仍然无法使用它。官方网站建议这样做,而不是要求此权限使目标 API 29 并在清单中使用 android:requestLegacyExternalStorage="true" 。 click here to read about it.

处理这种情况的最佳方法是什么?

您可以使用特定于应用程序的文件夹来存储您正在创建的存档,而不是使用外部音频路径。

``` 存储访问框架 `` 能帮我处理这种情况吗?

我不太了解 IPC 如何在两个应用程序之间工作,所以我无法确切地说使用存储框架会更好。

【讨论】:

only returns media files.。没有人可以将所有类型的文件都放在媒体存储中。 之前我们可以得到this中使用的非媒体文件,如pdf、文本等。 之前?现在还是。你想说什么? 对不起,如果我的回答是错误的。但我正在使用一个名为 FilePicker link 的库。在这个库中,它使用 MediaStore api 来获取非媒体文件。但升级到 API 30 后,它没有显示任何非媒体文件。 我有两个应用程序,一个将音频文件保存在 zip 文件中的跟踪器,另一个是读取这些文件的主应用程序。所以我不能使用私有存储来存储。【参考方案3】:

接收应用可以使用 SAF 让用户选择您的目录。

或者更标准:您拥有文件,因此您可以构建自己的文件/内容提供程序来为您的文件提供服务。

如果您使用进程间通信(顺便说一下),您可以使用 mediastore 和 FileProvider 中的 uri 一个一个地提供文件。

【讨论】:

您能否分享工作链接以构建自己的文件/内容提供程序。? 不,我不能。然后我必须谷歌,所以我让你这样做。

以上是关于如何在 Android 11 中实现 New Storage API?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android 11中实现存储权限。有人可以分享一个用java实现的例子

如何在Android View中实现这种布局配置

如何在 React Native 中实现 Twilio android 推送通知?

Android程序中实现中英文切换

如何在基于 SQLite 的 recyclerview 中实现 searchview? - 安卓

如何在android中实现自定义可折叠工具栏?