SharedPreferences will not save/load in PreferenceActivity
Asked Answered
C

8

14

EDIT: The problem described below was due to a very peculiar device issue not caused by any coding-related problem.

I have a preferenceActivity in which I have many checkBoxPreferences. The checkBoxPreference is suppose to save the the default shared preferences file, and then be called again when I open the app in order to update the UI.

This does not happen like it's suppose to. If I close the app and open it back up, my values remain like they are suppose to, but if I use task manager to end the app or if I power cycle the phone (when the app is not running) then the defaultValues are called again.

So, I created a SharedPreference in my onResume() to test it.

SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

I then check to see if there is a key in that sharedpreference.

pref.contains("myCheckBoxPreference");

When I close out and open it back up, it returns true. if I close with the task manager or power cycle the phone off and on, then that returns false.

So, I tried manually setting the SharedPreference

SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("myCheckBoxPreference", myCheckBoxPreference.isChecked());
editor.commit();

and then I called that when the checkboxpreference value changed. I also tried calling it in onStop and onPause. Still, if I close the app and open it back up, pref.contains returns true, but if I power cycle the phone off and back on, it returns false.

So I then tried using a SharedPreferences file.

In the class declaration:

public static final String PREFS = "prefs";

And in the onResume():

SharedPreferences pref = this.getSharedPreferences(PREFS, 0);

Same behavior, pref.contains still returns true if I just close the app and open it back up, but it returns false if I power the phone off and back on.

I then tried changing the key value of myCheckBoxPreference to something that did NOT match the xml key for the CheckBoxPreference, and it still had the same effect.

And I uninstalled the application from the phone, then powered the phone off and back on, and then re-installed, and it still has the same effect.

Chondriosome answered 27/6, 2011 at 23:55 Comment(4)
I would be interested to see the output of logcat while you are testing this, an exact test case written entirely in onCreate that simply opens the preferences and saves a value, then reads it back the next time you start the program, and what the contents of your MYPREFS constant is. Are you really not able to read the preferences back, or are they simply not appearing in the DialogPreference GUI when you launch your PreferenceActivity subclass?Sabian
Well, I would post that, but I'm really new to android and honestly don't know how to use the logcats, and I just make Toast notifications to tell me if things are right. (and I feel that's more useful anyway, because I can easily view toasts while the app is running. But, with the toast notifications, it says the boolean value is false, when I previously saved it as true. And that happens when toasting from the main activity and from another activity that calls the sharedpreference. And it doesn't seem an issue with GUI updating because it works before power cycling the phone.Chondriosome
Observing the same behaviour on Android 2.3.7. I have noticed though that it is enough to rotate the device, so that the activity is destroyed and onCreate fires once again with the new preferences.Fiorin
@jakar add lines like Log.d("prefstest", "Pref == " + pref); after you've loaded the settings, and it will drop the data to the logcat output in Eclipse. Its also readable by typing adb logcat on a terminal window. Very handy.Choragus
C
7

I just solved it, I'm pretty sure. There's no code error on my part, and there is no issue with my app whatsoever (I don't believe, anyway.)

I created a new project called "testproj", then I copied ALL the code from my settings PreferenceActivity, pasted it into the TestprojActivity, and I copied the code from the xml it relied on, then pasted that into the main.xml of TestProj.

I then installed TestProj on the Samsung Captivate, changed the settings around, cleared the ram through RAM management (a function of the custom ROM I have), and the settings stuck. I then power cycled the phone and the settings were still there like I'd configured them.

They stayed both when I manually set them using:

PreferenceManager.getDefaultSharedPreferences();

and without manually saving them to the SharedPreferences.

Since it is not my phone, I haven't tried it yet, but I assume a Factory Data reset would fix it completely EDIT: I was able to test on both a new Samsung Captivate and a Samsung infuse, and it worked.

I wasted a lot of my time trying to figure this out, and I hope it helps someone else. :)

Chondriosome answered 1/7, 2011 at 23:19 Comment(3)
Sounds like Paul's answer below is relevant.Spreader
I wasn't aware that the Samsung Captivate is a Samsung Galaxy S variant. It seems like David Caunt is right about it being an issue on that model.Cronk
8 years later, and I just wasted a good few hours wondering what was wrong with my code... turns out it was just a problem with the deviceAmyamyas
C
6

I encountered a possibly similar problem on a Samsung Galaxy S, where the permissions for the preferences XML file had somehow changed/corrupted.

The log revealed some host process was failing to read the file, causing all the settings to reset to their defaults. I don't recall the exact error message, but it was along the lines of "permission denied for /path/to/preferences/file.xml".

The resolution for me was to delete the application data through Settings, Applications, Manage Applications, MyApp, Delete data. This deletes the preference file associated with the app and the problem instantly disappeared.

I assumed it was an isolated event, as I've not run into it again on a variety of Android devices (including the Galaxy S II).

Cronk answered 1/7, 2011 at 23:26 Comment(6)
Odd thing is, when I go to manage applications, "Delete Data" was grayed out AND "Data.......0.00B". The same exact thing is happening for TestProj, but the phone is getting replaced within the next week so I will be able to test it for real soon.Chondriosome
A common issue on the Galaxy S I believe - a bug where the preference permissions are corrupted. I've had a few users report it.Spreader
@David-Caunt Good to know that; I was worried I was doing something foolish.Cronk
I've seen it reported on a few forums, and reinstallation usually fixes it. No word from Samsung but their code has been slated by many developers.Spreader
I had a user w/ a similar issue on a Samsung Infuse getting this error : Attempt to read preferences file /dbdata/databases/com.munzee.android.client/shared_prefs/MunzeePrefs.xml without permission. I tried to change the MunzeePrefs.xml file name to be the UID, but it looks like the permissions are set on the FQN in the path.. Any suggestions on how to fix this? Uninstalling/reinstalling the app is not working. Suggested the only solution to user may be factory reset. Any idea where to report bugs to Samsung?Enteron
The only thing that comes to mind is rooting the phone and manually deleting the file manually.Cronk
R
3

On the client's main test device I came across the very same issue. The Device used is a Samsung Galaxy S with SDK level 8 (2.2.1).

The strange behavior is that either SharedPreferences are not saved, or, as after a factory reset, they're too persistent, that is to say they are not deleted after having reinstalled the application.

Due to the current distribution of 2.2.x, and the number of Samsung Galaxy S devices sold being several millions, the probability of an occurrence of this issue is significant.

So it can be considered as crucial to implement a workaround for saving preferences.

For collecting detailed characteristics to isolate this workaround in a sharp-edged way, could everyone who is also facing that issue please provide the corresponding kernel version (System.getProperty("os.version") here?

I was thinking of something like this:

// !! I know that 2.6.32.9 is not yet correct. This would be a false positive !!
if ((System.getProperty("os.version").startsWith("2.6.32.9"))
    && (android.os.Build.DEVICE.contains("GT-I9000")))
    useInternalStorage();
else
    useSharedPreferences();

I can post the real code here also once it's ready and someone is interested.


EDIT: some additional information:

Devices facing that issue:

    Property                         | Values
    ---------------------------------+------------------------------------
    Build.DEVICE                     | "GT-I9000T"
    Build.VERSION.INCREMENTAL        | "UBJP9"
    Build.VERSION.RELEASE            | "2.2.1"
    Build.VERSION.SDK                | 8
    System.getProperty("os.version") | "2.6.32.9"
    

Similar devices NOT facing that issue:

    Property                         | Values
    ---------------------------------+------------------------------------
    Build.DEVICE                     | "GT-I9000"
    Build.VERSION.INCREMENTAL        | "AOJP4"
    Build.VERSION.RELEASE            | "2.2"
    Build.VERSION.SDK                | 8
    System.getProperty("os.version") | "2.6.32.9"
    
Repudiate answered 26/9, 2011 at 12:16 Comment(1)
The device I use now works, but on your test device, if you call editor.clear().commit() to clear all values for that pref file, then do values save successfully? Also, what happens if you change it so the prefs file just has a different name? I didn't think to try these steps previously, and I no longer have a malfunctioning galaxy s.Chondriosome
I
3

Try clearing the editor before you set your values. I had the same problem and it worked for me. Example:

Editor e = PreferenceManager.getDefaultSharedPreferences(getParent()).edit();
e.clear();
e.putStringSet(key, value);
Impel answered 22/9, 2013 at 21:35 Comment(1)
Thank you for the input, but the issue I was having was actually a device problem. There is no reason why the problem I described would exist outside of it being a device or OS error. Also, you should not have to clear() in order to write new values, unless you're just trying to set your app back to it's default state.Chondriosome
E
0

It is possible to work around the issue of permissions by using sharedUserId which should be the same for any of your signed apps.

http://developer.android.com/reference/android/R.attr.html#sharedUserId

Enteron answered 9/11, 2011 at 18:1 Comment(0)
A
0

I too had a problem with saving and then retrieving data. I had my Save and Load code in a class that extends Application because I wanted a single instance of my data. I could see the String being saved, no errors in LogCat and yet when I try to load it, again with no error, my String is empty. I never checked whether the data actually went into the file so I have no idea whether there was a failure on Save or Load or both.

My code was more or less as follows: (comboToSave is simply a string generated by Gson from a simple data class)

in one method to save:

  SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE); 
  SharedPreferences.Editor editor = sharedPref.edit();
  editor.putString(getString(R.string.prefCombos), comboToSave); 
  editor.commit();

in another method to load:

  SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
  String loadedComboText = sharedPref.getString(getString(R.string.prefCombos), "");

After lots of head scratching and not knowing what to do I changed the code that retrieves the sharedPref value from

SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);

to

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

There is some more here on the difference between the two (although in my case it seems exactly the same)

Still the result on my Galaxy S3 was the same. However, testing both versions on other devices, including VDs (virtual devices) worked.

In the first version of the code I passed the Activity from the calling activity; for save from the activity where the final bit of data is collected from the user, and for loading from my main activity so that I had it ready when the app is started.

I played with uninsalling the app and re-intalling, turning the device off and on again last night to no avail.

I have now moved the save and load methods from the application class to the activity where I complete the input i.e. both load and save code is now in the same activity. I have tested this with both variations of the code and they both work. I get back what I save. I then moved all the code back to the Application class and it works; this leads me to believe that somehow with all the installing/uninstalling I somehow managed to get it working. Point is: the code is correct - if it does not work the device and/or settings are probably to blame

Adoree answered 16/7, 2013 at 11:35 Comment(0)
T
0

I have the same problem, and i suffered from it for a while , finally i found the solution , and it is so easy , just pass the direct reference of the activity , and do not use any general context

public SessionManagment(Activity mContextActivity){
//  this.contextActivity = mContext;
    sharedPrefSession =  mContextActivity.getSharedPreferences(
            Constants.SHARED_PREFERANCES_LIGHT_TIGER_SESSION_FILE_NAME, 
            Context.MODE_PRIVATE);

}//enden constructor 

the code above is the constructor of the class that i have written for session management , and and when i call it in the code in the main ActivityFramgment in a AsyncTask i call it like this

SessionManagment sessionManagment = new SessionManagment(referanct2thisActivity);

where referanct2thisActivity is defined in "onCreate" function of fragment activity like this

referanct2thisActivity = this;

hope that will help others in the future

Thaumatology answered 22/8, 2013 at 7:51 Comment(1)
I appreciate your help, but the actual issue in my case was due to a faulty device.Chondriosome
P
0

Had similar problem. Maybe because of renaming package name and project name. After finding this thread I tried to change the preferences name. For example:

SharedPreferences prefs = getSharedPreferences("myprefs", MODE_PRIVATE);

to

SharedPreferences prefs = getSharedPreferences("mynewprefs", MODE_PRIVATE);

then it worked again!

Perfumery answered 15/5 at 6:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.