I've got a really weird problem with my shared preferences. I'm using them to store the user-ID, different settings and so on. I'm using an activity which switches fragments if a user has clicked an item in my menu (I'm using Menu-Drawer).
After every login I store the user profile. This works perfect. After doing this I can restart the app, kill it from the memory, I can even restart my device and my values are still stored. But when I switch the fragment, e.g I'm in the home view and click "about app" in the menu, everything is gone. My values are empty.
Where it gets even weirder: If I force the activity to reload the fragment by selecting the home-item while I'm already in the home view, it's still stored. Only if I replace it with a different type of fragment everything is lost.
I don't have any idea why the app behaves like this. It's all in the same activity with the same context. I'm always using getActivity to get my context inside the fragment.
Here's a simplified snippet of my code to store it.
public static void storeUserProfile(Context context, LoginEvent event, String userId, String emailAddress, String passwordHash) {
SharedPreferences userPrefs = context.getSharedPreferences(AppConfig.USER_PREFS, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = userPrefs.edit();
editor.clear();
editor.putString("username", event.userName);
editor.putString("id", userId);
editor.putString("email", emailAddress);
editor.commit();
}
This is how I switch my fragments:
HomeFeedFragment fragment = new HomeFeedFragment();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
Try this snippet, it can be accessed from all activities/ fragments in your app.
Declare these methods first..
public static void putPref(String key, String value, Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(key, value);
editor.commit();
}
public static String getPref(String key, Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(key, null);
}
Then call this when you want to put a pref:
putPref("myKey", "mystring", getApplicationContext());
call this when you want to get a pref:
getPref("myKey", getApplicationContext());
Using fragments, does not work with getSharedPreferences() only with
PreferenceManager.getDefaultSharedPreferences (getActivity ());
Thank you very much for the fast responses! I've found the error myself. For the about view, I'm loading an html file which will be stored in shared preferences too. I haven't thought about the fact that sharedpreferences are just an xml file so I think that the html string made the xml file invalid.
I've noticed that my prefs.getString(key, defaultValue) weren't returning the defaultValue, they were returning an empty String. So I've removed the html storing and do this in a different way.
But thank you for your comments!
I had the same problem, i solved by changing the key string of my sharedpreferences
I was using :
SharedPreferences userPrefs = context.getSharedPreferences("MuslimActive", Context.MODE_PRIVATE);
I changed with :
SharedPreferences userPrefs = context.getSharedPreferences("muslim_active", Context.MODE_PRIVATE);
Anything past 2.3 and MODE_MULTI_PROCESS is disable by default, and if multiple instances of the same SharedPreferences exist MODE_MULTI_PROCESS will need to be set.
Try:
getSharedPreferences(AppConfig.USER_PREFS, Context.MODE_MULTI_PROCESS);
Also, make sure you are consistently using AppConfig.USER_PREFS in your method calls.
Related
I have a Sharedpreferences to check if the user has activated the pro section with InAppPurchase and I check it every time Mainactivity is opens, like this:
SharedPreferences s = c.getSharedPreferences("app" , MODE_PRIVATE);
String value = s.getString(key , " ");
Log.i("myapp" , value);
and if some one tries to change the value manually my app warns him .so I tried to test my app's security and changed the value manually with text editor from data/data/com.myapp.package/shared_prefs/ let's say the value was 39m49ur3.I changed it a to 87mjr83.Then I started the app and the value from the logs stil was 39m49ur3 . I closed the app and started it again but no change was seen except when I clear the RAM of my device then start the app , finally then the value I got from the logs is what really is in the shared_prefs folder.
What can I do about this?
Save like this,
SharedPreferences pref = c.getSharedPreferences("app", MODE_PRIVATE);
Editor editor = pref.edit();
editor.putString("myapp", "string value");
editor.commit();
Get Like this,
pref.getString("myapp", null);
//to save String in shared preferences
public void put(String key, String value) {
mSharedPreferences.edit().putString(key, value).apply();
}
//to get value from shared preferences
public String get(String key, String defaultValue) {
return mSharedPreferences.getString(key, defaultValue);
}
Try to use
editor.apply();
Instead of
editor.commit();
Unlike commit(), which writes its preferences out to persistent storage synchronously, apply() commits its changes to the in-memory SharedPreferences immediately but starts an asynchronous commit to disk and you won't be notified of any failures.
This question already has answers here:
TextView that gets Value from SharedPreferences shows nothing, though there should be default values
(4 answers)
Closed 6 years ago.
I am having an issue with SharedPreferences that is kind of weird.
I have an Activity that holds a Fragment in a ViewPager. The fragment shows an icon and text. You can change the icon (check mark or cross, check mark is default) and text displayed in this fragment from another activity.
Now I want to save the text and chosen icon, so the fragment is shown with the same text and icon, even when you close the app and restart it later.
So I tried to achieve this with SharedPreferences, but when I tried it, my fragment showed me no text though I have default values set and the icon is always the cross, no matter what it was before and though the default icon should be the check mark.
I am saving the values in onActivityCreated() of my Fragment when it is created with the data the user inputted in the activity before.
Saving:
SharedPreferences sharedPref = getActivity().getApplicationContext().getSharedPreferences("com.fragmentdata.myapp", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
//Here I am getting the values I want to save from a bundle, city and country...
editor.putString("savedCity", city);
editor.putString("savedCountry", country);
editor.putString("fragmentSaved", "yes");
editor.apply();
Then, I am getting the values in onCreate() of my Activity that holds the Fragment:
SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("com.fragmentdata.myapp", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
//adding fragment that was created with user input
String ifAdded = sharedPref.getString("addedFragment", "no");
if(ifAdded.equalsIgnoreCase("yes")){
Bundle extras = getIntent().getExtras();
StatusFragment newFragment = new StatusFragment();
newFragment.setArguments(extras);
mSectionsPagerAdapter.addFragment(newFragment, extras.getString("city"));
editor.putString("addedFragment", "no");
editor.apply();
}
//Adding a saved fragment after restart
String storedSave = sharedPref.getString("fragmentSaved", "no");
if (storedSave.equalsIgnoreCase("yes")){
String storedCity = sharedPref.getString("savedCity", "somecity");
String storedCountry = sharedPref.getString("savedCountry", "somecountry");
Bundle saves = new Bundle();
StatusFragment savedFragment = new StatusFragment();
saves.putString("city", storedCity);
saves.putString("country", storedCity);
savedFragment.setArguments(saves);
mSectionsPagerAdapter.addFragment(savedFragment, saves.getString("city"));
}
In the activity where the fragments data is created, I have this:
SharedPreferences sharedPref = getApplicationContext().getSharedPreferences("com.fragmentdata.myapp", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("addedFragment", "yes");
editor.apply();
fragmentHolder.putExtras(bundle);
startActivity(fragmentHolder);
bundle has the values the user typed in, and fragmentHolder is the activity that holds the fragment.
I searched for answers in different questions here on stackoverflow, but none of them worked for me, like:
Cannot get value from sharedpreferences
Shared Preferences get lost after shutting down device or killing the app
Shared Preferences reset data when app is force closed or device is restarted
SharedPreferences return only default value
SharedPreferences return only default value
Shared preference always taking default value
SharedPreferences keep getting default value
Sorry if I it is perhaps something trivial, but I haven't worked with Fragments much and I am using SharedPreferences the first time now.
I would be grateful for every helpful answer.
The problem is solved now. I had to use getActivity().getApplicationContext().getSharedPreferences("com.fragmentdata.myapp", Activity.MODE_PRIVATE); and some of my variables in the bundles and preferences got mixed up. I corrected this and now it works fine :) Thanks for your answers.
You are mixing up things that are stored in your SharedPreference and inside your applications resources (strings.xml)
editor.putString(getString(R.string.pref_fragment_saved), "Yes");
This line saves the string inside your preference XML, but then you try to read it as
getResources().getString(R.string.pref_fragment_saved).equals("Yes")
Which actually just reads the value R.string.pref_fragment_save from your strings.xml
The correct way of reading what you saved would be
getActivity().getPreferences(Context.MODE_PRIVATE).getString(getResources().getString(R.string.pref_fragment_saved), "defaultValue")
Or a bit cleaner:
SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE);
String key_frag_saved = getResources().getString(R.string.pref_fragment_saved);
String storedString = prefs.getString(key_frag_saved, "defValue");
if ( storedString.equalsIgnoreCase("yes") ) {...}
And the same way you would read the other saved values from your SharedPreference object instance.
You wanted to use this
SharedPreferences sharedPref = ...;
extras.putString("city", sharedPref.getString(getResources().getString(R.string.pref_saved_city), ""));
in your onCreate method
I have a fragment where I let set some SharedPreference values set.
In the fragment, everything works fine - I can get any value I want, saving, editing, deleting works fine.
Then I have an Activity, from where I want to get the value "savedValue1" - but it does not work
public static final String MyPref = "MyPreference";
static SharedPreferences sharedpreferences;
//onCreateView...
sharedpreferences = this.getActivity().getSharedPreferences(MyPref,
Context.MODE_PRIVATE);
editor.putString("savedValue1", someString);
editor.commit();
I tried it with in Fragment:
public static String getValue(){
return sharedpreferences.getString("savedValue1","");
}
in Activity:
String newValue = Fragment.getValue();
But that doesn't work - any hint?
You should not have a Fragment.getValue() method.
SharedPreferences are here to avoid that.
Use the same getSharedPreferences("whatever", Context.MODE_PRIVATE) code and you shall get/set the same values inside the same preferences.
That is how it is supposed to be used. From the official documentation:
For any particular set of preferences, there is a single instance of
this class that all clients share.
Use this code to save and retrieve values from SharedPreferences
//To save string
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor e = settings.edit();
e.putString("savedValue1", someString);
e.commit();
//Retrieve team score
String saved_value = settings.getString("savedValue1", "");
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;
}
}
How to remove some key/value pair from SharedPreferences ? I have put and I to remove that from prefs.
SharedPreferences mySPrefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = mySPrefs.edit();
editor.remove(key);
editor.apply();
Here editor is the sharedPreferences editor.
It is important to note that, unless you're planning on doing something with the return value of the commit() call, there is absolutely no reason for using the synchronous commit() call instead of the asynchronous apply() call.
Keep in mind that if you're calling this from the main/UI thread, the UI is blocked until the commit() has completed. This can take upwards of around 100ms as apposed to about 5ms for the apply. That may not seem like much, but if done continually throughout an application, it will certainly add up.
So, unless you're planning on doing something like this, hopefully on a separate thread:
editor.remove(String key);
boolean success = editor.commit();
if (!success) {
// do something
}
You should instead be doing this:
editor.remove(String key);
editor.apply();
It's very simple:
private SharedPreferences sharedPreferences() {
return PreferenceManager.getDefaultSharedPreferences(mContext);
}
public void clearSharedPreferences() {
sharedPreferences()
.edit()
.remove(SOME_KEY_1)
.remove(SOME_KEY_2)
.remove(SOME_KEY_3)
.apply();
}
SharedPreferences.Editor.remove(key)
commit();
Here is how I tacked this issue.
First I created an instance of SharedPreference as
SharedPreferences mobilePreference;
then I used this sharedPreference as
mobilePreference = this.getSharedPreferences("in.bhartisoftwares.amit.allamitappsthree", Context.MODE_PRIVATE);
Here "in.bhartisoftwares.amit.allamitappsthree" is my package name and I am using Context.MODE_PRIVATE, because I want to manipulate this shared preference only for this package name.
Then I am deleting the selected sharedPreference (key of my sharedPreference is mobileString) as follows:
mobilePreference.edit().remove("mobileString").commit();
See the code as full below:
SharedPreferences mobilePreference = this.getSharedPreferences("in.bhartisoftwares.amit.allamitappsthree", Context.MODE_PRIVATE);
mobilePreference.edit().remove("mobileString").commit();
Information
Just check sharedpref class is extended to Map that's why there is remove method
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = prefs.edit();
editor.remove(String key);
editor.apply();
Here editor is the sharedPreferences editor.