7

Is there a way to access SharedPreferences across user profiles on Android?

For example if UserA makes a change to an applications preferences I want that change to be available to UserB as well. I've tried to use a text file written out to getFilesFir() path and read that from a different account but when userA writes a file, it's not available to userB. I write the files with MODE_PRIVATE since MODE_WORLD_READABLE and MODE_WORLD_WRITABLE are deprecated but I'm not sure using those would help to start with.

Does any one know if there is a way to centralize preferences for my application settings so that it can be shared across all users? I want to avoid writing anything out to the SD Card.

Ali
  • 12,354
  • 9
  • 54
  • 83
  • Did you ever get this working? I'm having the same problem – Tim Apr 21 '16 at 17:32
  • 1
    I ended up writing a file on external storage. I used facebook conceal to encrypt it. Worked like a charm, not the perfect solution, but it's secure. If you want to see the code I used, you can find it [here](https://gist.github.com/alphamu/87ca7bf57b5f9e6a0f84db93bef3b792). – Ali Apr 26 '16 at 01:26

4 Answers4

0

You can't. Only the SD card doesn't enforce user permission.

regisd
  • 151
  • 7
0

You might want to acquaint yourself with the rules in play when multiple users are added to a device in this doc, under the Effects section. It should be evident that what you're trying to accomplish will be a "creative workaround", or simply impossible.

So what Android facilities exist for apps to share data that are not a filesystem? Well, the usual mechanism is a ContentProvider, but I suspect that two sandboxed instances of an app can not access each others' ContentProviders (and besides, how would you tell them apart?).

Let's assume that user-instance apps simply can't access each other. Maybe they could share some system level facilities that are accessible by all apps all the time regardless of who is the active user? The only thing that occurs to me as I write this is DropBoxManager. Unfortunately it's not reliably persistent as there are limits to how much it can store, and those limits could cause your data to get pushed out of the queue at any time before it can be read by the other app instance. Also, the data there is essentially public, which may not be what you want.

If you want to get crazy, you can revisit ContentProviders and somehow make use of the system level providers for calendar or contacts to stash data, as long as both apps know how to locate the secret special record. Wild stuff.

Another solution might be to store all your data on some server, and have each user enter some key to be able to location and read/write your blob of data on the server. If not a manual key, try to use some "unique" device property as the key. This is probably the best solution as you have more of a guarantee that something will not accidentally delete or expose your data.

Community
  • 1
  • 1
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
0

Using getSharedPreferences() with MODE_PRIVATE should be enough. The only thing you need is to use application context. In that way your shared preferences will be available from all your Activities regardless of the current user.

String PREFS_NAME = "com.your_application";
Context context = getApplicationContext();

Read preference example:

SharedPreferences reader;
reader = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
reader.getInt("name1", 3);

Write preference example:

SharedPreferences.Editor writer;
writer = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE).edit();
writer.putString("name2", "string").apply();
toro
  • 19
  • 5
0

A solution would be to provide a content provider with custom permissions and define a protocol for saving and restoring preferences from this content provider.

Radu Ionescu
  • 3,462
  • 5
  • 24
  • 43