Search code examples
androidmediastoreandroid-11storage-access-frameworkscoped-storage

How to implement New Storage API in Android 11?


Scenario

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.

Now I'm upgrading both apps to Android 11. In Tracker App, I'm using MediaStore.Files API to save files and trying to read these files using the file path in Main App. While reading file File.canRead() returns false in Main App. Even I tried MediaStore API to read these files it returns empty Cursor.

Here I've few questions.

  1. 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.
  2. Is my app eligible for MANAGE_EXTERNAL_STORAGE permission to access all files in storage?
  3. What will be the best way to handle this scenario?
  4. Can ``` Storage Access Framework `` help me to handle this scenario?

I'm saving files in the public directory Documents/AppData/Audio. Please give me working links regarding this. Any help will be appreciated. Thanks


Solution

  • 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.

    That seems overly complex.

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

    Technically, you are not writing a file. You are creating an entry in MediaStore.Files. Other apps cannot read entries that you create in MediaStore.Files.

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

    We are not Google. We have no way of answering that. It would surprise me greatly, though, if they considered your app to be eligible for this.

    What will be the best way to handle this scenario?

    Well, IMHO, the best way by far would be to have one app, not two. But I am assuming you are not in position to change that at this time.

    If so, then:

    • Have the "tracker" app write the content to files in a filesystem directory that the app can write to. Mostly, that will be via methods on Context, such as getFilesDir() or getExternalCacheDir().

    • Have the "tracker" app use FileProvider to serve files from that directory, and use FileProvider.getUriForFile() to get a Uri pointing to that file.

    • Have the "tracker" app invoke your "main" app via some Intent-based mechanism (startActivity(), startService(), sendBroadcast(), etc.). Put the Uri from the previous bullet into that Intent, and add FLAG_GRANT_READ_URI_PERMISSION to that Intent.

    • Have the "main" app read the content using a ContentResolver and openInputStream(), passing in the Uri that it extracts from its copy of the Intent.

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

    You could have the user, in each app, use the Storage Access Framework. For example, you could use ACTION_OPEN_DOCUMENT_TREE in each app, hoping that the user would choose the same tree in each app. Personally, I would use FileProvider, as it does not require user interaction and does not require the user to make good choices.