0

I have 2 applications Application 1 (com.mine.app1) in which I have declared a SharedPreference.

SharedPreferences controlinfo = getSharedPreferences("pincode", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE);
SharedPreferences.Editor editor = controlinfo.edit();

editor.putString("pincode", "dddd");
editor.commit();

I have an application 2 (com.mine.app2) in which I try to read out the SharedPreference from Application 1.

Here I have the following code (under onclick of a button):

Context con = createPackageContext("com.mine.app1", 0);
SharedPreferences interalPref = getSharedPreferences("pincode", MODE_PRIVATE); //shared pref of App 2 (this app)
SharedPreferences externalPref = con.getSharedPreferences("pincode", MODE_PRIVATE); //shared pref of App 1
//note: MODE_PRIVATE doesn't matter

String internalPincode = interalPref.getString("pincode", "none");
String externalPincode = externalPref.getString("pincode", "none");

In this case I get for internalPincode and externalPincode "none".

However when I change the order of getSharedPreference:

Context con = createPackageContext("com.mine.app1", 0);
SharedPreferences externalPref = con.getSharedPreferences("pincode", MODE_PRIVATE); //shared pref of App 1
SharedPreferences interalPref = getSharedPreferences("pincode", MODE_PRIVATE); //shared pref of App 2 (this app)

String internalPincode = interalPref.getString("pincode", "none");
String externalPincode = externalPref.getString("pincode", "none");

I this case I get for both internalPincode and externalPincode “dddd” (which is the value set in Application 1 (com.mine.app1))

I expect that internalPincode will return "none" and externalPincode "dddd" in both case.

Why doesn't it?

RvdK
  • 19,580
  • 4
  • 64
  • 107

1 Answers1

4

I have an application 2 (com.mine.app2) in which I try to read out the SharedPreference from Application 1.

This is not a great idea. The user can get rid of Application 1 whenever they wish, at which point Application 2 can no longer get at this data.

Instead, use a synchronization model. Have Application 1 send out a broadcast Intent when preferences change, with an attached signature-level permission so only Application 2 (or any others that you write) can receive it. Application 2 can then update its own local data store (e.g., its own SharedPreferences). Application 2 can do the same, allowing the user to modify its copy of the preference data and sending out the broadcasts to let the other application(s) know. That way, if any one application is removed, the other application(s) do not lose their preference data, yet everything can remain in sync.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    Thanks for pointing out the flaws in my answer. I've deleted it to prevent misinformation. – Raghav Sood Sep 14 '12 at 19:10
  • @CommonsWare: thanks for showing me another solution but this is not what I'm looking for. I was looking for a synchronous solution where I could easily look for a settings in an App of mine without creating a ContentProvider(because of overhead) or broadcast the data. I like to use this code as a 'Helper' class used in multiple projects. – RvdK Sep 17 '12 at 11:54
  • Hmm...the flaw with this solution is that Application 1 will never know about the changes made by Application 2, while Application 1 isn't running. App 1 will start up, read its own preferences and remain oblivious. I'm not seeing any way around having an external, shared file which both apps use to share preference data. – JamieB Nov 02 '12 at 15:11
  • @JamieB: "the flaw with this solution is that Application 1 will never know about the changes made by Application 2, while Application 1 isn't running." -- sure it will. As I state in my answer, App1 has its **own local copy** of the preferences, which **it updates when App2 broadcasts its changes**. See this project for a partial implementation: https://github.com/commonsguy/cw-omnibus/tree/master/Prefs/Sync – CommonsWare Nov 02 '12 at 15:17