SharedPreferences overwrite other value - android

I have a problem with the SharedPreferences If I want to save two different values. I tried with this code:
SharedPreferences sharedPref = getSherlockActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.SavedStartSilentHour), hour);
editor.commit();
editor.putInt(getString(R.string.SavedStartSilentMinute), min);
editor.commit();
// One editor.commit() is enough
If I run this code the first value is overwritten with the seccond value. If I delte the second part the value is saved correctly. Why is that?

Your code seems perfect!
You could simplify the thing by committing all the stuff after all the "puts" operations. Although I don't think that this could be your problem...
Just make sure SavedStartSilentHour and SavedStartSilentMinutes xml's defined values are correctly defined, i.e., if they are the same of course they will be overwritten. (This is the only one thing that makes any sense to me considering your code).
Let mew know of your progress ;)

Remove first call to
editor.commit();
and you will be fine.

The issue is most likely caused by re-using a key such that the second assignment simply overwrites the same-keyed value.
One way to test this hypothesis is to try using simple keys which eliminate such possibility, e.g.:
editor.putInt("hour", hour);
editor.putInt("min", min);
Alternatively, a debugger can be attached and the results of getString(keyId) can be compared.
If this does indeed "fix" the issue, then ensure that the SavedStartSilentHour and SavedStartSilentMinute resources actually evaluate to different strings - inspect the resource file itself.

Related

Android, sharedPreferences automatically remove the list of the unused preferences when upgrading an application

My app have had many releases and some of the earlier version sharedPreferences are useless.
What would be the best way to have the app itself sorting out the one that are still used and remove the unused one ?
Basically it would be like parsing the preferences XML's to extract the current android::key and by getting all preferences present on the device remove the one not being anymore in an XML.
Not sure I am very clear, but I have lot's of shared preferences not used anymore and having to establish the list manually can be source of problem.
Any hint would be great,
Thanks a lot
you can go through the keys one by one removing any that you dont use anymore like this
Map<String,?> prefs = pref.getAll();
for(Map.Entry<String,?> prefToReset : prefs.entrySet()){
if(prefToReset.getKey().equals("someKey")){
pref.edit().remove(prefToReset.getKey()).commit();
}
}
though there really is no performance benefit from doing this really

Saving Shared Prefrences in Multiple instances

I would like to be able to save my users session or sharedPrefrences in a way that if the user kills the application and you start it it would look like this.
Button one = Start Activity with Blank Preferences
Button Two = List of Saved Sessions of Preferences and once clicked all put into the Starting activity.
Is this possible and if so how would I go about doing that?
Thank you!
Yes you can do that and it is good to use sharedPreferences if you just have to store some session variables. But if it is more, then go for database.
Do clear sharedPrefences in your application you need to do this:
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity);
Editor editor = settings.edit();
editor.clear();
editor.commit();
For reading the preferences, you can keep a sharedPreference with the count for the seesions. While saveing the prefences, always save with the strings session1, session2, session3 etc. So, while accessing them based on count, prepare a loop and form the string and access all the session variables and show them.
The reason why I didnt suggest you to do getAll() for sharedPreference is that, you may save few other things in sharedPreference. So by forming strings yourself, while reading you can just get the sessions and not other data saved in sharedPreference.
I hope you understand what I meant
Is this possible
I would say yes, depending on exactly what you mean.
if so how would I go about doing that?
SharedPreferences has a couple different functions to do something like this, depending on exactly what you want. You can get a Map of all preferences that are stored after clicking Button2 with getAll() or a set of preferences with a certain String such as "userName" or something similar with getStringSet(). Play around with the functions it offers and see if it gives you what you are looking for.
Also take not of the warnings of these functions
Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.

Initializing Preferences

Android Guide recommends defining preferences in XML files, And from there, these can be loaded in PreferenceActivity/PreferenceFragment etc for viewing and editing by user. But in real scenario, User Interacts with other activities first, then (maybe) with Preferences UI.
What if the starter activity needs some of these preferences ? They'll be not loaded yet, because preferences resources has not been inflated yet. Is there a way to pre-access preferences in XML files ?
Yes. When you first request the preference you can provide it with a default value. E.g. if you are loading a preference of type Int, then you can do so in the following manner from an activity:
SharedPreferences defaultSettings = PreferenceManager.getDefaultSharedPreferences(this);
int preferenceValue = defaultSettings.getInt("PreferenceName", 7);
This would load your preferenceValue to be 7 (without this preference ever being initialized yet). This is assuming that in your XML preference file, you have a preference of key "PreferenceName". If you plan on editing this preference in the activity before the Preference activity has been ran, be sure you commit your changes with a SharedPreferenceEditor:
// ... change to preferenceValue occurs prior to this code
SharedPreferences.Editor defaultEditor = defaultSettings.edit();
defaultEditor.putInt("PreferenceName", preferenceValue);
defaultEditor.commit();
We probably want to avoid "PreferenceName" in a hardcoded matter though, and instead use it as a string in the strings.xml file. This way it can be grabbed both from the initial code when the preference has not been saved yet and from the Preference XML file as well. This means that our above code would substitute the string "PreferenceName" with something like the following:
getResources().getString(R.string.pref_name)
And in your Preference XML file you may would reference the key in the following way:
android:key="#string/pref_name"
android:defaultValue="7"
This should cover "pre-loading" the preference as well as trying to keep most of the application settings within one place. There may indeed be overlap in terms of whether or not the XML preference was created/loaded before the initial Activity occurred, but I haven't tested that out yet.
EDIT: It turns out instead of using the above code, you can directly load the XML file (with its default preference) by the following method:
PreferenceManager.setDefaultValues(this, R.xml.preference, false);
More information about this method can be found in the documentation for the PreferenceManager: http://developer.android.com/reference/android/preference/PreferenceManager.html
If you look at SharedPreference API, you will see this
getString(String key, String defValue)
So, you can actually in fact define a default value if it's not already existed.
Source: http://developer.android.com/reference/android/content/SharedPreferences.html
You can also predefine default value in XML using
android:defaultValue="SOMETHING"

Parsing XML one time only on 1st startup

I'm currently using a Parser and it parses every time the onCreate gets called.
My parser uses an XML file that's located in my assetfolder.
Is there any chance that I can make it parse only once, instead of every time I rotate the screen or restart the application?
Thank you :)
There are 2 answers to this question. The easy one first:
If you only want this to happen once, create a static boolean in your main activity and set it to true when the XML is parsed in. Then use:
if(!isParsed)
XML.parse();
The more complete answer to this question is to make sure you are handling configuration changes correctly.
I suggest you read this article on how to implement configuration change handling. You should be able to solve this problem "the Android way" by implementing this.
Hope this helps!
Persist a flag using the Preferences system the first time you complete a parse, and check this each time before parsing again. Do all this in your OnCreate() method.
SharedPreferences settings = getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
if (!settings.getBoolean("parsed", false)) {
parseTheXML();
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("parsed", true);
editor.commit();
}
There are other ways but this has the advantage of working across app reloads/phone power cycles - assuming that's what you want.
You could add a preference. Something like -
void setIsAppOpened() {
editor.putBoolean(APP_OPENED, true);
editor.commit();
}
Set it in your onCreate(). Then, also add the following code to check if the preference exists.
if (!prefs.contains(APP_OPENED))
{
//parse the XML
setIsAppOpened();
}
You can parse your XML in a "Application" object and have it accessible from there. Check out the documentation at http://developer.android.com/reference/android/app/Application.html

Preferences Not Saved in DialogPreference

My problem is the following: I have a component that extends DialogPreference. If I change the associated preference from outside the UI...
SharedPreferences.Editor ed= sharedPreferences.Edit();
ed.putInteger("Setting",aValue);
ed.commit();
...then, when I open the dialog the selected preference has not changed. Even if the shared preference value is modified, it still contains the previously set value.
Does anyone have any idea what could be causing this?
This has probably been solved long ago, but just in case....
Some ideas for things which might be causing the problem:
The 'SharedPreferences' you are writing your value in might not be the same you are reading from. You can test this by getting the value from the SharedPreferences and printing it (On Log or via a Toast) just after calling commit() on the dialog. If you see the modified variable, you might actually be opening a new 'SharedPreferences' on the dialog, instead of the one you use on the calling activity, or
You might be rewriting the default value again after your dialog. For example, IF onResume() or other function is being called just after closing the dialog, and if the default value is written there. I think this is unlikely, but might be something else to consider if you are sure that you are writing to the right 'SharedPreferences'.
The function you are using when you write the variable might be wrong.... It is not clear to me how this would go undetected by the compiler or not fail otherwise, but as I see in the documentation for SharedPreferences.Editor, the function for writing an Integer value could be putInt(String key, int value) instead of putInteger(String key, int value).
You might be reading or writing the wrong variable.... This might happen if you copy-pasted the putInt command and left the wrong key or the wrong value. This is the kind of mistake that goes undetected for a long time, but it.... I guess it happens. A mistake with similar effect would be having a typo on the key (Two different keys for reading and writing).
Without the real code I think there is not much more I can suggest... But I hope this can somehow be of help to anyone getting to this question.
Regards.

Categories

Resources