Write a private access file to another app's files directory

13,028

Solution 1

First of all, NEVER use a full path to internal storage like /data/data. Let the operating system give you the path (for example, via Context.getFilesDir() or Environment.getExternalStorageState()). Don't make assumption on where the data is.

Secondly - you already are doing that! Unlike File, Context.openFileOutput already prepends /data/data/[package] to your path, so you don't need to specify that. Just specify the file name.

If you really feel that it's safe and necessary, and if both apps share the same user ID using android:sharedUserId in the manifest, you can get a context of the other app by using Context.createPackageContext() and use CONTEXT_RESTRICTED, then use openFileOutput with only the file name.

Solution 2

Open a FileOutputStream of the needed file, relative to this path:

String filePath = getPackageManager().
    getPackageInfo("com.your2ndApp.package", 0).
    applicationInfo.dataDir;

Solution 3

Since this is months old I assume you've already solved your problem, but I'll contribute anyway.

Sharing data between apps is what ContentProviders are for. Assuming that you know how to write a ContentProvider and access it, you can access files via ParcelFileDescriptor, which includes constants for the mode in which you create the files.

What you need now is to limit access so that not everybody can read the files through the content provider, and you do that via android permissions. In the manifest of one your apps, the one that will host the files and the content provider, write something like this:

<permission android:name="com.example.android.provider.ACCESS" android:protectionLevel="signature"/>

and in both apps add this:

<uses-permission android:name="com.example.android.provider.ACCESS" /> 

by using protectionLevel="signature", only apps signed by you can access your content provider, and thus your files.

Solution 4

You should not be overwriting other applications files. That said you have two solutions

  1. Use public external storage (like the SD card) to share the file between the apps.
  2. If the other app is not yours then you can't write to its /data directory, without root that is. Anything is possible with root, just don't expect your users to all have root access.

Edit: Developer owns both applications

Thanks for Roman Kurik for pointing this out. A link to his post on SO

From the android docs

android:sharedUserId

The name of a Linux user ID that will be shared with other applications. By default, Android assigns each application its own unique user ID. However, if this attribute is set to the same value for two or more applications, they will all share the same ID — provided that they are also signed by the same certificate. Application with the same user ID can access each other's data and, if desired, run in the same process.

So this is exactly the way user id's work in linux, essentially you are the owner of both and have read/write access to both.

Share:
13,028
700 Software
Author by

700 Software

Join 700.social ! A happy medium between Facebook and Gab. :) The name is too long but the domain looks good. Also, Software Development / Consulting (423) 802-8971 700software.com old username: George Bailey (but now I use my real name) http://www.google.com/images?q=George+Bailey

Updated on July 29, 2022

Comments

  • 700 Software
    700 Software almost 2 years

    The two apps have the same sharedUserId. When I use this code in app1

    context.openFileOutput("/data/data/org.me.app2/files/shared-data.dat", MODE_PRIVATE)
    

    I get an exception telling me that the file contains a path separator.

    I am trying to write a file from app1 into app2's storage. (I do of course need to make sure that app2's files directory exists first)

    Ideally, I would write to a user specific directory instead of an app specific directory, but I do not know if that can be done

  • 700 Software
    700 Software over 13 years
    But how do I say app1 should write a file to app2?
  • EboMike
    EboMike over 13 years
    That's generally discouraged. You should never write into another app's private storage! MODE_PRIVATE specifically will not do you much good - the data wouldn't even be readable by the other app! If you really really have to, use File to specify an absolute path. But it sounds like you're using the wrong approach to begin with.
  • 700 Software
    700 Software over 13 years
    First of all (I think) MODE_PRIVATE would work because I am using the same sharedUserId. Second, I was planning to write shared data to both apps. It is important that unknown apps do not have access to the shared data.
  • 700 Software
    700 Software over 13 years
    The two apps have the same sharedUserId. I control both apps. Also it is important that unrelated apps do not have access to my data. So I don't think either of those two options will work... but what is that about root. Are you saying that I can run my app as root?
  • EboMike
    EboMike over 13 years
    Try creating a context for the other app using Context.createPackageContent(), then use openFileOutput with only the file name. Haven't tried that, but since you have a sharedUserId, that may just work. I wouldn't be surprised if it doesn't work though.
  • smith324
    smith324 over 13 years
    It is possible to gain root access on most phones, this is how custom roms can be installed. From there applications can request root via the 'Superuser' application. But since you control both there should be a simpler solution, I'll get back to you in a bit.
  • 700 Software
    700 Software over 13 years
    It worked. I was used CONTEXT_RESTRICTED for the second parameter for createPackageContent
  • ognian
    ognian over 13 years
    This doesn't answer the question
  • 700 Software
    700 Software over 13 years
    +1: I was able to use this to check modification time/exists on other app without using absolute path.. Thanks.
  • 700 Software
    700 Software over 13 years
    Actually I ended up using createPackageContent
  • ognian
    ognian over 13 years
    If you move the useful info from comments to the answer, I'll give you an upvote.
  • EboMike
    EboMike over 13 years
    Might as well... here you go.
  • 700 Software
    700 Software almost 13 years
    Very interesting. I will not be able to try it out however, since the solution has already been implemented, and any/all additional apps/upgrades will probably re-use the existing system. +1 anyway. I think your solution is valid even though I have not been able to test it out.
  • Ishyc
    Ishyc over 10 years
    +George Bailey +EboMike You seem to have solved this without ContentProviders… what did you do and how did it work out for you? (Stackoverflow actively rewards answerers of their own questions :))
  • EboMike
    EboMike over 10 years
    @jamesh The answer should contain everything you need. Do you have any problems or questions?
  • Ishyc
    Ishyc over 10 years
    @EboMike my bad. I got confusticated.