How can I reload SharedPreferences when I resume from one activity to another? If I resume, it is possible that user has changed the settings. Is it possible to reload SharedPreferences or do I need to refresh/reload activity. And if, then how?
There is no difference in how you get and set SharedPreferences normally and from doing so in onResume. What you will need to do in addition to getting the most recent preferences, is update any objects you have in the Activity that use preference values. This will ensure your Activity is working with the most recent values.
A simple example:
protected void onResume() {
super.onResume();
getPrefs();
//...Now update your objects with preference values
}
private void getPrefs() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String myPref = prefs.getString("myPref", "");
}
Related
I have a variable who contains data that can change when user is using app.
My goal is to store those data in SharedPrefs just before user is closing app,
I was thinking about something like
OnStop() {
Preferences.edit()... }
but i don't know the correct syntax ...
thanks in advance guys
Save your data in SavedPrefs in onStop Method.
Syntex will be like
In onStop Method
#Override
protected void onStop() {
super.onStop();
SharedPreferences saved_values = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = saved_values.edit();
edit.putString("key", "stringToBeSaved")
editor.commit();
}
And then to retrive your data in onCreate method
#Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences saved_values = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String foo = saved_values.getString("key", "default_string");
}
Remember the key should be same.
For more info check out Android docs on
Shared Preferences: Save key-value data
Android Lifecycle: Understand the Activity Lifecycle
Activity.onStop() is called just before the app is completely closed (kicked from recents)
You should probably use Activity.onPause() to save your preferences as it will also be called when the user just switches to another app.
Further information:
https://developer.android.com/guide/components/activities/activity-lifecycle
You should save your persistent data in onPause() rather than in onStop().
Then you can retrieve your data in onResume().
For saving the data you can take a look at this example
SharedPreferences.Editor editor = getSharedPreferences("myPrefs", MODE_PRIVATE).edit();
editor.putString("username", "My name");
editor.apply();
And then retrience your data like this
SharedPreferences prefs = getSharedPreferences("myPrefs", MODE_PRIVATE);
String username = prefs.getString("username", "No username"); //No username is the default value
I've looked all over and can't seem to find an answer to my issue. For some reason the data saved in SharedPreferences reappears after switching activities. Why is my SharedPreferences still the exact same as it was before I cleared it and how can I fix this?
In first activity:
#Override
protected void onStop() {
super.onStop();
SharedPreferences sp = this.getSharedPreferences(TEMP_KEY, MODE_PRIVATE);
Gson gson = new Gson();
String objectJson = gson.toJson(object, Object.class);
String activityJson = "FirstActivity";
SharedPreferences.Editor editor = sp.edit();
editor.putString(CONTINUE_KEY, objectJson);
editor.putString(ACTIVITY_KEY, activityJson);
editor.apply();
}
public void onClickSave() {
Gson gson = new Gson();
String objectJson = gson.toJson(object);
SharedPreferences sp getSharedPreferences(SAVE_KEY, MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString(object.getDate(), objectJson);
editor.apply();
SharedPreferences spTemp = this.getSharedPreferences(TEMP_KEY, MODE_PRIVATE);
spTemp.edit().clear().apply();
// go back to the main menu
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
Before the apply():
After the apply():
In Main Activity:
SharedPreferences sp = this.getSharedPreferences(TEMP_KEY, MODE_PRIVATE);
From main activity:
From Coordinating activities android documentation.
When one activity starts another, they both experience lifecycle
transitions. The first activity stops operating and enters the Paused
or Stopped state, while the other activity is created. In case these
activities share data saved to disc or elsewhere, it's important to
understand that the first activity is not completely stopped before
the second one is created. Rather, the process of starting the second
one overlaps with the process of stopping the first one.
The order of lifecycle callbacks is well defined, particularly when
the two activities are in the same process (app) and one is starting
the other. Here's the order of operations that occur when Activity A
starts Activity B:
Activity A's onPause() method executes.
Activity B's onCreate(), onStart(), and onResume() methods execute in sequence. (Activity B now has user focus.)
Then, if Activity A is no longer visible on screen, its onStop() method executes.
This predictable sequence of lifecycle callbacks allows you to manage
the transition of information from one activity to another.
Back to your case, when you start MainActivity from FirstActivity.
FirstActivity's onPause() method executes.
MainActivity's onCreate(), onStart(), and onResume() methods execute in sequence. (MainActivity now has user focus.)
Then, if FirstActivity is no longer visible on screen, its onStop() method executes.
When the code in onClickSave executes.
SharedPreferences spTemp = this.getSharedPreferences(TEMP_KEY, MODE_PRIVATE);
spTemp.edit().clear().apply();
At this time, TEMP_KEY prefs has been cleared. After MainActivity is visible on screen, FirstActivity will be no longer visible on screen, so its onStop() method executes.
SharedPreferences sp = this.getSharedPreferences(TEMP_KEY, MODE_PRIVATE);
Gson gson = new Gson();
String objectJson = gson.toJson(object, Object.class);
String activityJson = "FirstActivity";
SharedPreferences.Editor editor = sp.edit();
editor.putString(CONTINUE_KEY, objectJson);
editor.putString(ACTIVITY_KEY, activityJson);
editor.apply();
In this code you add two entries into TEMP_KEY prefs again. So when users click on a button in MainActivity, at that time the prefs size is 2 instead of 0 as you expected.
Why is my SharedPreferences still the exact same as it was before I
cleared it?
This is predictable or expected behavior in Android. You can put a log in onCreate(), onStart(), onResume() method of MainActivity, then you can see TEMP_KEY prefs size at that time is always 0.
How can I fix this?
Do not add new entries into TEMP_KEY in onStop(), you should add in onPause() instead.
Save To Shared Preferences
SharedPreferences sp = getSharedPreferences("test" , MODE_PRIVATE);
SharedPreferences.Editor spEditor = sp.edit();
spEditor.putString("hello1" , "hello11");
spEditor.putString("hello2" , "hello22");
spEditor.apply();
Clear From Shared Preferences
SharedPreferences sp1 = getSharedPreferences("test" , MODE_PRIVATE);
SharedPreferences.Editor spEditor1 = sp1.edit();
spEditor1.clear();
spEditor1.apply();
Get From Shared Preferences
SharedPreferences sp2 = getSharedPreferences("test" , MODE_PRIVATE);
String value = sp2.getString("hello1" ,"noting");
Log.i("test_sp" , " == == ==" +value);
First, you have different preference file name for getSharedPreferences(String name, int mode), in onStop() and onClickSave() methods:
// in onStop()
SharedPreferences sp = this.getSharedPreferences(TEMP_KEY, MODE_PRIVATE);
// in onClickSave()
SharedPreferences sp getSharedPreferences(SAVE_KEY, MODE_PRIVATE);
you need to use the same file name to access the same preference.
Second, onStop() is not always guaranteed to be called, so it's not a reliable method to save your preferences. Related answer: Is onStop() always preceded by onPause()
Third, always save the preference when you need to keep the value in it. Don't wait to save it later and hoping that you can depend on either onPause(), onStop(), or onDestroy(). Never assume that your application will gracely terminate by user or system.
So I am trying to use SharedPreferences to pass a value from the Activity to a Class. The problem is the following:
On initial loading of the Activity, the value is stored in SharedPreferences but if I exit the Activity and return back, and try to update the value, the SharedPreferences does not seem to update and stays at the value of the initial load of the Activity.
Some class function
private void populatePlayerQueue(){
int category_index;
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this.getContext());
category_index = sharedPreferences.getInt("selected_category", 0);
}
Activity onResume
#Override
public void onResume() {
super.onResume();
int tmp = Integer.parseInt(getIntent().getStringExtra("CategoryIndex"));
//store the category in the shared preferences
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("selected_category", tmp);
editor.commit();
}
What I am trying to do:
I have to send an integer from the activity to a specific class and if I come back to the activity then I need to store the update value and so the class will be able to access the newly updated value again. I only have access to the context and not the activity. This causes errors if I try to create an interface callback to communicate with the activity. So this option is eliminated, hence I am trying anything I can to do that.
For some better result remove the SharedPreference through its key at the time of exit application.
In your case when you exit your application just clear the SharedPreference like:
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove("selected_category"); //Just remove it by its specific key
editor.commit();
Then it will clearly load and save the new value again when you go back to your application on the same key or you can use new one.
In my android app the user can enter the text in the EditView and the click on a button which takes him to an other activity where he can select a contact ... and then press a button which
brings him back to the first activity...
now the problem is I need to pass the selected contact to the first activity and display it (which i have done it using a bundle) but i am unable to retain already entered text in the EditView... which i should do (but the text should be retained with out passing it through the the bundle and getting it back)
thanks :)
The text in a view component is automagically saved by the OS, even after a soft kill (user changed phone orientation), but not after a hard kill, the user hit the back button while the parent activity was in focus. So, unless you are doing something non-standard, such as calling onSaveInstanceState without calling super.onSaveInstanceState, the data in the view state should persist.
One solution would be to save the text in the view component as a non view instance property before you launch the child activity, and just read this value back when the focus returns to the parent activity in the method onActivityResult.
JAL
EDIT: The Android Docs Activity page has been extensively updated. View state will not be saved if the widget does not have an ID.
EDIT: What I am saying is that the view state should be persisted by the OS. You should not need to save the view state manually. On a hard kill, you would need to save the state of your activity IF that is the expected behavior of the activity. So here is some code that saves the activity state. Given an instance variable:
String password;
Here we save state on a soft kill:
protected void onSaveInstanceState(Bundle outState){
password= editTextPassword.getText().toString();
outState.putString("password", password);
super.onSaveInstanceState(outState); // save view state
}
Here we save state on a hard kill
#Override
protected void onStop(){
super.onStop();
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("password",password);
editor.commit();
Here we restore state in onCreate(Bundle savedInstanceState):
if( savedInstanceState!= null){ // get saved state from soft kill after first pass
try {
password= savedInstanceState.getString("password");
Log.d(TAG,"RestoredState!");
}
catch(Exception e){
Log.d(TAG,"FailedToRestoreState",e);
}
}
else { // get saved state from preferences on first pass
SharedPreferences prefs = getPreferences(MODE_PRIVATE); // singleton
if (prefs != null){
this.password= prefs.getString("password","");
Log.d(TAG,"gettingPrefs");
}
}
Log.d(TAG,"onCreate");
Also given the fact that IF onSaveInstanceState is called it will be called before onStop, it is possible to use the flags isSavedInstanceState and isSavedPreferences to write to prefs ONLY on a hard kill if you reset the flags in onResume as:
protected void onResume() {
super.onResume();
Log.d(TAG,"onResume");
isSavedInstanceState= false;
isSavedPrefs= false;
}
Setting the flags in onCreate will not result in the desired outcome.
I have searched through this and a few other sites for the answer, but I have been unable to find it. I am trying to save a boolean and an int using onSaveInstanceState and onRestoreInstanceState, but I can't seem to get it to work. It doesn't crash or anything, but it either isn't saving it or it isn't restoring it, or I am stupid and have no idea what I am doing.
Here is what I have for my activity, do I need to have it in my onCreate somewhere or something?
public class CannonBlast extends Activity {
/** Called when the activity is first created. */
private panel panelStuffz;
#Override
public void onCreate(Bundle savedInstanceState) {
final Window win = getWindow();
super.onCreate(savedInstanceState);
panelStuffz = new panel(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(panelStuffz);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState){
savedInstanceState.putInt("HighLevel", panelStuffz.getLevel());
savedInstanceState.putBoolean("soundstate", panelStuffz.getSound());
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
panelStuffz.setHighLevel(savedInstanceState.getInt("HighLevel"));
panelStuffz.setSound(savedInstanceState.getBoolean("soundstate"));
}
#Override
public void onResume(){
super.onResume();
}
#Override
public void onPause(){
super.onPause();
panelStuffz.setThread(null);
}
#Override
public void onStop(){
}
I tried putting stuff in the onStop, but it crashes, which is why its empty, in case that matters, thanks in advance
Many applications may provide a way to capture user preferences on the settings of a specific application or an activity. For supporting this, Android provides a simple set of APIs.
Preferences are typically name value pairs. They can be stored as “Shared Preferences” across various activities in an application (note currently it cannot be shared across processes). Or it can be something that needs to be stored specific to an activity.
Shared Preferences: The shared preferences can be used by all the components (activities, services etc) off the applications.
Activity handled preferences: These preferences can only be used with in the activity and can not be used by other components of the application.
Shared Preferences:
The shared preferences are managed with the help of getSharedPreferences method of the Context class. The preferences are stored in a default file(1) or you can specify a file name(2) to be used to refer to the preferences.
(1) Here is how you get the instance when you specify the file name
public static final String PREF_FILE_NAME = "PrefFile";
SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
MODE_PRIVATE is the operating mode for the preferences. It is the default mode and means the created file will be accessed by only the calling application. Other two mode supported are MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE. In MODE_WORLD_READABLE other application can read the created file but can not modify it. In case of MODE_WORLD_WRITEABLE other applications also have write permissions for the created file.
(2) The recommended way is to use by the default mode, without specifying the file name
SharedPreferences preferences = PreferencesManager.getDefaultSharedPreferences(context);
Finally, once you have the preferences instance, here is how you can retrieve the stored values from the preferences:
int storedPreference = preferences.getInt("storedInt", 0);
To store values in the preference file SharedPreference.Editor object has to be used. Editor is the nested interface of the SharedPreference class.
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference); // value to store
editor.commit();
Editor also support methods like remove() and clear() to delete the preference value from the file.
Activity Preferences:
The shared preferences can be used by other application components. But if you do not need to share the preferences with other components and want to have activities private preferences. You can do that with the help of getPreferences() method of the activity. The getPreference method uses the getSharedPreferences() method with the name of the activity class for the preference file name.
Following is the code to get preferences
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
int storedPreference = preferences.getInt("storedInt", 0);
The code to store values is also same as in case of shared preferences.
SharedPreferences preferences = getPreference(MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference); // value to store
editor.commit();
You can also use other methods like storing the activity state in database. Note Android also contains a package called android.preference. The package defines classes to implement application preferences UI.
To see some more examples check Android's Data Storage post on developers site.
This method is only for saving state associated with a current instance of an Activity,are you switching to another activity and trying to get the values again when you return to this activity? i supposed that :: "I tried putting stuff in the onStop, but it crashes".
a recommendation, is NOT SAFE to use onSaveInstanceState() and onRestoreInstanceState(), according to http://developer.android.com/reference/android/app/Activity.html
consider using Sharedpreferences or SQLite database.
SharedPreferences Example (from webworld):
/**
* get if this is the first run
*
* #return returns true, if this is the first run
*/
public boolean getFirstRun() {
return mPrefs.getBoolean("firstRun", true);
}
/**
* store the first run
*/
public void setRunned() {
SharedPreferences.Editor edit = mPrefs.edit();
edit.putBoolean("firstRun", false);
edit.commit();
}
SharedPreferences mPrefs;
/**
* setting up preferences storage
*/
public void firstRunPreferences() {
Context mContext = this.getApplicationContext();
mPrefs = mContext.getSharedPreferences("myAppPrefs", 0); //0 = mode private. only this app can read these preferences
}