5

I'd like to save user preferences from a sketch running either on a PC or an Android phone, using the same code in as standard "Java-way" as possible.

Ideal candidate for my purposes seems to be the java.util.prefs.Preferences class. So, I wrote a little test script to see if it's working in processing:

String prId = "counter";
Preferences prefs = Preferences.userNodeForPackage(this.getClass());
int counter = prefs.getInt(prId, 0);

println(counter);
prefs.putInt(prId, 1+counter);

This program outputs an increasing number each time it is executed - on a PC. On Android, the default value (0) is always shown. Are there any additional steps required to get this working on Android? Permissions to be requested? Are there any alternatives for saving name - value pairs on both platforms?

Obs.: "WRITE_EXTERNAL_STORAGE" permission is already enabled

user1352652
  • 425
  • 1
  • 8
  • 21

2 Answers2

2

This is a known Android bug unfortunately: https://code.google.com/p/android/issues/detail?id=22232

Basically the app does not have write permissions for the generated path, which should be a system-specific location where the user has write permissions instead.

Simplest (cross platform) workaround could be to use java.util.Properties, where you have control over the storage location.

Another workaround (if you are tied to the Preferences API for some reason) might be to provide your own implementation of AbstractPreferences (perhaps backed by Android SharedPreferences?), see this SO post: Is there a way to use java.util.Preferences under Windows without it using the Registry as the backend?

P.S.: Another workaround option might be to explicitly export / import the data using Preferences.exportSubtree(OutputStream os) and Preferences.importPreferences(InputStream is)

Stefan Haustein
  • 18,427
  • 3
  • 36
  • 51
0

In Android, the preferred way to store preferences is to make use of SharedPreferences. The equivalent code would be like this:

String prId = "counter";
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int counter = prefs.getInt(prId,0);    // Get int, default is 0

SharedPreferences.Editor prefsEditor = prefs.edit();
prefsEditor.putInt(prId, counter++);    // Put counter back
prefsEditor.commit();    //Don't forget to commit the changes

I don't know exactly why java.util.prefs.Preferences would fail in Android. I suspect the reason is data would be deleted after the current Activity or the application is destroyed.

Because directory structure is different on each platform, it's hard to get preferences by just using one single same method. For example, data is stored in /.java/.userPrefs/**yourpacakgename**/prefs.xml on Android while it's in Registry on Windows and in ~/Library/Preferences/**yourpacakgename**/prefs.xml on Mac OS X. Also, you can't use Preferences.userRoot() in Android because an application cannot get root access.

Stefan Haustein
  • 18,427
  • 3
  • 36
  • 51
Aaron He
  • 5,509
  • 3
  • 34
  • 44