47

I've created an Android live wallpaper and i'm trying to let a user choose an image from their phone and apply it as a background image, but when I launch the activity that start the intent to pick the images, my shared preferences don't seem to save properly.

Below is my onCreate method of the activity I start when the users presses the preference button, and the onActivityResult which gets the path of the image on the device (all that seems to work). The println after I commit the preferences prints out nothing.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
    photoPickerIntent.setType("image/*");
    startActivityForResult(photoPickerIntent, SELECT_PICTURE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            selectedImagePath = getPath(selectedImageUri);

            preferences = getApplicationContext().getSharedPreferences(PREFERENCES_NAME, 0);
            preferences.edit().putString(SETTINGS_BACKGROUND_IMAGE, "okok");
            preferences.edit().commit();

            System.out.println("Image" + preferences.getString(SETTINGS_BACKGROUND_IMAGE, ""));
        }
    }

    finish();
}
jOE
  • 491
  • 1
  • 4
  • 5

5 Answers5

98

From the documentation:

Create a new Editor for these preferences, through which you can make modifications to the data in the preferences and atomically commit those changes back to the SharedPreferences object.

Since that's a new Editor instance, your code should be more like this:

preferences = getApplicationContext().getSharedPreferences(PREFERENCES_NAME, 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SETTINGS_BACKGROUND_IMAGE, "okok");
editor.apply();
Community
  • 1
  • 1
zrgiu
  • 6,200
  • 1
  • 33
  • 35
  • 27
    Am i the only one who can't see the difference in the logic between this and the original code? – josephus Mar 13 '12 at 03:47
  • 48
    when you call preferences.edit(), you get an Editor instance, on which jOE was putting a string, but after that, that instance was not longer used (thus lost, and possibly garbage collected). Then, jOE called preferences.edit() again, getting another Editor instance containing the initial settings, which he just saved in place. This basically just saved the initial settings (did nothing to update his shared preferences) – zrgiu Mar 13 '12 at 03:55
  • 1
    zrgui, thank you very much for your help! Your suggestion worked perfectly! – jOE Mar 13 '12 at 21:10
  • 2
    Thanks man, you saved my day. The behavior of shared preference described in the question is really confusing for me. – gmuhammad Aug 27 '14 at 15:28
  • Thanks! This issue was very hard to debug, especially when a lot of the answers just create an editor object but don't explicitly mention it. – Script Kitty Mar 14 '16 at 02:07
  • Is it possible to pass a object other than string inside sharedpreferences? – amit pandya Feb 12 '18 at 10:11
  • Would preferences.edit().putString(SETTINGS_BACKGROUND_IMAGE, "okok").apply(); not work just as well if you wanted to string the commands together? – Nic2352 Dec 26 '19 at 16:41
16

Try another way of initializing your SharedPreferences variable:

SharedPreferences sf = PreferenceManager.getDefaultSharedPreferences(this);

You can also chain writing to sf with sf.edit().putString(string, value).commit();

josephus
  • 8,284
  • 1
  • 37
  • 57
3

well, based on @zrgiu post, for me only worked adding editor.clear(); before use the Editor...so the final code will be something like:

preferences = getApplicationContext().getSharedPreferences(PREFERENCES_NAME, 0);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.putString(SETTINGS_BACKGROUND_IMAGE, "okok");
editor.commit();

;)

lienmt
  • 147
  • 8
0

In my case I had to add editor.apply(); before commit in order to work.

This is my code:

preferences = getApplicationContext().getSharedPreferences(PREFERENCES_NAME, 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SETTINGS_BACKGROUND_IMAGE, "okok");
editor.apply();//I added this line and started to work...
editor.commit();
Juan Pablo
  • 1,213
  • 10
  • 15
  • 11
    apply is to save the data a-synchronically while commit is to save it immediately, you should NOT use them both !!! – XcodeNOOB Dec 16 '16 at 07:58
0

Bear in mind that you need the same activity to save and retrieve data. You can not use a method like

public String readValue(Activity activity, String key) {
    SharedPreferences sp = activity.getPreferences(Context.Mode_PRIVATE);
   //...
}

For receiving the same data from the same activity you need to call this method with the exact same activity which you had saved your data.

Guchelkaben
  • 1,205
  • 1
  • 12
  • 18