we have two apps. The first one is creating some audio files and save in internal storage (Shared storage according to android 11). The first app is creating an audio file and shared the audio file path to our second app and the second app access that audio file using the file path and upload it to the server.
We are using contentProvider to share the filePath to the second app.
Our first app is able to create audio files in internal(shared) storage because its target SDK version is still 26.
But we have changed the target SDK version of our second app to 30 (android 11), Because of the android 11 restriction, our second app is not able to access those audio files from internal (Shared storage) using the file path provided by the first app. Permission denied exception is coming if I am trying to access those files.
And those audio files are saved in the 'my_recrodings' folder. which is created by the first app in shared storage.
Full Path = /storage/emulated/0/.my_recrodings/
Please help me. How can I access those files?
Related
We are writing a C++ app that is cross compiled for Android. This app uses native libraries (namely gdal and Qt) to read and write files.
These files often have references to each other (e.g. a xml file, referencing other files next to it; or shapefiles, where multiple files have a common base name). The above mentioned libraries need to be able to open files by path (fopen(name)) to get access to all information.
Common use cases are:
download a zip file using a browser, unzip it using an file manage (e.g. amaze) and open the contents in our app
use a file sharing app like nextcloud, syncthing, ... to sync a folder. The files in this folder are then edited by our app.
Since API level 30 Google PlayStore restricts file access and only allows unrestricted direct file access in an specific app-specific directory.
In shared folders (e.g. the Download folder, root folders in external storage devices, etc.) only a subset of file types is accessible through direct file access.
The Acess media files from shared storage documentation mentions
If you don't have any storage-related permissions, you can access files in your app-specific directory, as well as media files that are attributed to your app, using the File API.
Media files in our tests include images, videos, ... but not the file types required here (.dbf, .shp, .qgs).
There is also the storage access framework where a DocumentProvider can be used to stream data of individual files and intents like OPEN_DOCUMENT_TREE these will however generate access via URI which is not compatible with native fopen(name) calls.
The only option we found capable of opening files by name (through native labraries) is to use the all files permission (MANAGE_EXTERNAL_STORAGE). This works well but needs to be whitelisted to be published on Google Play Store.
Google support suggests using the system file picker (and sometimes extends the suggestion to "or other privacy friendly approaches").
Q: If your libraries could work with paths before then they still can. Where is it that the problem starts?
A: On Android 11, without a MANAGE_EXTERNAL_STORAGE permission, what we have seen in our multiple tests is that directly opening non-media files in shared locations via their path strings is not working anymore.
The file opening fails.
We have also noticed that doing a directory listing (using Qt APIs) only shows media file extensions, skipping all other types.
How is it possible to open files by file path (string) in shared locations with native libraries without the all files permission (MANAGE_EXTERNAL_STORAGE)?
My ideas app does not have an online back-end, so users can export a zip file to backup/transport their ideas. Then on their other (new) device, they could import the zip file from their download folder. Inside the app the zip file is extracted and the content (text, audio, images) recreated.
Since Android 10 (and beyond) the way files and permission works is different.
On https://developer.android.com/training/data-storage/shared/documents-files#grant-access-directory
it says:
When using ACTION_OPEN_DOCUMENT_TREE, your app gains access only to the files in the directory that the user selects.
On Android 11 (API level 30) and higher, you cannot use the ACTION_OPEN_DOCUMENT_TREE intent action to request access to [...] the Download directory.
https://developer.android.com/about/versions/10/privacy/changes
By default, apps targeting Android 10 and higher are given scoped access into external storage, or scoped storage. Such apps can see the following types of files within an external storage device without needing to request any storage-related user permissions:
Files in the app-specific directory, accessed using getExternalFilesDir().
Photos, videos, and audio clips that the app created from the media store.
https://developer.android.com/about/versions/11/privacy/storage
(as far as I can tell, the same rules as for 10 regarding my issue)
Since my files are not media files, it doesn't seem to be possible to let users select the file from a list.
I actually thought my current solution (file chooser, pointing to Environment.getExternalStorageDirectory()) was working, since it worked in emulator. But today I got a new device with Android 10 and it failed.
I find it very hard to find an answer to this question, because the search words and documentation all resolve around media files (images mostly).
Any way the user could import the zip file will do. But it is quite difficult for a normal user to move a downloaded / USB transfered file first into an app specific folders or something like that.
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.
We have a flutter app similar to Whatsapp (say MessagingApp) for broadcasting messages with media (images, videos, PDF) within a closed group of people.
The current flutter app's android targetSdkVersion is 29 and uses the Legacy Storage using file path access method to read and write media files as described below.
All the app's media files are downloaded under the base directory /storage/emulated/0/MessagingApp.
Following are the example file path's of various media:
Sample Downloaded Image's path /storage/emulated/0/MessagingApp/MessagingApp_Images/20210410_111512.jpg
Sample Downloaded Video's path /storage/emulated/0/MessagingApp/MessagingApp_Videos/20210410_111513.mp4
Sample Downloaded PDF's path /storage/emulated/0/MessagingApp/MessagingApp_Documents/20210410_11151.pdf
To download an image the dio package is used:
dio.download(imageHttpUrl, '/storage/emulated/0/MessagingApp/MessagingApp_Images/20210410_111512.jpg',)
The downloaded image is rendered in the app using the Image.file widget:
Image.file(File('/storage/emulated/0/MessagingApp/MessagingApp_Images/20210410_111512.jpg'))
The downloaded images can be viewed from android's Gallery app.
Starting November 2021, Playstore forces the targetSdkVersion to be 30 and in the API Level 30's Scoped Storage model, apps cannot create folders directly in the "Shared Storage".
In Scoped Storage the files can be downloaded and used from the app specific directory - /storage/emulated/0/Android/data/org.test.MessagingApp/files
But they will not accessible to other(Gallery) apps.
Other than that Scoped Storage mentions to use "MediaStoreAPI" for managing media.
How to manage and handle downloaded media in Flutter android (API 30) with the new Scoped Storage of Android 11?
Also i noticed on emulator running android 11 and app with targetSdkVersion 30, the app cannot create a folder in the root storage /storage/emulated/0/, but the android folders "Documents, Download, DCIM, Pictures and so on" are freely accesible, that is new folders can be created under them using the existing code i.e. the image path can be changed to /storage/emulated/0/Documents/MessagingApp/MessagingApp_Images/20210410_111512.jpg and it works.
What is the best practice for using the new Scoped Storage of Android 11 for a Flutter android app?
I'm working with one of the many Android FFmpeg libraries on GitHub, which each involve an NDK wrapper around a C binary. I'm trying to give other apps access to the video file I have edited with FFmpeg (and saved in External Storage), but at least on Android 6.0, the new permissions system prevents them from being able to access the shared file unless they themselves have the External Storage permission granted. The solution here would be to use content providers to open up a directory for other apps to access. However...
My FFmpeg binary is contained within the app's data directory, but it fails when I try to access or modify a video file saved there. As mentioned above, it has no problem accessing external storage.
Is there a way to give FFmpeg access to my app's data directory, giving it read and write permissions? Would naming the library with the same package name do the trick?
Any ideas? Thanks for any advice!