如何在Android 11中实现新存储API?

7

场景

我有两个应用程序,一个是跟踪器应用程序,记录进出电话并压缩这些文件,并通过进程间通信将文件路径发送给主应用程序,主应用程序将这些文件上传到服务器。

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

这里我有几个问题。

  1. 我能够在Android 11上读取由其他应用程序创建的文件吗?我在某个地方读到,您无法访问Android 11中其他应用程序的文件。
  2. 我的应用程序是否有资格获得MANAGE_EXTERNAL_STORAGE权限以访问存储中的所有文件?
  3. 处理此场景的最佳方法是什么?
  4. Storage Access Framework 可以帮助我处理这种情况吗?

我正在公共目录 Documents/AppData/Audio 中保存文件。请给我相关的可行链接。任何帮助都将不胜感激。谢谢


请在此处阅读我的问题和答案 - https://dev59.com/klIH5IYBdhLWcg3wQLfr - HB.
我正在使用MediaStore.Files API来保存文件,并尝试使用文件路径读取这些文件,但是这是错误的。你应该继续使用MediaStore api。 - blackapps
我的应用程序是否有资格获得MANAGE_EXTERNAL_STORAGE权限以访问存储中的所有文件?你应该问谷歌。 - blackapps
@blackapps 我也试图通过MediaStore在选定的文件夹中访问,但在主应用程序中返回空游标。但是当我尝试在Tracker应用程序中访问时,游标不为空。 - Jitendra Singh
在Tracker应用程序中,您应该查询媒体存储并使用文件提供程序将获取的URI转发到主应用程序。或者使用您自己的内容/文件提供程序。请参见答案。 - blackapps
显示剩余2条评论
3个回答

3

在Android 11中,MediaStore API只返回媒体文件。

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

我可以阅读由其他应用程序在Android 11上创建的文件吗?我在某个地方看到过,在Android 11中无法访问其他应用程序的文件。

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

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

据我理解,您的应用程序不需要外部存储来存储数据,也可以在私有存储中进行读取或写入。如果您的应用程序无论如何有资格获得此权限,现在仍然不能使用它。官方建议而不是请求此权限,请将目标API设置为29并在清单中使用android:requestLegacyExternalStorage ="true"。点击此处了解更多信息。

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

与其使用外部音频路径,不如使用您的应用程序特定文件夹来存储您正在创建的归档。

``` Storage Access Framework ```可以帮助我处理此场景吗?

我对两个应用程序之间的IPC如何工作没有太多了解,因此无法确切地告诉您使用Storage框架是否更好。


只返回媒体文件。任何人都不能将所有类型的文件放入媒体存储中。 - blackapps
1
我们可以更早地获取非媒体文件,例如PDF、文本等,就像在这里中使用的那样。 - Bhavin
之前?现在还是一样。你想说什么? - blackapps
抱歉如果我的回答有误。但我正在使用一个名为FilePicker的库链接。在这个库中,它使用MediaStore API来获取非媒体文件。但是在升级到API 30之后,它不再显示任何非媒体文件。 - Bhavin
我有两个应用程序,一个是保存音频文件的跟踪器,另一个是读取这些文件的主应用程序。因此,我不能使用私有存储来存储。 - Jitendra Singh

2

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

或者更标准的方式:您拥有文件,因此要构建自己的文件/内容提供程序来提供您的文件。

如果您使用进程间通信(顺便问一下如何),则可以使用来自MediaStore和FileProvider的URI逐个提供您的文件。


请问您能否分享一些构建自己的文件/内容提供程序的有效链接? - Jitendra Singh
不,我不能。我得去谷歌搜索一下,所以我让你来做吧。 - blackapps

2
我有两个应用程序,一个是Tracker App,记录进出电话并压缩这些文件,并通过进程间通信将文件路径发送到Main App,后者将这些文件上传到服务器。看起来过于复杂。
我能在Android 11上读取由其他应用程序创建的文件吗?
从技术上讲,您没有编写文件。您正在创建MediaStore.Files中的条目。其他应用程序无法读取您在MediaStore.Files中创建的条目。
我的应用程序是否有资格获得MANAGE_EXTERNAL_STORAGE权限以访问存储中的所有文件?
我们不是谷歌。我们无法回答这个问题。但如果他们认为您的应用程序有资格获得此权限,那会让我非常惊讶。
处理这种情况的最佳方法是什么?
在我看来,迄今为止最好的方法是只有一个应用程序,而不是两个应用程序。但我假设您现在无法更改它。
如果是这样,那么:
1. 让“跟踪器”应用程序将内容写入文件系统目录中,该应用程序可以写入该目录。主要使用Context的方法,例如getFilesDir()getExternalCacheDir()。 2. 让“跟踪器”应用程序使用FileProvider从该目录提供文件,并使用FileProvider.getUriForFile()获取指向该文件的Uri。 3. 通过某些基于Intent的机制(例如startActivity()startService()sendBroadcast()等),让“跟踪器”应用程序调用您的“主”应用程序。将来自前一步骤的Uri放入该Intent中,并将FLAG_GRANT_READ_URI_PERMISSION添加到该Intent中。 4. 让“主”应用程序使用ContentResolveropenInputStream()读取内容,并传递从其Intent副本中提取的Uri
“存储访问框架”能帮助我处理这种情况吗?
您可以在每个应用程序中使用存储访问框架。例如,您可以在每个应用程序中使用ACTION_OPEN_DOCUMENT_TREE,希望用户在每个应用程序中选择相同的树。个人而言,我会使用FileProvider,因为它不需要用户交互,并且不需要用户做出良好的选择。

感谢您的回答。正如您建议的那样,我现在正在实施SAF框架。稍后我将把上传任务转移到“Tracker应用程序”中。 - Jitendra Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接