7

Tested on Android 4.3. I have two apps, com.my.app.first and com.my.app.second. In my activity I want to read preferences from the other app. I chose to use the same user ID for both my apps:

android:sharedUserId="com.my.app"

I always load my preferences like this:

prefs = getSharedPreferences("MyAppPreferences", Context.MODE_PRIVATE);

Now, in my second app I do the following:

try {
    Context context = createPackageContext("com.my.app.first", Context.CONTEXT_IGNORE_SECURITY);
    // context.getPackageName() does indeed return "com.my.app.first"

    // Note: Context.MODE_WORLD_READABLE makes no difference here!
    prefs = context.getSharedPreferences("MyAppPreferences", Context.MODE_PRIVATE);
}

prefs.mFile erroneously points to /data/data/com.my.app.second/shared_prefs/MyAppPreferences.xml.

Obviously, the call to getSharedPreferences returns the preferences for the current app even though I used the context of the other app. What am I doing wrong? Please help!

l33t
  • 18,692
  • 16
  • 103
  • 180

4 Answers4

2

Found the problem! This sure looks like a bug in the getSharedPreferences API. It turned out that a previous call to getSharedPreferences caused the other context.getSharedPreferences() call to return the previous instance - the current app's preferences.

The solution was to make sure that getSharedPreferences() was NOT called before reading the preferences of the other app.

l33t
  • 18,692
  • 16
  • 103
  • 180
2

Solved by just reading the old context again. Sounds like a cache to me too.

Context tempContext = context.createPackageContext(originalContext.getPackageName(),Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedInformationM2 = tempContext.getSharedPreferences("sharedInformation", Context.MODE_WORLD_READABLE);
Brian North
  • 1,398
  • 1
  • 14
  • 19
1

You might want to make the SharedPreference created in App A MODE_WORLD_READABLE and use a common sharedUserId for both App A and App B. Like mentioned in the link,

http://androiddhamu.blogspot.in/2012/03/share-data-across-application-in.html

stack_ved
  • 721
  • 3
  • 11
  • Thanks, but doesn't `MODE_WORLD_READABLE` make the preferences readably by *all* apps? I thought the purpose of `sharedUserId` was to allow reading private data. – l33t Aug 19 '13 at 12:47
  • This is what the documentation says about `MODE_PRIVATE`: *File creation mode: the default mode, where the created file can only be accessed by the calling application (or all applications sharing the same user ID).* That's why I posted my question. – l33t Aug 19 '13 at 12:51
  • Right MODE_WORLD_READABLE makes it read-able all the applications, by nature, and my bad about sharedUserId, instead what i meant was use a unique name while calling like context.getSharedPreference("unique", MODE). http://developer.android.com/reference/android/content/Context.html#getSharedPreferences(java.lang.String, int) – stack_ved Aug 19 '13 at 12:58
  • you have said you are using prefs = context.getSharedPreferences("MyAppPreferences", Context.MODE_PRIVATE) here, with Desired Name as MyAppPreference, this will result in system creating a new shared preference file for this app. ideally it should be the same as what the other applicatin uses while creating. – stack_ved Aug 19 '13 at 13:07
  • I googled this, and a few sources show my code snippet. Will it create a new file even though I'm using the other app's context? Makes no sense. – l33t Aug 19 '13 at 15:47
0

Since both your apps are running you can also solve this problem by setting shared preferences:

tempContext.getSharedPreferences("sharedInformation", Context.MODE_MULTI_PROCESS);
arghtype
  • 4,376
  • 11
  • 45
  • 60
topGun1028
  • 21
  • 5