What does Preference.setSummary() do? - android

In my code I've used the Preference.setSummary() method to change the summary line of a setting to a certain string. In my main activity when I need to retrieve this setting's value I call the getString(key) method on the SharedPreferences object, where key is the key of an EditTextPreference.
Now I really wonder if setSummary also sets the value of a preference in SharedPreferences by the same key to the value that I pass to setSummary, because I really never created a SharedPreferences.Editor object and called a putString method on it explicitly.
The docs don't say anything specific other than:
Sets the summary for this Preference with a CharSequence.
Parameters
summary The summary for the preference.
Reference

Firstly I'm sorry that I asked this question even though one of the next lectures in the course (by Google) provided the answer, but I think it was worth it as there existed no question on SO about Preference.setSummary() also saving values in SharedPreferences.
The answer is that when the summary is changed so is the value in SharedPreferences as quoted in this video by Google's official Android Course:
When the user selects an option, it's saved into SharedPreferences.
Providing some context, "user selects an option" refers to choosing an option in a ListPreference which is then set as its summary.

Related

How do I retrieve the preferences from my settings activity in Kotlin?

I am currently struggling with Kotlin for my Bachelor thesis and I have no idea what I am doing.
So here is my problem:
I created a (functional) settings activity with multiple EditTextPreferences and a ListPreference.
Right now I want to retrieve the selected item from the ListPreference in another activity.
This is my ListPreference:
<ListPreference
android:dialogTitle="Art des Implantates"
android:entries="#array/settings_list_preference_titles"
android:entryValues="#array/settings_list_preference_values"
android:key="list"
android:title="Implantat"
app:useSimpleSummaryProvider="true"/>
So how do I retrieve the selected Item? Let's say I just want to display it somewhere else. I have no clue whatsoever, since every single Tutorial I came across is for java and I don't speak java.
Please help me. I'm desperate.
Step #1: Get a SharedPreferences object for the default preferences:
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
(where context is a Context, such as an Activity or the Application singleton)
Step #2: Call getString("list", someDefaultValue) on the SharedPreferences, where "list" is your key (from your <ListPreference>) and someDefaultValue is a String that you want returned if the user has not yet set this preference
since every single Tutorial I came across is for java
This sample app (from this book) is in Kotlin and shows the use of SharedPreferences. The documentation also shows the use of SharedPreferences with Kotlin (and Java).
If you are using java:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
You can access values by using XML app:key="this_value" like this:
prefs.getString("this_value","some_val");

Android: PreferenceManager vs Context.getSharedPreferences() and why the latter failed me

ok, following the Udacity Android Development Course, I reached the part where I'm expected to access the postal code saved to a sharedPreferences file called pref_general.xml, which has the postal code saved in string type and connected to a key called location via key-value pair.
My approach to the problem was to use the getSharedPreferences() method to get the file by name. While that appears to not cause problems because the file didn't turn out null, the attempt to retrieve the postal code resulted in not finding the value via the key and settling on the given default value of the argument.
SharedPreferences appPreferences = getActivity().getSharedPreferences("pref_general", Context.MODE_PRIVATE);
if(appPreferences == null) {
Log.v("ERRORTAG", "Cannot get sharedPreferences file");
}
String getPostal = appPreferences.getString(getString(R.string.pref_location_key), "0");
Log.v("ERRORTAG", getPostal);
The 2nd verbose statement on logcat results in the default String value of 0 instead of the value tied to the given key of 94043 postal code.
Now the answer Udacity gave was to use PreferenceManager, which grabs the default lone sharedPreferences file tied to the Activity
SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
The file isn't null AND the retrieved postal code is the given default postal code 94043 set within the sharedPreference file as a key-value pair.
I want to understand why my approach wasn't working; it was quite close. The only difference was how the file was accessed. Please give me an explanation as to why. Thank you.
The docs for PreferenceActivity say:
If you are using PreferenceActivity in its old mode, the documentation [for PreferenceFragment] applies to the deprecated APIs here.
And the docs for PreferenceFragment explain what's happening:
To retrieve an instance of SharedPreferences that the preference hierarchy in this fragment will use, call getDefaultSharedPreferences(android.content.Context) with a context in the same package as this fragment.
This suggests that PreferenceActivity#addPreferencesFromResource(...) does not create a SharedPreferences file with the same name as the original. Instead, it merges the file into the default shared preferences. The pref_general file does not exist, and you're basically creating it when you attempt to read from it. (Though it's not actually created on disk until you edit it.)

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.

How can I force SharedPreferences to save?

As far as I can tell, values aren't stored in Android's SharedPreferences until they're explicitly accessed. That is, while they may have default values in XML, no value is placed in a SharedPreferences store until an accessor method is called, which is why all the accessors have "default" parameters included.
While this isn't a huge deal for simply pulling values out of the preference store, it prevents any attempt to get all the preference keys that are used in the application, even if they are stored in XML. The keys don't appear when SharedPreferences#getAll() is called unless the preference has already been explicitly accessed.
Is there any way to force all preferences defined in XML to be saved into a SharedPreferences store? The nearest solution I can find is to manually parse the Preference XML files, find all keys and defaults, and save the default value for each one. Is there a cleaner approach?
UPDATE
After looking at this in more depth, I've been getting a partial list of preferences for a different reason. When the defaults are set, only EditTextPreference and ListPreference values are saved. The other two, a custom preference and a CheckBoxPreference, are completely ignored. Here's an example of the CheckBoxPreference that's being ignored:
<CheckBoxPreference
android:defaultValue="false"
android:key="PREF_NAME"
android:summary="Summary text"
android:title="Title" />
Any idea why not all defaults are being set?
You can use PreferenceManager::setDefaultValues. For instance, at your Application::onCreate method.
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
If the last argument is false, this will only set the default values if this method has never been called in the past.
The reason for the missing preferences in my case was actually an Android bug. The workaround was to manually set the missing preferences to their default values, as indicated in a duplicate question: Android CheckBoxPreference Default Value

How to attach a Preference to a particular SharedPreferences?

I am working on implementing the preferences for our application. I know how to display preferences UI and how to read/write values using SharedPreferences. In our app, I need to handle two sets of preferences and I would like to ask about this issue, one comment in the Android documents in particular.
The documentation for Preference.getSharedPreferences() has the following comment under the Return values section:
Returns The SharedPreferences where this Preference reads its value(s), or null if it isn't attached to a Preference hierarchy.
I would like to ask how it is possible to attach a SharedPreferences to a particular Preference, be it EditTextPreference or others. In other words, how does the persistence code in a Preference know that it should store the user input in one particular SharedPreferences object and not the other?
To explain my question further with an example, suppose I have the following:
SharedPreferences prefs1 = getSharedPreferences(file1, mode);
SharedPreferences prefs2 = getSharedPreferences(file2, mode);
My question is what API I should use so that prefs1 is used by the Preference objects' persistence code and not prefs2.
The target is Nexus One, running 2.3.4.
Maybe the answer is obvious but I could not find it after reading the documentation and searching the web. Thank you in advance for your help.
In other words, how does the persistence code in a Preference know that it should store the user input in one particular SharedPreferences object and not the other?
Preference uses PreferenceManager's getSharedPreferences(), which eventually routes to getDefaultSharedPreferences().
You are welcome to create your own Preference subclasses that change this behavior, but since the preference screen system may not be designed to handle multiple SharedPreference objects, there's a chance that your preference changes might not get persisted.
IOW, I encourage you to reconsider:
In our app, I need to handle two sets of preferences

Categories

Resources