I can read and write shared preferences and have verified that the resulting XML file looks correct. But is it possible to build a hierarchy of preferences instead of just a flat list?
I'm accessing the preferences directly from my code, so the solution must not assume a preferences screen is present in the app. I have found the PreferenceGroup, PreferenceCategory, and PreferenceManager classes, but they seem to assume a preferences screen is present.
But is it possible to build a hierarchy of preferences instead of just a flat list?
No, sorry. From the rest of your question, it's unclear why you are using SharedPreferences in the first place, instead of another persistent data model (database, XML file, JSON file, etc.)
Related
The Android documentation describes how to create a "preferences" UI using either a PreferenceActivity or a PreferenceFragment. The preferences themselves are defined in a XML file (e.g. preferences.xml) which contain, among other things, the "key" (android:key) to use to store each preference in the app's SharedPreferences.
This is good for apps which have a single set of preferences. However let's assume that there is an app that can have multiple "items" (for example: multiple account in a video chat app), and needs to show a preferences screen for each account.
How can this be done? Is it possible to specify the keys at runtime (so that e.g a different prefix can be used for each account)? Is there a better way to approach this?
Yes, its possible!
you can assign keys on Runtime like, but as you said in comments that you need to change the Keys of the pre-defined Preferences in Xml rather than creating new Preferences explicitly, here's a method -
Preference pref = findPreference("my_pref");
String myPrefix = "prefix_";
pref.setKey(myPrefix + pref.getKey());
In my application I am trying to add support for different profiles. Each of these profiles can have their own independent Preferences, configured from a deep tree of custom and stock preference objects.
I thought that I could add this easily by using different Preference Files per profile, as in getSharedPreferences("george", MODE_PRIVATE); would store them for profile "george".
The issue I am having is the Preference objects seem to be storing their values in the default Preference file. Is there any way from my Activity or Fragment to change which Preference file is used by the Preferences on my Preference Screen? I know this doesn't exist, but I'm looking for something like .setPreferenceFile(String filename) for a Preference or PreferenceGroup.
Any help or suggestions to minimize the work to support independent profile preferences will be appreciated..
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"
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
My application is used on multiple platforms so it saves it preferences to a file (rather than to the standard Android SharedPreferences).
Is there any easy of reusing the PreferenceActivity to save preferences to a file or is it a case of creating a whole new activity to do the job? If the latter is the case is there a layout I can use that will make the activity look like the normal preferences screen? PreferenceActivity uses com.android.internal.R.layout.preference_list_content but this doesn't appear to be available to apps for reuse.
Is there any easy of reusing the
PreferenceActivity to save preferences
to a file or is it a case of creating
a whole new activity to do the job?
Not really. I mean, you could subclass SharedPreferences, rip the guts out, and map it to your own data model, but that would be far, far worse for maintainability than just using SharedPreferences in the first place.
If the latter is the case is there a
layout I can use that will make the
activity look like the normal
preferences screen?
It's just a ListView. It will take you a lot more time to do this than to just use SharedPreferences.
PreferenceActivity uses
com.android.internal.R.layout.preference_list_content
but this doesn't appear to be
available to apps for reuse.
Sure it is. If you have the SDK installed, it's on your hard drive right now. Look in $ANDROID_HOME/platforms/$API/data/res/layout, where $ANDROID_HOME is where you have the SDK and $API is some API (e.g., android-2.1).
You can create a function that exports the data from SharedPreferences to a file.
Normally Preferences are saved into sharedpreferences when the user clicks on the prefrence item. Add your code to update your external dataholder on onPreferenceTreeClick() function.