Mess with the shared preferences of android - which function to use? - android

Here's a standard task: store some values in the application's shared preferences in order to be able to retrieve it later on.
But one will discover that there are 3 functions to store a value in there:
//1.
public static SharedPreferences PreferenceManager.getDefaultSharedPreferences(Context context) {}
//2.
public SharedPreferences Activity.getPreferences(int mode) {}
//3.
public SharedPreferences ContextWrapper.getSharedPreferences(String name, int mode) {}
So now here's the question: which one to choose and which one is better or there's a different purpose for each of them?

Here's the answer to my own question:
First, let's take a look at the implementations of those 3 functions.
//1.
public static SharedPreferences PreferenceManager.getDefaultSharedPreferences(Context context) {
return context.getSharedPreferences(getDefaultSharedPreferencesName(context), getDefaultSharedPreferencesMode());
}
//2.
public SharedPreferences Activity.getPreferences(int mode) {
return getSharedPreferences(getLocalClassName(), mode);
}
//3.
public SharedPreferences ContextWrapper.getSharedPreferences(String name, int mode) {
return mBase.getSharedPreferences(name, mode);
}
Here mBase is a reference to an object of type Context.
We see that the 2nd functions calls the 3rd one, and all those 3 functions are basically equivalent but with different parameters. Think of overloading.
Next, going deeper to the 1st function's implementation, we can simplify its call as the following:
//1.
public static SharedPreferences PreferenceManager.getDefaultSharedPreferences(Context context) {
return context.getSharedPreferences(context.getPackageName() +
"_preferences", Context.MODE_PRIVATE);
}
and similarly, for the second function:
//2.
public SharedPreferences Activity.getPreferences(int mode) {
return mBase.getSharedPreferences(getLocalClassName(), mode);
}
To sum-up, the 1st function creates a shared preference file with a name as <your_package_name>_preferences, the 2nd function creates a shared preference file with a name as <your_class_name>, and finally, the 3rd function lets you to specify arbitrary name for the shared preference file.
Needless to say that you need to specify the correct name for the shared preference file in order to retrieve the saved values back. So you may use the 3rd function to specify the name yourself or to use the 1st or 2nd function respective to how you have saved it before.
Warning! Make sure you are passing the correct instance of the Context class.
For example, a messy scenario would look like this: you are saving into shared preferences from a background thread which is running in the system (like for example when using the android's out-of-the-box SyncAdapter framework) and trying to get back the saved values from your UI-thread, you may get the default/wrong values!
Hope this will be helpful for someone else... ;)

I am sharing mine, hope it will make life easy -
public class SharedPreferenceStore {
public static void deleteValue(Context context, String key) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = preferences.edit();
editor.remove(key).apply();
}
public static void storeValue(Context context, String key, String value) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = preferences.edit();
editor.putString(key, value).apply();
}
public static void storeValue(Context context, String key, boolean value) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = preferences.edit();
editor.putBoolean(key, value).apply();
}
public static void storeValue(Context context, String key, double value) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String doubleVal = String.valueOf(value);
Editor editor = preferences.edit();
editor.putString(key, doubleVal).apply();
}
public static void storeValue(Context context, String key, float value) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = preferences.edit();
editor.putFloat(key, value).apply();
}
public static void storeValue(Context context, String key, long value) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = preferences.edit();
editor.putLong(key, value).apply();
}
public static void storeValue(Context context, String key, int value) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = preferences.edit();
editor.putInt(key, value).apply();
}
/*************************
* GET Methods
***************************************/
public static String getValue(Context context, String key, String defValue) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(key, defValue);
}
public static boolean getValue(Context context, String key, boolean defValue) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getBoolean(key, defValue);
}
public static double getValue(Context context, String key, double defValue) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String doubleVal = String.valueOf(defValue);
return Double.parseDouble(preferences.getString(key, doubleVal));
}
public static float getValue(Context context, String key, float defValue) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getFloat(key, defValue);
}
public static long getValue(Context context, String key, long defValue) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getLong(key, defValue);
}
public static int getValue(Context context, String key, int defValue) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getInt(key, defValue);
}
}
Just use the class and forget about all complications of SharedPrefences. Hope it will help you :)

its one and only method, just different calls and accesibility
"default" means you are not declaring name of XML file storing your data (thats the way that SharedPreferences work) and it will be available from every Activity/Context (lets say "globally") - if you want to keep ony few values you may use this
is keeping values available only for calling Acivity - "private" for storing Activity, but be aware about int mode
the last one is working also "globally" like first one, but in here
you may declare file name and keep few files with different kinds of
values - dedicated for creating more complicated storing values constructions (some wrappers etc.)

It depends. #1 Will return the SharedPreferences for whichever Context you pass it. #2 Will return the SharedPreferences for the context of the Activity you're in. This may be the same as #1 or it might not. #3 Will let you break your SharedPreferences up into different groups and name them. This might be a nice way to break things up but I have never actually done it.

Related

Android not saving sharedPrefs [duplicate]

This question already has answers here:
How to use SharedPreferences in Android to store, fetch and edit values [closed]
(30 answers)
Closed 7 years ago.
So I'm just trying to save a string.. But everytime I rerun the app, I get null for the saved String :/ I'm 100% sure I'm calling the save method, and that the string it not null when I'm saving it.
public class CFUser {
private final static String ID_KEY="myUserID";
private static String userID;
public static String getUserID(Context context) {
if(userID==null) {
SharedPreferences prefs= context.getApplicationContext().getSharedPreferences(ID_KEY, 0);
userID=prefs.getString(ID_KEY, null);
}
return userID;
}
public static void setUserID(String id, Context context) {
userID=id;
Log.d("saving", id);
SharedPreferences prefs=context.getApplicationContext().getSharedPreferences(ID_KEY, 0);
prefs.edit().putString(ID_KEY, userID);
prefs.edit().apply();
}
public static boolean isLoggedIn(Context context) {
return getUserID(context)!=null;
}
}
many thanks!
In this code, you are creating two different SharedPreferences.Editor Objects:
SharedPreferences prefs=context.getApplicationContext().getSharedPreferences(ID_KEY, 0);
prefs.edit().putString(ID_KEY, userID);
prefs.edit().apply();
So that means you are putting the String in Editor1, but are committing the (non-existant) changes of Editor2.
You need to do it this way:
SharedPreferences prefs=context.getApplicationContext().getSharedPreferences(ID_KEY, 0);
SharedPreferenced.Editor edit = prefs.edit();
edit.putString(ID_KEY, userID);
edit.apply();
At the moment the name of your entire SharedPreferences file is myUserID because of how you're retrieving the SharedPreferences. Instead use the following. This isn't causing the issue but I'm assuming you don't want the SharedPreferences file as your ID key...
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Then when you're writing to the preferences make sure you're using the same Editor.
Editor editor = preferences.edit();
editor.putString(ID_KEY,userID);
editor.apply();

How to use Android SharedPreferences

I am working on an Android project where a user can store some data but is able to delete and change/alter/update the values, I have been searching for a while now for a tutorial, but are not able to find any, so I was wondering, Is it possible to use SharedPreferences for that?
While you can always read the docs and know more about SharedPreferences, for a quick start here are few static methods from one of my project which you can use.
public static boolean getBooleanPrefs(Context ctx, String key) {
return PreferenceManager.getDefaultSharedPreferences(ctx).getBoolean(key, false);
}
public static void setBooleanPrefs(Context ctx, String key, Boolean value) {
PreferenceManager.getDefaultSharedPreferences(ctx).edit().putBoolean(key, value).commit();
}
public static String getStringPrefs(Context ctx, String key) {
return PreferenceManager.getDefaultSharedPreferences(ctx).getString(key, "");
}
public static void setStringPrefs(Context ctx, String key, String value) {
PreferenceManager.getDefaultSharedPreferences(ctx).edit().putString(key, value).commit();
}
public static int getIntPrefs(Context ctx, String key) {
return PreferenceManager.getDefaultSharedPreferences(ctx).getInt(key, 0);
}
public static void setIntPrefs(Context ctx, String key, int value) {
PreferenceManager.getDefaultSharedPreferences(ctx).edit().putInt(key, value).commit();
}
public static void clearPrefs(Context ctx) {
PreferenceManager.getDefaultSharedPreferences(ctx).edit().clear().commit();
}
So far if data is limited to some values, yes you can use SharedPreferences for that. You can easily update/alter/clear values in SharedPreferences.For usage of Shared preferences, refer these
Android Shared preferences example
http://developer.android.com/guide/topics/data/data-storage.html#pref
http://www.tutorialspoint.com/android/android_shared_preferences.htm
But if your data is not limited and have some repititive type of values to be stored.For eg. data of app users, their info and all that, then you should go for local database using SQLite. For SQLite,you should go through this tutorial
For pros and cons of SQLite and SharedPreferences, you should go through this answer
shared preference is good way to store values.
need to declare shared preference and stored value to it like.
SharedPreferences prefrs = PreferenceManager
.getDefaultSharedPreferences(getApplication());
Editor editor = prefrs.edit();
editor.putString("key",abc);
editor.commit();
you can easily get that value like below...
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
String name = prefs.getString("key", "default");
you can delete that stored value and can use for stored new value like below
SharedPreferences prefrs = PreferenceManager
.getDefaultSharedPreferences(getApplication());
SharedPreferences.Editor editor = prefrs.edit();
editor.clear();
editor.commit();
finish();

Best Practices for SharedPreferences

A set of questions about SharedPreferences that I was looking for:
What, Why, When?
How does it work inside?
The Best Practice to use it?
Only some of those question were answered here. That's why I made some investigations, and tests.
As I've answered on my own question I've decided to share answer with other people.
I've wrote a little article that can also be found here.
Best Practice: SharedPreferences
Android provides many ways of storing application data. One of those ways leads us to the SharedPreferences object which is used to store private primitive data in key-value pairs.
All logic are based only on three simple classes:
SharedPreferences
SharedPreferences.Editor
SharedPreferences.OnSharedPreferenceChangeListener
SharedPreferences
SharedPreferences is main of them. It's responsible for getting (parsing) stored data, provides interface for getting Editor object and interfaces for adding and removing OnSharedPreferenceChangeListener
To create SharedPreferences you will need Context object (can be an application Context)
getSharedPreferences method parses Preference file and creates Map object for it
You can create it in few modes provided by Context, it's strongly recommended to use MODE_PRIVATE because creating world-readable/writable files is very dangerous, and likely to cause security holes in applications
// parse Preference file
SharedPreferences preferences = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// get values from Map
preferences.getBoolean("key", defaultValue)
preferences.get..("key", defaultValue)
// you can get all Map but be careful you must not modify the collection returned by this
// method, or alter any of its contents.
Map<String, ?> all = preferences.getAll();
// get Editor object
SharedPreferences.Editor editor = preferences.edit();
//add on Change Listener
preferences.registerOnSharedPreferenceChangeListener(mListener);
//remove on Change Listener
preferences.unregisterOnSharedPreferenceChangeListener(mListener);
// listener example
SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener
= new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
};
Editor
SharedPreferences.Editor is an Interface used for modifying values in a SharedPreferences object. All changes you make in an editor are batched, and not copied back to the original SharedPreferences until you call commit() or apply()
Use simple interface to put values in Editor
Save values synchronous with commit() or asynchronous with apply which is faster. In fact of using different threads using commit() is safer. Thats why I prefer to use commit().
Remove single value with remove() or clear all values with clear()
// get Editor object
SharedPreferences.Editor editor = preferences.edit();
// put values in editor
editor.putBoolean("key", value);
editor.put..("key", value);
// remove single value by key
editor.remove("key");
// remove all values
editor.clear();
// commit your putted values to the SharedPreferences object synchronously
// returns true if success
boolean result = editor.commit();
// do the same as commit() but asynchronously (faster but not safely)
// returns nothing
editor.apply();
Performance & Tips
SharedPreferences is a Singleton object so you can easily get as many references as you want, it opens file only when you call getSharedPreferences first time, or create only one reference for it.
// There are 1000 String values in preferences
SharedPreferences first = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 4 milliseconds
SharedPreferences second = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 0 milliseconds
SharedPreferences third = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 0 milliseconds
As SharedPreferences is a Singleton object you can change any of It's instances and not be scared that their data will be different
first.edit().putInt("key",15).commit();
int firstValue = first.getInt("key",0)); // firstValue is 15
int secondValue = second.getInt("key",0)); // secondValue is also 15
When you call get method first time it parses value by key and adds this value to the map. So for second call it just gets it from map, without parsing.
first.getString("key", null)
// call time = 147 milliseconds
first.getString("key", null)
// call time = 0 milliseconds
second.getString("key", null)
// call time = 0 milliseconds
third.getString("key", null)
// call time = 0 milliseconds
Remember the larger the Preference object is the longer get, commit, apply, remove and clear operations will be. So it's highly recommended to separate your data in different small objects.
Your Preferences will not be removed after Application update. So there are cases when you need to create some migration scheme. For example you have Application that parse local JSON in start of application, to do this only after first start you decided to save boolean flag wasLocalDataLoaded. After some time you updated that JSON and released new application version. Users will update their applications but they will not load new JSON because they already done it in first application version.
public class MigrationManager {
private final static String KEY_PREFERENCES_VERSION = "key_preferences_version";
private final static int PREFERENCES_VERSION = 2;
public static void migrate(Context context) {
SharedPreferences preferences = context.getSharedPreferences("pref", Context.MODE_PRIVATE);
checkPreferences(preferences);
}
private static void checkPreferences(SharedPreferences thePreferences) {
final double oldVersion = thePreferences.getInt(KEY_PREFERENCES_VERSION, 1);
if (oldVersion < PREFERENCES_VERSION) {
final SharedPreferences.Editor edit = thePreferences.edit();
edit.clear();
edit.putInt(KEY_PREFERENCES_VERSION, currentVersion);
edit.commit();
}
}
}
SharedPreferences are stored in an xml file in the app data folder
// yours preferences
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PREFS_NAME.xml
// default preferences
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml
Android guide.
Sample Code
public class PreferencesManager {
private static final String PREF_NAME = "com.example.app.PREF_NAME";
private static final String KEY_VALUE = "com.example.app.KEY_VALUE";
private static PreferencesManager sInstance;
private final SharedPreferences mPref;
private PreferencesManager(Context context) {
mPref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public static synchronized void initializeInstance(Context context) {
if (sInstance == null) {
sInstance = new PreferencesManager(context);
}
}
public static synchronized PreferencesManager getInstance() {
if (sInstance == null) {
throw new IllegalStateException(PreferencesManager.class.getSimpleName() +
" is not initialized, call initializeInstance(..) method first.");
}
return sInstance;
}
public void setValue(long value) {
mPref.edit()
.putLong(KEY_VALUE, value)
.commit();
}
public long getValue() {
return mPref.getLong(KEY_VALUE, 0);
}
public void remove(String key) {
mPref.edit()
.remove(key)
.commit();
}
public boolean clear() {
return mPref.edit()
.clear()
.commit();
}
}
Yakiv has mentioned everything about preferences so neatly and nicely. I just want to add one more point. While editing data in shared preferences we usually do
mPref.edit()
which creates a new object of SharedPreferences.Editor type every time which can result in unnecessary objects in memory. So you can maintain a reference to editor object too and save memory and object creation time and corresponding garbage collection time.

SharedPreferences commit and rollback

Is the following the intended/reasonable way to commit and rollback SharedPreferences, and to use it in general?
public class Settings {
private static final String PREFS_NAME = "Settings";
private static SharedPreferences preferences = null;
private static SharedPreferences.Editor editor = null;
public static void init(Context context) {
// Activity or Service what ever starts first provides the Context
if (preferences == null)
// getSharedPreference because getPreferences is a method of Activity only (not Service or Context)
preferences = context.getSharedPreferences(PREFS_NAME, 0);
editor = preferences.edit();
}
public static String getEmail() {
return preferences.getString("email", null);
}
public static void setEmail(String email) {
editor.putString("email", email);
}
public static String getPassword() {
return preferences.getString("password", null);
}
public static void setPassword(String password) {
editor.putString("password", password);
}
public static void save() {
editor.commit();
}
public static void rollback() {
editor = preferences.edit();
}
}
This is more detail as enforced by stackoverflow editor. I really don't know what else should be said about this.
Experts' feedback is much appreciated. And if may snipped is reasonable it could well as better explanation then all other threads I have found here.
There is only one change in the following method from my understanding. Because if u forget to initialize preference ,u will get null pointer exception.
public static void rollback(Context context) {
if (preferences == null)
// getSharedPreference because getPreferences is a method of Activity only (not Service or Context)
preferences = context.getSharedPreferences(PREFS_NAME, 0);
editor = preferences.edit();
}
Best way to have things persisted is "USE OF PREFERENCE ACTIVITY". See examples and read online docs about them. Use EditTextPreference for automatically persisting values.
First thing is that no body ever uses shared preference to save user id and password . Because shared preference is key-value pair. For key Email you can have only one respective value. Here what you want is :- for key Email multiple values and for key password also multiple value.
There exist one solution if u want to do something like this. Use email id (xyz#xyz.com) as key . And password as the value of key(xyz#xyz.com).

android default values for shared preferences

I am trying to understand the SharedPreferences of Android. I am a beginner
and don't know a lot about it.
I have this class I implemented for my app Preferences
public class Preferences {
public static final String MY_PREF = "MyPreferences";
private SharedPreferences sharedPreferences;
private Editor editor;
public Preferences(Context context) {
this.sharedPreferences = context.getSharedPreferences(MY_PREF, 0);
this.editor = this.sharedPreferences.edit();
}
public void set(String key, String value) {
this.editor.putString(key, value);
this.editor.commit();
}
public String get(String key) {
return this.sharedPreferences.getString(key, null);
}
public void clear(String key) {
this.editor.remove(key);
this.editor.commit();
}
public void clear() {
this.editor.clear();
this.editor.commit();
}
}
The thing is that I would like to set default preferences. They would be set when the app is installed and could be modified after by the application and stay persistent.
I heard about a preferences.xml but I don't understand the process.
Could someone help me?
Thanks for you time
Simple, if you want a separate default value for each variable, you need to do it for each one, but on your method:
public String get(String key) {
return this.sharedPreferences.getString(key,"this is your default value");
}
If the variable was never accessed by the user or was never created, the system will set the default value as value and if you or the user changed this value, the default value is ignored. See http://developer.android.com/guide/topics/data/data-storage.html#pref
Directly from the Android Documentation:
The SharedPreferences class provides a general framework that allows
you to save and retrieve persistent key-value pairs of primitive data
types. You can use SharedPreferences to save any primitive data:
booleans, floats, ints, longs, and strings. This data will persist
across user sessions (even if your application is killed).
Could you use the default value parameter of the getX() method?
For example, to get a String called 'username', you could use this:
String username = prefs.getString("username_key", "DefaultUsername");
You can simply define your default values in your Preferences class.
You can store default values in string resource:
<string name="key_name">default_value</string>
and then get it as it follows:
int ResId = context.getResources().getIdentifier(key_name, "string", context.getPackageName()));
prefs.getString(key_name,context.getResources().getString(ResId);

Categories

Resources