In my app I was using for more than 1 year "Shared preferences" to store some boolean values (if the user has seen the intro page for example). Now I added one more setting (if the user has seen the help page!) and all the settings stopped working...
I tried changing "commit" to "apply" with no luck. How could by just adding one more shared preference to make it stop working? Is there any properties limit?
My code:
public SharedPreferences getSettings() {
SharedPreferences settings = getSharedPreferences(AppConstants.PREFS_NAME, 0);
return settings;
}
old Activity for Intro:
private void saveUserHasSeenIntro() {
SharedPreferences.Editor editor = getSettings().edit();
editor.putBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_INTRO_STEPS, true);
editor.commit();
}
where intro boolean is being read:
Boolean hasShownIntroSteps = getSettings().getBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_INTRO_STEPS, false);
if ( !hasShownIntroSteps ) {
// show intro
} else {
New activity for help:
private void saveUserHasSeenHelp() {
SharedPreferences.Editor editor = getSettings().edit();
editor.putBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS, true);
editor.commit();
}
where the "help" boolean is read:
Boolean hasSeenHelp = getSettings().getBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS, false);
if ( !hasSeenHelp ) {
// show help activity
} else {
Your methods are fine and they should work perfectly. Check a couple of things just in case:
Ensure you don't call clear() or remove() method of the SharedPreferences editor after saving your prefs by mistake.
Ensure the constants AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS and AppConstants.SETTING_BOOLEAN_HAS_SHOWN_INTRO_STEPS have different values as the former could overlap the second by mistake.
Just add a breakpoint after setting the new pref and read the value to check if it's set just after it.
SharedPreferences.Editor editor = getSettings().edit();
editor.putBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS, true);
editor.commit();
Boolean hasSeenHelp = getSettings().getBoolean(AppConstants.SETTING_BOOLEAN_HAS_SHOWN_HELP_STEPS, false);
In some extreme cases you could even implement SharedPreferences.OnSharedPreferenceChangeListener to see where your SharedPreferences are being changed to avoid unwanted pref sets.
It can be a Memory Limitation on your SharedPreferences file and usually this comes with an OutOfMemoryException. I guess if something like that would happen you would probably seen it in your code, unless you are not reading/writing in another Thread. How big is your SharedPreferences file in numbers of key - value pair ?
Related
I have 2 int in my navigation drawer, the value of whom changes upon clicking different button on different locations in the app.
I got the code to successfully increment and update them, but the problem is that they got reset when I open the app after closing or exiting it.
How can I make them stay there after getting updated?
If you want any code from my app, then please tell me.
Sorry for bad formatting of the question, but I have no idea how to do this and hence I haven't posted any code.
You must save the info in a persistent storage.
You can use SharedPreferences.
SharedPreferences prefs= getSharedPreferences("aName", MODE_PRIVATE);
//save the value
prefs.edit()
.putInt("nameOfTheValue", theValue).apply();
// get the data
prefs.getInt("nameOfTheValue", aDefaultValue);
You should save them as User SharedPreferences in onDestroy method.
public void onDestroy() {
super.onDestroy();
SharedPreferences settings;
settings = getSharedPreferences("TWO_INT_SAVING", Context.MODE_PRIVATE);
//set the sharedpref
Editor editor = settings.edit();
editor.putInt("FIRST_INT", firstIntValue);
editor.putInt("SECOND_INT", secondIntValue);
editor.commit();
}
And then you can get them back wen needed:
SharedPreferences settings;
settings = getSharedPreferences("TWO_INT_SAVING", Context.MODE_PRIVATE);
//get the sharepref
int firstInt = settings.getInt("FIRST_INT", 0);
int secondInt = settings.getInt("SECOND_INT", 0);
I found all answers here and tried all solutions, still my shared prefs are not persistent.
Here's my code:
public static void setActivated(boolean activated) {
SharedPreferences sp = Utils.getContext().getSharedPreferences(
USER_PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(ASD, activated);
editor.commit();
}
public static boolean isActivated() {
SharedPreferences sp = Utils.getContext().getSharedPreferences(USER_PREFS, Context.MODE_PRIVATE);
return sp.getBoolean(ASD, true);
}
I've tried also:
editor.clear();
editor.put ..
editor.commit();
I've also tried with
editor.apply();
I even tried with both .apply() and .commit() and no luck.
Another idea was to try using a different mode for the files:
...getSharedPreferences(USER_PREFS, Context.MODE_MULTI_PROCESS);
The problem is that the values saved are not persistent. If I close the app and then re-open it the values are all wrong.
Does anyone have any ideas? I would also mention that the problem is only on some devices, for example HTC One S, Samsung Galaxy S3 (I tested on a different S3 and it worked perfectly).
EDIT: I call the save on a button click listener and I call isActivated when I load the fragment (after onViewCreated()).
Thanks!
Hi I think it should work. If clearing does not work, you could try the second option as detailed in my solution:
You have 2 options:
Get shared preference value during the life-cycle of the activity.
Call .clear before .commit
See my answer:
Android Persistent Checkable Menu in Custom Widget After Reboot Android
public abstract SharedPreferences.Editor clear()
Added in API level 1 Mark in the editor to remove all values from the
preferences. Once commit is called, the only remaining preferences
will be any that you have defined in this editor. Note that when
committing back to the preferences, the clear is done first,
regardless of whether you called clear before or after put methods on
this editor.
Returns Returns a reference to the same Editor object, so you can
chain put calls together.
In my user preferences class I was getting a null value on some other strings and my code was something like this:
SharedPreferences sp = Utils.getContext()
.getSharedPreferences(USER_PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (session != null && !"".equals(session)) {
sessionId = session;
editor.putString(SESSION, sessionId).commit();
} else {
sessionId = null;
editor.clear().commit();
}
The editor.clear() was resetting all my other commits!
I don't know why, but it is working by just putting your prefs code inside the async task:
prefss = getSharedPreferences(ACCOUNT_PREFS_NAME, MODE_MULTI_PROCESS);
new AsyncSave(favNamesList).execute();
private static class AsyncSave extends AsyncTask<Void, Void, Boolean> {
String favNamesList;
AsyncSave(String favNamesList) {
this.favNamesList = favNamesList;
}
#Override
protected Boolean doInBackground(Void... params) {
prefss.edit().putString("favNamesList", strings).apply();
return null;
}
}
I have in my main activity access to a shared preference like this:
preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("maxValue", "666");
Boolean test = editor.commit();
when I open my Preference activity I see for that preference the value 666. So that works without issue.
Now I want to do pretty much the same in my Preferences.java, background is that I want to check the input string and notify the user if something is wrong, e.g. I want to make sure that if the users sets the maxValue above 1000, to tell him that this is too high and set it to 899 automatically. I have implemented a change listener:
#Override
public boolean onPreferenceChange(Preference pref, Object newValue)
{
if(Integer.valueOf(etAdd.getEditText().getText().toString()) > 899)
{
SharedPreferences.Editor editor = preferences.edit();
editor.putString("maxValue", "899");
Boolean test = editor.commit(); //test shows true
Toast.makeText(Preferences.this, "value too high have set it to the maximum of 899", Toast.LENGTH_LONG).show(); //this toast is shown
}
return true;
}
When I re-open this preference, even after leaving the preference activity and returning back to it, I see the value the user has entered, e.g. 1000.
anyone an idea?
thanks.
According to the documentation onPreferenceChange is called BEFORE the changes are written. If you return true (accept new Value), after leaving onPreferenceChange the newValue object is successfully applied and your modifications are ignored. That is the reason of mentioned behavior. Returning false would do the trick.
To project your corrected value to PreferenceActivity immediately, use SetText on your EditTextPreference.
Using typecasted newValue.toString() instead of using contents of the corresponding EditText is also worth considering.
I created a MainActivity in which the user has a few app options, displayed in a grid menu, which access subsequent specific activities. However, when the application starts, I use an AlertDialog for the user to enter login details, inflated just after the grid layout definition.
The problem is, each time I select an item in the grid menu (and, consequently, a new activity), the AlertDialog pops-up again. How can I avoid this?
Moreover, I have an uploading service which should start with the beginning of the MainActivity (or after the login, perhaps), but should not be restarted each time a new activity is called. I assume this problem is related to the previous one, although I have managed to temporarily solve it by using a startService button via an OptionsMenu. This is no permanent solution.
Thank you in advance.
EDIT: I tried to use getSharedPreferences as follows:
private SharedPreferences prefs;
private String prefName = "MyPref";
int hasLoggedIn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mm_gridmenu);
SharedPreferences prefs = getSharedPreferences(prefName, MODE_PRIVATE);
hasLoggedIn = prefs.getInt("hasLoggedIn", 0);
if (hasLoggedIn == 0) {
showDialog(SHOW_DIALOG);
prefs = getSharedPreferences(prefName , MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("hasLoggedIn", 1);
editor.commit();
}
However, this way the hasLoggedIn value is saved as 1 and the dialog never pops-up again. I tried setting the back button to fix that, but this seems to prevent the app from being minimized. Is there a way to add that action to the button? (Which I would duplicate on the Home button as well)
#Override
public void onBackPressed() {
prefs = getSharedPreferences(prefName , MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("hasLoggedIn", 0);
editor.commit();
Log.i("hasLoggedIn", hasLoggedIn + "");
return;
}
Moreover, I believe this action will affect subsequent activities (setting the alertDialog back on). Which should be a valid alternative to this?
Basically you need to keep track of your applications states, you have a few options to do this. One simple way would be to use a SharedPreferences to store a boolean variable called something like hasLoggedIn after the user logs in you set this value to true. Each time your main activity launches simply check the value of hasLoggedIn if its is set to false require the user log in again. If it is already true don't show the log in dialog
You can try this:
Add a boolean flag in your MainActivity:
private boolean dialogFlag = true;
in the onCreate/onResume method:
if(dialogFlag) {
createDialog();
dialogFlag = false;
}
If you want to pop up just once the app is installed, you can save this flag into a property file. And read it first whenever the app is getting started.
i need to save a simple field to configurate my APP, cause this, i wont use a database (it's only a field...), i need to save true or false value for this field on a file, and everytimes a section of my app wanna check if it is true they have to check this textfile, and not to open a connexion to a database
i need to save the config for ever... i mean that when i exit from my app, and for example, i shut down my android device, when i start my device again and start my app, the config have to be saved
is this possible? how can i do it? i can't find any information about that
EDIT: i have problems with the first answer... this code is on my oncreate method:
static SharedPreferences settings;
static SharedPreferences.Editor configEditor;
settings = this.getPreferences(MODE_WORLD_WRITEABLE);
if (settings.getBoolean("showMeCheckBox", true))
showMeCheckBox.setChecked(true);
else
showMeCheckBox.setChecked(false);
applyButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
if (showMeCheckBox.isChecked()) {
configEditor.putBoolean("showMeCheckBox", true);
} else {
configEditor.putBoolean("showMeCheckBox", false);
}
}
});
ok, but this doesn't works... allways is selected... always true, like the default value... doesn't matter if i checked or unchecked it.... :S
i suggest not to use a textfile but the Preference Editor.
static SharedPreferences settings;
static SharedPreferences.Editor editor;
settings = this.getPreferences(MODE_WORLD_WRITEABLE);
editor = settings.edit();
//store value
editor.putString("Preference_name_1", "1");
//get value
//eill return "0" if preference not exists, else return stored value
String val = settings.getString("Preference_name_1", "0");
Edit: you have to initialize the configEditor and after setting a value, you have to commit
editor = settings.edit();
editor.putBoolean("name",true);
editor.commit();