i still don't understand the change made on access media files in android Q. My app downloads videos, but playing or retrieving the video gives error.
Noticed, for android Q, every media file outside of app specific folders need to be registered in the contentresolver. In which the content resolver gives a special id to that file in return. Am i right?
if so how do i register a media file in content resolver and at the same time get the uri of the media file
A good explanation on accessing, saving and opening media files on android Q will be appreciated for a better understanding
The file manipulation changes from android 9 (Q) are really confusing.
Have you read the basic documentation on data and file storage?
Basically consider your app can write and read files that it created inside internal storage or primary external storage on the folders that belongs to this app.
Reading from sdcard can be done but requires permission from the user.
Writing on sdcard can be done with limitations and is not so easy. It also requires user permission.
Media files can be handled by MediaStore api and if they are inside the folders from your app it is easier.
If you want to store Media file on other folders different from the default media folders, then it is a little more difficult.
Please, define better what are your app flows and requirements in order to be easier for someone to help.
Related
I'd like to write an app that crops/resizes photos and writes them back to shared storage in their new size but everything I've read about how SAF and mediastore works suggests that at best I'd only be able to write the file back with a new name. And at worst I might not be able to open the files at all if I'm not the original creator. A solution that involves triggering a SAF dialog to open the file is reasonable though I'd like to be able to just batch change all the files (photos) in a folder (say dcim). But if I have to also trigger a SAF dialog to write the file back out that's pretty yucky.
Obviously if I were to target pre-10 versions of android this could still be done, but then I'd be blocked from the playstore, and I don't really want to write apps that only I can use.
everything I've read about how SAF and mediastore works suggests that at best I'd only be able to write the file back with a new name
Use ACTION_OPEN_DOCUMENT (or ActivityResultContracts.OpenDocument). You have full read-write access to the content identified by the Uri that you receive.
A solution that involves triggering a SAF dialog to open the file is reasonable though I'd like to be able to just batch change all the files (photos) in a folder (say dcim)
Use ACTION_OPEN_DOCUMENT_TREE (or ActivityResultContracts.OpenDocumentTree). You have full read-write access to all of the documents inside of that tree.
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.
I am confused with the new app storage system in Android. I am not sure where my use case falls under and I need your help in telling me the right approach for this
My app captures images and generates pdf documents. Prior to Android 10, I used to store them in an app directory where the user can easily navigate to them through other files browsing app (like Files app on Samsung). In addition, these files can be accessed from within my app (so essentially read and write).
With the new storage, I am not sure how to accomplish the same thing. If I use the internal storage then user can't see them. If I use the media approach, well it seems it is only for Audio/video plus they will not be organized in a folder like I have them organized.
Am I missing something? How would I solve this problem?
Thank you
On an Android 11 device you can store your files in a subdirectory of the public Documents directory.
You can do that using classic File means or the media store or SAF.
Other apps can see them using SAF or the media store. Or with classic file means when requested all files access.
The user can see them using the default Files app on the device.
I have a doubt I read these tutorials just to get the clear understanding of the SAF introduced in kitkat in higher version of android How to use the new SD card access API presented for Android 5.0 (Lollipop)?
How to persist permission in android API 19 (KitKat)?
Android API below 19 equivalent for ContentResolver takePersistableUriPermission
Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT
Now i have a question when the intent is fired and i get select the sd card to get the uritree from the intent which i am getting but is the root tree I will have to iterate through the uri to get the specific file uri.
Now the question is I have mp3 files in my phone and I want to edit that specific file which is selected so how can i get that selected files uri from the tree and edit it?I tried editing directly using file but it makes my mp3 file disappear and i dont want to fire SAF intent again n again so how to check is user has given permission to sd card or not?
P.S. I am using jaudio tagger for editing the tags of mp3 files.
THANK YOU!!
I have got answers of almost everything in this question Now the issue if I am using jaudio tagger library for tagging mp3 files which takes File as a objects but android 4.4 and above wont let u modify File objects so I just want to knw the alternative how can i edit File objects in 4.4 above?
This is how I did it,
first copy the file from the sdcard to the phone memory and then do the desired changes and cut and paste the file again at its original place.
Example is here where I am editing the tag of mp3 file which is in the sdcard:-
https://github.com/reyanshmishra/Rey-MusicPlayer/tree/master/app/src/main/java/com/boom/music/player/TagEditor
The library you refer to is called JaudioTagger, and it does not and most probably will never accept DocumentFile. The Storage Access Framework is Google's invention and far from any standard. And JaudioTagger is written for portability.
However, I finally managed to get JaudioTagger mostly running with SAF, but had to substantially modify it, even to rewrite some functions. Basically I replaced all File and RandomAccessFile with my own classes, and additionally the handling of temporary files and renaming must be rewritten (e.g. the scheme: copy original file, change copy, remove original file, rename copy to original name).
In fact it might be easier to use the native TagLib instead, because that already accepts a special C++ class as input. All I did was to create such C++ class whose basis is a file descriptor derived from ParcelFileDescriptor derived from Uri derived from DocumentFile.
Finally one might come to the conclusion that the Storage Access Framework is somewhat suboptimal.
I have images uploaded on the simulated sdcard on my emulator. I downloaded them from the browser, using the long-click on each image.
When I look at the file explorer in the DDMS perspective, I see that they are in the directory sdcard/download.
Now if I want to download some audio files and use them in an app to, say list the title of all audio files, will they go in the same directory? (I am trying to push the audio files manually from my computer to the emulator).
This doesn't seem right. Shouldn't the media files of different types (pictures, audio, video) go into different directories?
Also, thinking this through a little, how is something like this related to the physical directory on the sdcard?
Uri mMedia = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Thanks!
The correct way to access media content is via the media content providers on the device.
Content providers make it easy to access data in a unified way, whether that data is stored on disk (i.e. /sdcard/...) or in something like a SQLite database. Content providers generally expose data using a custom Android-specific content:// URI scheme.
To query content living at a given content URI (such as MediaStore.Images.Media.EXTERNAL_CONTENT_URI), use the ContentResolver class. Examples on how to use this class can be found all throughout the SDK samples and Android Open Source Project (gitweb).
Also look at the MediaScannerConnection class for information on triggering media scanning (which populates the media content providers), etc.