My company has three different Android apps that provide functionality for sales reps. We opted to separate the apps into "modules" because not all reps need all the modules. Up to now we have been using a JSON file in a directory on the SD card of the devices to set some configuration data for the apps. However, it appears that with Android 10 and beyond this will no longer be possible.
Currently we use getExternalStorageDirectory() to access the SDCARD and then open a file inside a directory our app creates.
Since we want the file access to not be something the sales reps have any control over we want it to happen transparently. However it does not seem this will be possible going forward.
Will using a custom FileProvider or even a DocumentsProvider be a way to continue to share data between our apps?
Another question, although not as important, is, can we change the default location of the DB files our app creates as we do now in earlier versions of Android?
Thanks
Rich
Related
I'm going to create an app for accessing the files from the Internet. I do not want to implement UI, but instead to make them visible from other file managers. So, I chose to implement a Document Provider. And I did it. On the next pictures you can see that I open "Files" app, find "My document provider" and can access its files.
However, it's an emulator. When I tried to use the app on my physical device I found that I have no ways to see document providers. I use Xiaomi Redmi Note 5 Pro (android 9.0) there is no "Files" app. I tested top ~20 File Managers from Google Play and even MIUI build in file-explorer, but none of them can show me my "My document provider".
I managed to see my documents provider only when tried to attach a document from Gmail app. But it's not what I need.
Questions:
am I right that Documents Provider is not what I need?
Am I right it's rather an ADDITIONAL way to share the files with other client apps which use Storage Access Framework (like Gmail, photo editor, etc), but was not designed to be used as the main method for accessing the files?
Am I right that I have to implement my own Activities with UI and full functionality of file explorer as a main approach for user to access his files? (like Google Drive app - it has both: own UI for managing the files and documents provider accessible from system picker)
UPDATED
Finally I've found a solution. As I understand standard application "Files" is build in to ANY device. However, probably, manufacturer "hides" this app and provides some analog. On MIUI it's some "File Manager". On many Samsung devices, as well as on Pixel 2 XL, it's "Google Files" app. None of them see document providers. Only "Files" app can.
The "Files" app is still accessible as an option when you use SAF (for example start an Intent with ACTION_OPEN_DOCUMENT). But still you are not able to launch that app standalone. However, you can download "Files shortcut" from Google Play. When open it, you can choose an app for which "Files shortcut" should work as a shortcut. I chose "Files" app and everything works (didn't work until I checked "remember my choice" option). On both, Pixel 2 and Redmi Note 5 I can see my document providers. It's a great news, since I do not have to waste time for creating UI!
P.S. Please note, what I described above is not taken from a reliable source. I used the phrase "hidden app" and the fact about pre installed "Files" on ANY device just based on my observation and understanding.
P.P.S Also, I found that on Pixel 2 in "Google files" app there is also a way to open "Files": Browse -> Other storage -> System traces. For some reason there is no "Other storage" button on Redmi Note 5.
I do not want to implement UI, but instead to make them visible from other file managers
You have no means of forcing other apps to do much of anything. In particular, you have no means of forcing a file manager to show things from your app.
Am I right it's rather an ADDITIONAL way to share the files with other client apps which use Storage Access Framework (like Gmail, photo editor, etc), but was not designed to be used as the main method for accessing the files?
Correct. A DocumentsProvider is for making documents available via the Storage Access Framework. A file manager could elect to show documents from the registered DocumentsProvider implementations on the device. In practice, I am not surprised that few file managers do this. You might consider contributing that feature to open source file managers.
Am I right that I have to implement my own Activities with UI and full functionality of file explorer as a main approach for user to access his files?
That is up to you. If you want your app to be guaranteed to do something for all of your users, having your own UI for traversing your collection of documents would be a good idea.
I am writing a specific use-case camera app that targets Android 11. When I hit record I would like to create a new directory somewhere (with a name based on the timestamp etc) that contains the resulting video as well as a whole heap of other custom YAML/JSON/CSV files that also get written during the recording process (belongs logically to the "output" of the recording).
I would like all of the generated files to survive an app uninstall/reinstall as I do not want to risk users losing everything they've ever recorded if they uninstall the app. How do I do this with the new scoped storage changes etc in Android 11?
Looking at the overview here, I can see that:
App-specific files, App preferences and Database are clearly not suitable as amongst other things these files do not survive an uninstall
Documents and other files uses the Storage Access Framework, but this is not suitable because it requires a system file picker every time you want to write something. This would disrupt the flow of recording/user experience, and no camera app works like that.
Datasets/BlobStoreManager (here) also is not appropriate for my use case.
MediaStore API looks like it should be the one, but it can't seem to do what I want in terms of producing a whole directory of outputs, including custom YAML/JSON/CSV text files, that all belong together. My aim is that the user at all times can simply go to the file explorer, navigate to the appropriate folder, and just copy out the folder(s) with the recordings to their computer or whatever, to save/view the data. Even MediaStore.Files does not seem to guarantee you can actually do that if your app is using scoped storage.
The only option that seems to be left is using MANAGE_EXTERNAL_STORAGE and putting the data wherever I want in the home directory, but that seems like a bit of an extreme permission to be asking for just in order to be able to save some text files along with my produced videos. Also, that permission is Android 11 specific. If I want to support older Android versions, what would I need to do?
What is my best choice here? Is there an option I've missed?
but this is not suitable because it requires a system file picker every time you want to write something
No.
Use ACTION_OPEN_DOCUMENT_TREE to let the user pick a document tree. In there, you can create your own sub-tree and put your own documents into that sub-tree. You do not need the "system file picker" for anything beyond the initial ACTION_OPEN_DOCUMENT_TREE request itself. And the resulting documents will survive an uninstall.
You can create your own directory in a public directory like DCIM, Pictures, Music or Movies with classic File methods.
Android introduced the Multiple Users feature in 4.2 (Jelly Bean MR1) and its documentation states:
From your app’s point of view, each user is running on a completely separate device.
And here is a quote from the Environment.getExternalsStorageDirectory() and getExternalStoragePublicDirectory() methods doc:
On devices with multiple users (as described by UserManager), each user has their own isolated external storage. Applications only have access to the external storage for the user they're running as.
Could it be true that there really is no reliable way to communicate data between users on a single device without using the network as mediator? I'm looking for solutions that don't rely on quirks of how the device's file system is laid out by a manufacturer. Also, for security, the sharing should be internal to my app.
Even if file sharing is indeed impossible, is communication via intents somehow possible?
There are use cases for this. Use Case 1: let's say I'm writing an input method app that requires a 100MB dictionary file. I'd like to code things so that if User A downloads this file, then User B can access it also without needing to re-download. Use Case 2: let's say I'm writing a fun Leave My Wife a Note app that allows User A to type messages that will appear next time User B logs in (without using the network).
This thread on a separate site proposes a solution, but their method seems undocumented and possibly unreliable. And there are a few other SO questions that have a title similar to this one but are actually discussing different topics.
OBB Folder (/sdcard/Android/obb) is used to share files and folder between the multi users. But OBB folder not shown in my second user (One plus 5 mobile). So I have tried to create an OBB folder in Android folder (/sdcard/Android/) in second user and "BOOM" it worked. Now i am able to access the shared files in second user. Try this trick if OBB folder not shown in your second user.
OBB files (stored in /sdcard/Android/obb) and used as expansion files in Google Play are shared between all users by design, as they are fairly large. If you Input method uses expansion files, the downloaded data will be shared automatically. You can send broadcasts to other users but that requires the INTERACT_ACROSS_USERS permission, which is reserved for system applications.
I also had the same question, and have tried various approaches such as using /sdcard/Android/obb but it does not work in Android 10. So I followed below approach, and I am able to copy files seamlessly between users.
Login to the User from where you would like to copy files from (lets call U1)
Run FTP Server using any application of choice like MiXplorer / ES Explorer etc... Note down the details of the port#, username, password etc... and point it to /sdcard
Switch user, to where you want to copy files to (lets call U2)
Install the FTP browser. If you use MiXplorer / ES Explorer, they will allow you to add a FTP share
Use ftp://localhost:2121 assuming the port is 2121, if not change it accordingly and add the FTP share
Open the FTP share and you can see all the files & folders of U1 here
Copy across to your heart's content !
Does android support cross application file access i mean Lets say Application A created a file called
"abcd.txt", can we access the file "abcd.txt" from another application B like how it can be possible in windows and not possible in iOS. please help.
This is possible, even multiple manners.
If both applications are from the same developer they could use the same shared user id. This is an attribute in the AndroidManifest.xml, android:sharedUserId. When different applications/apks have the same userid they are able to read each others files. When using this technique, files are still prive to the rest of the OS, but are readable/writable by other apks from the same developer.
Another posibility is using the sdcard to share data. That storage is publicly available.
Android has built-in support for sharing data with other applications through the use of ContentResolvers. This does not work for files, but is probably the preferred way to shared data between applications.
According to the Android Development Documentation, you can't just open any file you want ("Open a private file associated with this Context's application package for writing.").
What, however, when I want my application to read files created by other applications? Let's say I have a file in /data/app_1/hello.txt, but my application has nothing to do with it because my app is called app_2, how would I still be able to open this file (and write back to it)?
You can't in general, Applications on Android are isolated and sparated. A application can only write and read its own files.
There are exceptions: As the documentation states: "It's possible to arrange for two applications to share the same Linux user ID, in which case they are able to access each other's files. To conserve system resources, applications with the same user ID can also arrange to run in the same Linux process and share the same VM (the applications must also be signed with the same certificate)."
Another possiblity is that the files are created as "world readable" so that every application can read it.
So to summarize and come back to your question: If you can not modify "my_app_1" then it is impossible. Of you can modify both applications choose one of the solutions above.
Two options:
If you are designing both applications and want to share the file, keep it somewhere else (for example - external storage) or make it world readable.
If you are trying to read another app's file - well, you shouldn't, that's a key element in the android security architecture.