How to implement New Storage API in Android 11? - android

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.
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?
What will be the best way to handle this scenario?
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

As in Android 11 MediaStore API only returns media files.
so, i will answer your questions related to it.
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.
No! you can't access the files created by other application that are stored in personal storage of that specific app.
Is my app eligible for MANAGE_EXTERNAL_STORAGE permission to access
all files in storage?
As far as i understand, your app doesn't required external storage to store the data it can be also done in private storage where you can read or write your data. and if your app is eligible for this permission anyway still you can't use it as of now. it's been suggested by official web rather then asking this permission make target API 29 and use android:requestLegacyExternalStorage="true" in your manifest.
click here to read about it.
What will be the best way to handle this scenario?
Rather using external audio path you can use you app specific folder to store the archive that you are creating.
Can ``` Storage Access Framework `` help me to handle this scenario?
I don't have much idea about how IPC work between two apps so i can't tell exactly that it will be better to use Storage framework.

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.

The receiving app can use SAF to let the user pick your directory.
Or more standard: you have files so you build your own file/content provider to serve your files.
And if you use inter process communication(how by the way) you could serve your files one by one using the uri from mediastore and FileProvider.

Related

Grant read access to FileProvider to any client app without knowing their package name

In the context of a MediaBrowserService for audio playback I need to provide image files via a ContentProvider (FileProvider). The URIs are propagated via meta data related to media browsing and playback. There are no Intents involved.
I need to grant read permission to any client app that tries to access the image files. As far as I can tell the only way to grant permission is via Context.grantUriPermission(). This involves knowing the package name of the client app. And that is my problem: at the time the URI is prepared and added to the meta data, I don't know (reliably) which apps will access the content.
To be more conrete: In an Android Automotive OS environment, the system media browser app will browse my content. It won't render images provided as Bitmap objects or images represented as online URLs. The only way I found to make it render images is via ContentProvider URIs. I do know the package name of the system media browser during browsing so granting file read permission works fine here.
But there are multiple apps accessing the meta data involved during playback. For instance the launcher app displays information about the media that is currently played. The launcher crashes trying to access the media art.
I do know the package names of the apps involved an could just hard code them. I guess I don't need to explain why I don't want to do that. I could query the package names of all apps installed on the device (at least that's what I assume), but that doesn't feel appropriate. Also theoretically additional related apps might be installed on the device later and then they will lack the required permission.
What I am looking for is a clean way to determine the package names of any app trying to access my FileProvider so I can grant read permission to it. Or any other way to grant read permission. In fact, I don't want to prohibit read access to the provider at all, so I would prefer to export the ContentProvider but that's not allowed anymore. Can anybody help me out here please?
FileProvider does not support your scenario, due to decisions made by its developers.
As blackapps mentioned in a comment, you will need to create a custom ContentProvider that happens to serve files. Then you can elect to export that provider and not apply a read permission to it. However, be very careful that your ContentProvider only serves files that you want it to, and that attackers cannot use hacks like ../ in path segments to trick you into serving files outside of those.

Access all files on android

I am trying to make a file manager type application and I want to access all files. I know it will need MANAGE_EXTERNAL_STORAGE permission but I am not able to figure out which api should I use.
I am trying to make a file manager type application and I want to access all files.
I'll recommend you to start from here : Manage all files on a storage device (keep in mind you cannot write internal storage on a non-rooted device).
I am not able to figure out which api should I use.
MediaStore might suit your needs (even if your question is a bit generic) , so give it a reading to Access media files from shared storage.

How to write to the external storage in android that will be present even after the application is uninstalled?

I am trying to build an application in which user can share media files over internet. Now I am confused that there are lots of functions in the library through which we can get access to files stored in the users storage. I don't know which to use..
In Context#getExternalFilesDir(String) documentation, they insist using Environment.getExternalStoragePublicDirectory() to write media that must be shared with other apps and that must be kept even after uninstall of an app. But in Environment#getExternalStoragePublicDirectory(string) documentation, they say that this method is deprecated, and recommend using alternatives such as Context.getExternalFilesDir(). If that was deprecated in first place, then why did they insist to use that method. What is the reason behind them playing these tricks, I don't understand.
Please suggest me a function that is: not deprecated, should return a directory where I can read and write, media stored there should be visible to other apps, they must not be deleted when user uninstalles this app.
I believe you are looking for Shared Storage.
Android file system and storage changed a lot during this years.
Data and file storage overview

How to copy files in external storage in Android Q

I made a app(is called A) without UI which provides some information to other clients app with AIDL.
So I want to make an UI app(is called B) for displaying A apps status and send some files to server(logs, db, etc...).
However, I'm having some problem with Scoped Storage in Android Q.
(I know about android:requestLegacyExternalStorage="true" but I don't want to use this trick)
I'm looking for MediaStore and SAF(Storage Access Framework) but I'm not sure which one is right and something more(what I didn't think)
Could I use MediaStore for copying DB files to external storage(actual public space for other apps)?
Could I use SAF even an App A doesn't have any UI?
(and how?)
Thanks for helping me.
Just request that legacy external storage.
It is not a trick. And quite handy for an Android 10 device. It works only on an Android 10/Q device.
which provides some information to other clients app
In which way?
You could use a content provider for that.

How do you get access to the raw of a different app using uri?

Is there a way to access the raws of a different app through manifest settings or anything of that sort? I am trying to access raw mp3 of an app to play on a different app.
If by "raw" you mean the contents of another app's /res/raw/ folder then you can't. At least not without SuperUser/Root access.
You could theoretically manually pull apart the app in question on your PC and use their resources as you wish where you wish but that may very well be at best a breach of their TOS and at worst copyright infringement.
However, if you have control over the app in question that contains the resource you want access to you could define a ContentProvider to allow public access. Perhaps the app even already has one?
Edit: You have now clarified that you have access to both apps so then you can of course share whatever you like with yourself.
As I mentioned above you can use a ContentProvider to share resources or information between apps. In this particular case you are looking to share an audio *.mp3 file I would suggest a FileProvider which inherits from ContentProvider.
I'll leave the implementation details to the official Android docs linked as they do a much better job of explaining it than I ever could.
In a nutshell though:
App A which holds the audio file defines a FileProvider.
App B makes an Intent request to App A for a/the file (with optional authentication)
App A can either return the file now or offer a choice of files to App B.
App B either consumes the received provider and gets its file or tells App A which file it wants.
App A can now pass the chosen file to App B which consumes it.
P.S. As some bedtime reading you could have a look at this alternative implementation that links to a github repo and explains the usage of a project from SO's very own CommonsWare: https://stackoverflow.com/a/14734310/1590950

Categories

Resources