How can I migrate Android preferences with a new version? - android

I have an app where I'm storing user preferences like this:
public static final String KEY_PREFS_LOGIN_INFO = "login_info";
public static final String KEY_PREFS_FILE_VERSIONs = "file_versions";
public static final String KEY_PREFS_LOGS = "logs";
public static final String KEY_PREFS_OTHERS = "others";
With pref-specific methods like this:
public static void setFileVersion(String key) {
SharedPreferences settings = getAppContext().getSharedPreferences(KEY_PREFS_FILE_VERSIONS, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("current", key);
editor.commit();
}
and then retrieving the values like this:
public static String filesVersion() {
SharedPreferences settings = getAppContext().getSharedPreferences(KEY_PREFS_FILE_VERSIONS, 0);
String current = settings.getString("current", "");
return current;
}
What I want to do is have all of my preferences be stored in one location, so I can use a generic method to access any of them. How can I set a way to, on upgrade, migrate values from the old storage locations to the new? I'm looking for something similar to the onUpgrade() method in a SQLiteOpenHelper.

I would override Application. Then on start up check what version number is stored in your shared preferences, and then perform the traversal from any old keys to new keys as necessary.
public class MyApplication extends Application {
private static final int CURRENT_PREFS_VERSION = 2;
#Override
public void onCreate() {
super.onCreate();
if(filesVersion() != CURRENT_PREFS_VERSION){
migrate(filesVersion())
}
}
private migrate(int oldVersion){
switch(oldVersion){
case 1:
//get old preference, store new preference
break;
}
setFileVersion(CURRENT_PREFS_VERSION)
}

Related

In android how to create a shared preferences when the application is installed?

Hi I'am new to android.
I want to create a shared preferences when the app is first installed and the insert some data.
The shared preference has to be used from all activities in the app.
I tried creating the shared preference in the onCreate() function of the first activity and inserted values into it.And edited the data from another activity.
But when I restart the app the shared preference changes to the data give in the
onCreate().
Can somebody help me?
The way if you want to insert data once:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences preferences = getSharedPreferences("myPref", MODE_PRIVATE);
boolean shouldInsertData = preferences.getBoolean("shouldInsertData", true);
if(shouldInsertData){
//insert your data into the preferences
preferences.edit().putBoolean("shouldInsertData", false).apply();
}
}
Share Preference is best way to store short information. but if you will create share preference from an active, it may create problem to access it from other activity.
You should create a global common share preference from application so you can access it through out the android project, any where in any activity.
I get reference from here -
It is 4 step process.
Step 1- create a java class file name as "myapp" and extend it by application.
public class MyApp extends Application {
private static Context context;
private String TAG ="myApp";
#Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
// Log.e(TAG, " myapp stater");
}
public static Context getContext(){
return context;
}}
Step 2 - in android manifest file inside application tab add android:name=".myapp"
Step 3 - Create java class name as "SharePreferenceUtils" (note don't use name SharePreference.)
public class SharePreferenceUtils {
private static String PREFERENCE_NAME = "shopeasy-ecommerce";
private static SharePreferenceUtils sharePreferenceUtils;
private SharedPreferences sharedPreferences;
private SharePreferenceUtils(Context context){
PREFERENCE_NAME = PREFERENCE_NAME + context.getPackageName();
this.sharedPreferences = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
}
public static SharePreferenceUtils getInstance(){
if (sharePreferenceUtils == null){
sharePreferenceUtils = new SharePreferenceUtils(SplashActivity.getContext());
}
return sharePreferenceUtils;
}
// login response user_id 1234
public void saveString(String key, String Val ){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, Val);
editor.commit();
}
public String getString(String key, String defVal){
return sharedPreferences.getString(key, defVal);
}
public String getString(String key){
return sharedPreferences.getString(key, "");
}
public void saveInt(String key, int Val ){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(key, Val);
editor.commit();
}
public int getInteger(String key){ return sharedPreferences.getInt(key, 0 ); }
/**
* Clear all values from this preference
*/
public void clear() {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear();
editor.commit();
}
/**
* Clear value of given key from this preference
*
* #param key name of the key whose value to be removed
*/
public void clearString(String key) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(key);
editor.commit();
}}
Step 4 Call sharePreferenceUtil from activity
SharePreferenceUtils.getInstance().saveString("Username", "username value here");
Now you can access sharepreference from any activity. Just call instance of sharepreference java class.

How to make SingletonClass of Sharedpreference in android

I have one activity in which I store all the details regarding registration of user and what I want is to make a class Singleton and save mobile and password of user and in activity I use those stored data instead of creating every time a new object. How can I do that?
Here is my RegistrationModel where I store user data:
public class CRegistrationSessionManagement {
;
// User name (make variable public to access from outside)
public static final String s_szKEY_MOBILENUMBER = "mobileNumebr";
public static final String s_szKEY_PASSWORD = "pin";
public static final String s_szKEY_EMAILID = "emailId";
// Sharedpref file name
public static final String s_szREGIS_FILE_NAME = "RegistrationData";
// All Shared Preferences Keys
private static final String s_szIS_REGISTERED = "IsRegistered";
public static String mobile;
public SharedPreferences m_Regis_Pref;
// Editor for Shared preferences
public SharedPreferences.Editor m_editor;
// Context
public Context m_Context;
public CRegistrationSessionManagement(Context m_Context) {
this.m_Context = m_Context;
m_Regis_Pref = m_Context.getSharedPreferences(s_szREGIS_FILE_NAME, Context.MODE_PRIVATE);
m_editor = m_Regis_Pref.edit();
}
// Registration Session Management.
public void setRegisteredData(String mobile, String pin, String emailId) {
m_editor.putBoolean(s_szIS_REGISTERED, true);
m_editor.putString(s_szKEY_MOBILENUMBER, mobile);
m_editor.putString(s_szKEY_PASSWORD, pin);
m_editor.putString(s_szKEY_EMAILID, emailId);
m_editor.commit();
}
/**
* checkRegistrtaion() session wil check user Registrtaion status
* If false it will redirect user to Registrtaion page
* Else won't do anything
*/
public boolean checkRegistration() {
if (!isRegistered()) {
Intent i = new Intent(m_Context, CMainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
m_Context.startActivity(i);
return true;
}
return false;
}
/**
* Get stored Registration session data
*/
public HashMap<String, String> getRegistrationDetails() {
HashMap<String, String> user = new HashMap<>();
// user name
user.put(s_szKEY_MOBILENUMBER, m_Regis_Pref.getString(s_szKEY_MOBILENUMBER, null));
// user email id
user.put(s_szKEY_PASSWORD, m_Regis_Pref.getString(s_szKEY_PASSWORD, null));
user.put(s_szKEY_EMAILID, m_Regis_Pref.getString(s_szKEY_EMAILID, null));
// return user
return user;
}
public boolean isRegistered() {
return m_Regis_Pref.getBoolean(s_szIS_REGISTERED, false);
}
}
How can I fetch mobile and password in activity where I want to ...by only creating instance of this class...instead of creating every time a new object of that class.
You can use static method. Instead of public HashMap<String, String> getRegistrationDetails () you can use public static HashMap<String, String> getRegistrationDetails (). So when you want to use your getter. CRegistrationSessionManagement. getRegistrationDetails () . Take a look to this example to know more about static method and their uses. Java: when to use static methods

SharedPreferences in picking random value when force closing application

I have to implement a functionality in which I have to store multiple id's in SharedPreferences in an application in android. I have to perform three main operations on data in preferences
1. add and save new id
2. delete a particular id
3. check if id exists
I wrote following class to perform all operations needed.
public class PreferenceUtils {
Context context;
private static final String TAG = PreferenceUtils.class.getName();
private static final String FAVOURITES = "favourites";
SharedPreferences preferences;
SharedPreferences.Editor editor;
public PreferenceUtils(Context context) {
this.context = context;
preferences = PreferenceManager.getDefaultSharedPreferences(context);
editor = preferences.edit();
}
public void save(long id) {
Set<String> prefStrings = preferences.getStringSet(FAVOURITES, new HashSet<String>());
prefStrings.add(id+"");
editor.putStringSet(FAVOURITES, prefStrings);
editor.commit();
editor.clear();
Log.d(TAG,id + " saved");
}
public void delete(long id) {
Set<String> prefStrings = preferences.getStringSet(FAVOURITES, new HashSet<String>());
prefStrings.remove(id + "");
editor.putStringSet(FAVOURITES, prefStrings);
editor.commit();
editor.clear();
Log.d(TAG,id + " deleted");
}
public boolean isExists(long id) {
final Set<String> prefStrings = preferences.getStringSet(FAVOURITES, new HashSet<String>());
return prefStrings.contains(id+"");
}
public Set<String> getAll() {
return preferences.getStringSet(FAVOURITES, new HashSet<String>());
}
public void clearHistory() {
editor.clear();
editor.commit();
}
}
I am creating instance of PreferenceUtils class from MainActivity like this:
PreferenceUtils pref = new PreferenceUtils(getApplicationContext());
Now the problem is when I am saving few values in preferences and closing application using back button or a Quit button (which will finish() MainActivity) everything is working fine and I am getting all the values from preferences. However, if I am force closing the application and reopening it I am getting only the first value I saved and rest all values are lost.
Try to remove the editor.clear() in both save and delete.this might be your problem.

android: sharedpreferences possible to use across activities?

i have created a sharedpreferences data in one activity, is it possible to be used in another activity? if yes, how could this be achieved?
The names of the 4 players are saved in NameIndex.java, and I would like to use the saved Names of the 4 players in the MainActivity.java
Under NameIndex.java:
private void SaveNamesToFile(String Game1, String P1Name, String P2Name, String P3Name, String P4Name)
// save the new row to the file, then refresh all Buttons
{
// originalScore will be null if we're modifying a slot that is existing already
String originalNameP1 = SavedNameP1.getString(Game1, null); // to return null if this preference does not exist.
String originalNameP2 = SavedNameP2.getString(Game1, null);
String originalNameP3 = SavedNameP3.getString(Game1, null);
String originalNameP4 = SavedNameP4.getString(Game1, null);
// get a SharedPreferences.Editor to store new row data
SharedPreferences.Editor preferencesEditorP1 = SavedNameP1.edit();
SharedPreferences.Editor preferencesEditorP2 = SavedNameP2.edit();
SharedPreferences.Editor preferencesEditorP3 = SavedNameP3.edit();
SharedPreferences.Editor preferencesEditorP4 = SavedNameP4.edit();
preferencesEditorP1.putString(Game1, P1Name);
preferencesEditorP2.putString(Game1, P2Name);
preferencesEditorP3.putString(Game1, P3Name);
preferencesEditorP4.putString(Game1, P4Name);
preferencesEditorP1.apply();
preferencesEditorP2.apply();
preferencesEditorP3.apply();
preferencesEditorP4.apply();
}
I used one SharedPreferences file between activities, but what I did was using the same file name declared in different private variables inside the two activities. You can check my code in the following link. What I don't understand is why you use 4 SharedReferences files just for the names of the players and not all the names in just 1 file. That's possible because I used it to save more than 2 variables.
Yes they can be shared across activities. The easiest route is to just use:
context.getDefaultSharedPreferences()
I am using it like this
public class SharedPreferencesHelper {
SharedPreferences myPrefs;
SharedPreferences.Editor prefsEditor;
private static SharedPreferencesHelper instance = null;
public static synchronized SharedPreferencesHelper getInstance() {
if (instance == null) {
instance = new SharedPreferencesHelper();
}
return instance;
}
private SharedPreferencesHelper() {
myPrefs = MyApplication.getInstanse().getApplicationContext().getSharedPreferences("prefs", Context.MODE_WORLD_READABLE);
prefsEditor = myPrefs.edit();
}
public void putValueForKey(String key, String value) {
prefsEditor.putString(key, value);
prefsEditor.commit();
}
}
public class MyApplication extends Application {
private static MyApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static MyApplication getInstanse(){
if(instance ==null){
throw new IllegalStateException("Application not created yet!");
}
return instance;
}
}

Android SharedPreferences.Editor putStringSet method not available

I am trying to update a password generator I made to include the ability to save passwords, so I'm using SharedPreferences. I want to put the saved passwords inside a Set, but when I try to save the set using SharedPreferences.Editor's putStringSet method, Eclipse does not recognize it. When I hover over putStringSet in my code, the 2 quick fixes available are "Change to putString(...)" and "add cast to editor", but I don't think either of those helps.
This is what I have:
public void save(View v)
{
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
final SharedPreferences.Editor editor = prefs.edit();
savedPasswords = (Set<String>) getSharedPreferences("savedPasswordsList", 0);
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setItems(passwords, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface face, int num)
{
savedPasswords.add(passwords[num]);
editor.putStringSet("savedPasswordsList", savedPasswords);
editor.commit();
refreshSavedPasswordsList();
}
});
dialog.show();
}
putStringSet(...) was added at API 11 (Android v3.0.x onwards). My guess is you're targeting a version below that.
I implemented data storage using putStringSet and then needed to backport it to Gingerbread so I created a small class called JSONSharedPreferences.
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.SharedPreferences;
public class JSONSharedPreferences {
private static final String PREFIX = "json";
public static void saveJSONObject(SharedPreferences prefs, String key, JSONObject object) {
SharedPreferences.Editor editor = prefs.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, object.toString());
editor.commit();
}
public static void saveJSONArray(SharedPreferences prefs, String key, JSONArray array) {
SharedPreferences.Editor editor = prefs.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, array.toString());
editor.commit();
}
public static JSONObject loadJSONObject(SharedPreferences prefs, String key) throws JSONException {
return new JSONObject(prefs.getString(JSONSharedPreferences.PREFIX+key, "{}"));
}
public static JSONArray loadJSONArray(SharedPreferences prefs, String key) throws JSONException {
return new JSONArray(prefs.getString(JSONSharedPreferences.PREFIX+key, "[]"));
}
public static void remove(SharedPreferences prefs, String key) {
if (prefs.contains(JSONSharedPreferences.PREFIX+key)) {
SharedPreferences.Editor editor = prefs.edit();
editor.remove(JSONSharedPreferences.PREFIX+key);
editor.commit();
}
}
}
Usage:
//Below, the code to use putStringSet is commented out.
//Alternative JSONSharedPreferences is used instead
//Set<String> trainers = new TreeSet<String>();
JSONArray jTrainers = new JSONArray();
List<FilteredWorkoutVideo> videos = getAllFilteredVideos(prefs);
for (FilteredWorkoutVideo video : videos) {
//trainers.add(video.getTrainerName());
jTrainers.put(video.getTrainerName());
}
//e = prefs.edit();
//e.putStringSet(Constants.KEY_ALL_TRAINERS, trainers);
//e.apply();
JSONSharedPreferences.saveJSONArray(prefs, Constants.KEY_ALL_TRAINERS, jTrainers);
To work around this issue I created a SharedPreferencesCompat class:
In stores the StringSet in a string CSV-style.
It is possible to change ',' used in CVS by another delimiter.
public class SharedPreferencesCompat {
private final static String KEY_DELIMITER = "com.example.delimiter";
public static void setStringSetDelimiter(final SharedPreferences sharedPreferences, final String delimiter) {
final Editor editor = sharedPreferences.edit();
editor.putString(KEY_DELIMITER, delimiter);
editor.commit();
}
public static Set<String> getStringSet(final SharedPreferences sharedPreferences, final String key) {
final Set<String> out = new LinkedHashSet<String>();
final String base = sharedPreferences.getString(key, null);
if (base != null) {
out.addAll(Arrays.asList(base.split(sharedPreferences.getString(KEY_DELIMITER, ","))));
}
return out;
}
public static void putStringSet(final SharedPreferences sharedPreferences, final String key,
final Set<String> stringSet) {
final String concat = StringUtils.join(stringSet, sharedPreferences.getString(KEY_DELIMITER, ","));
final Editor editor = sharedPreferences.edit();
editor.putString(key, concat);
editor.commit();
}
}
Note:
It depends on apache StringUtils.join() method.
You can easily swap this out for another one.
I know this thread is a old, but I just ran into the same issue and my solution was to use a global HashTable to keep track of my strings, which were actually file names. I also needed a status associated with with each file, so I implemented the following simple class:
public class Globals
{
public static enum SendStatus
{
NOT_SENT,
SEND_SUCCESS,
SEND_ERROR
}
public static volatile Hashtable<String, SendStatus> StoredFilesStatus;
}
}

Categories

Resources