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

How to implement New Storage API in Android 11?

场景

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

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

这里我有几个问题。

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

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

如 Android 11 MediaStore API 仅 returns 个媒体文件。

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

Can I read files that are created by the Others app on Android 11? I read somewhere that you can't access others apps files in Android 11.

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

Is my app eligible for MANAGE_EXTERNAL_STORAGE permission to access all files in storage?

据我了解,您的应用不需要外部存储来存储数据,它也可以在您可以读取或写入数据的私有存储中完成。如果您的应用无论如何都符合此权限的条件,您现在仍然无法使用它。官方网站建议,而不是请求此权限 make target API 29 并在您的清单中使用 android:requestLegacyExternalStorage="true" 。 click here to read about it.

What will be the best way to handle this scenario?

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

Can ``` Storage Access Framework `` help me to handle this scenario?

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

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

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

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

I've two apps, one is the Tracker App which records the incoming and outgoing calls and zipped these files, and sends the file path to the Main App via Inter-Process Communication which uploads these files to the server.

这似乎过于复杂了。

Can I read files that are created by the Others app on Android 11?

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

中创建的条目

Is my app eligible for MANAGE_EXTERNAL_STORAGE permission to access all files in storage?

我们不是Google。我们无法回答。不过,如果他们认为您的应用符合此条件,我会感到非常惊讶。

What will be the best way to handle this scenario?

嗯,恕我直言,到目前为止最好的方法是拥有一个应用程序,而不是两个。但我假设您目前无法更改它。

如果是,则:

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

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

  • 让“跟踪器”应用程序通过某种基于 Intent 的机制调用您的“主”应用程序(startActivity()startService()sendBroadcast() , ETC。)。将上一个项目符号中的 Uri 放入 Intent,然后将 FLAG_GRANT_READ_URI_PERMISSION 添加到 Intent

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

Can ``` Storage Access Framework `` help me to handle this scenario?

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