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.
Related
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
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
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.
I know that similar questions have been posted before, but I believe there has not been an answer for my exact use case.
I have a trial and a full version of my Android app. When the user buys the full version, both versions should share their settings. Changes in one app should show up in the other app as well. When one app is un-installed, the settings shall be preserved for the other app. It's not a one-time import because the user might not uninstall the trial app and could even continue using it.
Both apps use the same shared user id and run in the same process. However, when I call getFilesDir(), the directory returned contains the package name of the app, so the directories for storing files used by the two apps differ. How can I have both apps use the exact same file without using external storage?
How can I have both apps use the exact same file without using external storage?
That will not meet your objective:
When one app is un-installed, the settings shall be preserved for the other app
Given that objective, by definition, you cannot be using a single file that will be removed on uninstall, as if the user uninstalls that app, the other app is broken.
Your choices are:
Use external storage, specifically not getExternalFilesDir() or getExternalCacheDir(), or
Have each app maintain its own copy of the file, using some mechanism to keep the changes in sync, or
Switch to in-app purchases, so you do not have separate free/paid apps, or
Abandon your "both apps should share their settings" objective
You need to save those preferences either to a file or database if you want them to remain after the process containing all the components close.
A quick way, if you have this in your control, is to change all the uid's for your applications to the same and use the file api's for reading and writing from a file or the database. Using a database is just a step away from using a content provider though... which is probably the correct most solution.