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).
Related
I want to get some key-values throughout my application, in iOS we have user-defaults, how can we make preferences behave like that i.e. accessible from any activity?
You can create a new shared preference file or access an existing one by calling one of these methods:
getSharedPreferences() — Use this if you need multiple shared preference files identified by name, which you specify with the first parameter. You can call this from any Context in your app.
getPreferences() — Use this from an Activity if you need to use only one shared preference file for the activity. Because this retrieves a default shared preference file that belongs to the activity, you don't need to supply a name.
For example, the following code accesses the shared preferences file that's identified by the resource string R.string.preference_file_key and opens it using the private mode so the file is accessible by only your app:
Context context = getActivity();
SharedPreferences sharedPref = context.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE);
You can read the official guide on Save key-value data.
Edit: The provided "duplicate" doesn't solve my question as it doesn't fully answer my question. (Info about the second parameter is missing).
This question is intended to clear out the information for new Android developers and not to solve my own problem. Please reconsider the downvotes.
So, here's the method:
getSharedPreferences(string, Context.MODE_PRIVATE);
I can't really get what the first parameter does. What does it do? Why is there a first parameter if when we save something to SharedPreferences we use a key?
As documented in the Android Developer Documentation for getSharedPreferences(), the full signature for the method is:
SharedPreferences getSharedPreferences (String name, int mode)
The formal signature provides the name of the first parameter, name, which is information useful to the answer. The name parameter is the base name (without file extension) of an XML preferences file located in the private storage of the app.
For example, this call will return the SharedPreferences instance to allow reading and writing the app's settings.xml preferences file:
SharedPreferences sharedPrefs = getSharedPreferences("settings", Context.MODE_PRIVATE);
As indicated in the official documentation, the returned SharedPreferences object is a single-instance object, shared between all callers for the same file name. This means that a given call does not necessarily imply file IO to read a given preference, but may incur thread synchronization between threads in the same app.
The specified file will be created if it doesn't already exist prior to calling getSharedPreferences(). The second argument, mode, is the mode to use when creating the file, and should be set to Context.MODE_PRIVATE (or it's integer value 0); other mode values are not documented as allowed, and should not be used. As when creating any file, indicating a mode of Context.MODE_PRIVATE will locate the file in the app's private storage, as is expected for use with getSharedPreferences().
An example of writing a value (999) to a key (setting) in a SharedPreferences instance is this:
Context context = getActivity();
SharedPreferences sharedPrefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putInt("setting", 999);
editor.apply();
Reading the value from the same key is done this way:
Context context = getActivity();
SharedPreferences sharedPrefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE);
sharedPrefs.getInt("setting", 0);
Additional usage information can be found in the Saving Key-Value Sets page in the Android Getting Started Guide.
Note that getSharedPreferences() is a generalized version of getPreferences(), which is often the better choice for common application preferences. Aside from the ability to specify which preferences file to use with getSharedPreferences(), both methods are otherwise identical in function and behavior. According to the getPreferences() documentation, it simply calls getSharedPreferences() with "this activity's class name as the preferences name" (the first parameter to getSharedPreferences()).
The String parameter in getSharedPreferences() is the file name that stores the keys and values that you provide. For example:
SharedPreferences.Editor s = getSharedPreferences("Pref",Context.MODE_PRIVATE).edit();
s.putInt("someKey",0);
s.apply();
Will make an output file in your app, called Pref, which contains the keys you'll enter.
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.
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