1) What is the difference between
PreferenceManager.getDefaultSharedPreferences(context)
and
getSharedPreferences(name, mode)
2) And what does each of them do?
3) And how can I make a setting screen (Activity)?
1) You can have multiple SharedPreference files (so they are called SharedPreferences). The argument name of method getSharedPreferences(name, mode) specifies the the name of SharedPreference file to handle.
PreferenceManager.getDefaultSharedPreferences(context) returns the default SharedPreference file having default name and mode. Default name is based on your app's package name (as packagename_preferences.xml) and default mode is MODE_PRIVATE.
If you just want to use a single SharedPreferences file, PreferenceManager.getDefaultSharedPreferences(context) is concise to use.
2) With SharedPreferences you can save some key-value data.
3) Your last question: how to make a setting screen? is too wide topic to answer here. However, I suggest that using PreferenceActivity or PreferenceFragment you can manage a SharedPreferences without handling SharedPreferences directly.
Related
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 have a preference screen where I can change some settings.
In the code I can edit them via the shared preferences without a problem.
I have 2 questions:
- do these settings stay saved somewhere when the phone restarts?
- can I insert other settings into the sharedprefs. I mean settings that are not declared in the preference screen.
do these settings stay saved somewhere when the phone restarts?
Yes they are persisted in an xml file on the device.
can I insert other settings into the sharedprefs?
Yes you can have lots of settings in sharedprefs, the only ones that are displayed or modified through the PreferenceActivity are those you set in your layout file and their keys will be the keys specified in the layout file.
As stated before, SharedPreferences are persisted (written into an xml file) so they will always be available even if you restart (so long as you call commit() on the Editor belonging to the SharedPreference).
As far as inserting other settings into the sharedprefs,
You can actually have multiple SharedPreferences (in different files) if you want to be more organized, but you can definitely save anything you want in them.
To get the default shared preference for the activities context:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
To get one of many SharedPreference that you created, use this:
SharedPreferences prefs = context.getSharedPreferences(String name, int mode)
name being the name of the file
mode being MODE_PRIVATE, MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE, MODE_MULTI_PROCESS depending on how you want other applications to be able to access your apps prefs which can be useful
In my app, I use a PreferenceActivity framework to store persistent data. My intent is to create multiple save files, all of which may be accessed by the Preferences, but only one at a time.
When is it better to use a private file generated by Context.openFileOutput() and when is it better to use SharedPreferences?
EDIT
My data exists solely in primitives.
Normally developers use a preference file that is common to an entire app using getDefaultSharedPreferences.
However, Android has a getSharedPreferences(String name, int mode) method in Context. You could use this to have multiple preference files, in your case - save files, by using unique names passed into the name parameter.
Regarding volatility, you can force the preferences to save by getting an Editor via edit() and then calling commit().
Make sure to note that the SharedPreferences will indeed be shared based on the name:
Retrieve and hold the contents of the preferences file 'name', returning a SharedPreferences through which you can retrieve and modify its values. Only one instance of the SharedPreferences object is returned to any callers for the same name, meaning they will see each other's edits as soon as they are made.
Which of the following is/are appropriate for saving the state of an Android application?
a. Activity.onFreeze()
b. Activity.onPause()
c. Activity.onStop()
d. Activity.onDestroy()
e. Activity.onFinish()
Many applications may provide a way to capture user preferences on the settings of a specific application or an activity. For supporting this, Android provides a simple set of APIs.
Preferences are typically name value pairs. They can be stored as “Shared Preferences” across various activities in an application (note currently it cannot be shared across processes). Or it can be something that needs to be stored specific to an activity.
Shared Preferences: The shared preferences can be used by all the components (activities, services etc) off the applications.
Activity handled preferences: These preferences can only be used with in the activity and can not be used by other components of the application.
Shared Preferences:
The shared preferences are managed with the help of getSharedPreferences method of the Context class. The preferences are stored in a default file(1) or you can specify a file name(2) to be used to refer to the preferences.
(1) Here is how you get the instance when you specify the file name
public static final String PREF_FILE_NAME = "PrefFile";
SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
MODE_PRIVATE is the operating mode for the preferences. It is the default mode and means the created file will be accessed by only the calling application. Other two mode supported are MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE. In MODE_WORLD_READABLE other application can read the created file but can not modify it. In case of MODE_WORLD_WRITEABLE other applications also have write permissions for the created file.
(2) The recommended way is to use by the default mode, without specifying the file name
SharedPreferences preferences = PreferencesManager.getDefaultSharedPreferences(context);
Finally, once you have the preferences instance, here is how you can retrieve the stored values from the preferences:
int storedPreference = preferences.getInt("storedInt", 0);
To store values in the preference file SharedPreference.Editor object has to be used. Editor is the nested interface of the SharedPreference class.
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference); // value to store
editor.commit();
Editor also support methods like remove() and clear() to delete the preference value from the file.
Activity Preferences:
The shared preferences can be used by other application components. But if you do not need to share the preferences with other components and want to have activities private preferences. You can do that with the help of getPreferences() method of the activity. The getPreference method uses the getSharedPreferences() method with the name of the activity class for the preference file name.
Following is the code to get preferences
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
int storedPreference = preferences.getInt("storedInt", 0);
The code to store values is also same as in case of shared preferences.
SharedPreferences preferences = getPreference(MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference); // value to store
editor.commit();
You can also use other methods like storing the activity state in database. Note Android also contains a package called android.preference. The package defines classes to implement application preferences UI.
To see some more examples check Android's Data Storage post on developers site.
Why won't you just use SharedPreferences?
Anyways: i'd store the data in onPause(), depending on what these data items are. You probably already know that all items that have an id assigned in the R.java are automatically saved onPause() and restored onResume()? - but this is more or less useless anyways since this data is lost after the app dies completely...
assuming that you want so save other stuff that you might want to write to an DB or file, onPause() might be a good choice. as you can see in http://xenonite.net/news/android-activity-lifecycle, after onPause() is called, the OS might kill the app if there's memory needed for other things. so the data will be lost if you'd try to save it somewhere else (e.g. onStop())
but: make sure, that this saving produces not too much overhead, since onPause() is called on several occasions (e.g. screen rotates...)
When you createa a PreferenceScreen on Android, your application creates a default SharedPreferences file for the settings.
I want to read this name, or get a reference without specifing the name.
Currently I use:
SharedPreferences prefs = ctx.getSharedPreferences("prefs", 0);
SharedPreferences.Editor ed=prefs.edit();
But this returns another copy of the preference. When I checked the folder in /data/data/myapk/shared_prefs
I see two files, one named prefs.xml and the other is my [package name]_preferences.xml (this was created by the PreferenceActivity);
How do I get an instance of the shared preference with the usage of the default file name, so I should not mention a name for it?
I'm fairly sure you want PreferenceManager.getDefaultSharedPreferences(Context context).