OnSaveInstanceState and OnRestoreInstanceState not saving on app quit - java

I am trying to save my programmatically created CardView and TextView using OnSaveInstanceState and OnRestoreInstanceState as in the sample code.
While debugging, I notice that values are saved but when I quit the app and reopen it, nothing is being restored.
What am I doing wrong?
**#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("key", userInput.getText().toString());
savedInstanceState.putInt("LayoutId", mConstraintLayout.getId());
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getString("key");
savedInstanceState.getInt("LayoutId");
}**
This are the methods I am using after 'OnCreate'
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = getApplicationContext();
mConstraintLayout = findViewById(R.id.top_left);
addButton = findViewById(R.id.add);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View popup = findViewById(R.id.popup);
popup.setVisibility(View.VISIBLE);
}
});
mButton = (Button) findViewById(R.id.create);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final CardView sticker = new CardView(mContext);
CardView.LayoutParams params = new CardView.LayoutParams(
CardView.LayoutParams.WRAP_CONTENT,
CardView.LayoutParams.WRAP_CONTENT
);
params.height=500;
params.width=500;
CheckBox privateCalendar = findViewById(R.id.checkPrivate);
CheckBox workCalendar = findViewById(R.id.checkWork);
CheckBox holidayCalendar = findViewById(R.id.checkHoliday);
if (privateCalendar.isChecked()){
sticker.setCardBackgroundColor(Color.parseColor("#FFCC00"));
}
else if (workCalendar.isChecked()){
sticker.setCardBackgroundColor(Color.parseColor("#FF8080"));
}
else if (holidayCalendar.isChecked()){
sticker.setCardBackgroundColor(Color.parseColor("#66B3FF"));
}
else{
sticker.setCardBackgroundColor(Color.parseColor("#FFCC00"));
}
sticker.setId(CardView.generateViewId());
sticker.getId();
sticker.setTag(CARD_VIEW_TAG);
sticker.setLayoutParams(params);
sticker.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
ClipData.Item item = new ClipData.Item((CharSequence) sticker.getTag());
String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData data = new ClipData(sticker.getTag().toString(), mimeTypes, item);
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(sticker);
sticker.startDrag(data
, shadowBuilder
, sticker
, 0
);
sticker.setVisibility(View.INVISIBLE);
return true;
}
});
TextView tv = new TextView(mContext);
tv.setLayoutParams(params);
tv.setBackgroundColor(Color.TRANSPARENT);
tv.setGravity(Gravity.CENTER);
userInput = findViewById(R.id.editText);
tv.setText(userInput.getText());
tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
tv.setTextColor(Color.BLACK);
sticker.addView(tv);
mConstraintLayout.addView(sticker);
View popup = findViewById(R.id.popup);
popup.setVisibility(View.GONE);
}
});
}

SavedInstanceState and RestoreInstanceState will work if activity is recreated due to config change like orientation change or android system killed that activity due to memory issue, Then only savedInstanceState and restoreInstanceState comes in role.
If you finish activity by yourself and start activity again then there is no use of these methods.

Try to save data in SharedPreference instead savedInstanceState.
SharedPreferences pref =
getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
Editor editor = pref.edit();
For Storing data:-
editor.putString("key", userInput.getText().toString());
editor.putInt("LayoutId", mConstraintLayout.getId());
editor.apply();
For retriving data:-
editor.getString("key", null); // getting String
editor.getInt("LayoutId", 0); // getting Integer

First of all if by "close the app" you mean destroy it, this will never work for you.
Second of all in onRestoreInstanceState you don't do anything with those values, you simply read them but don't store them anywhere.
If you mean to recreate the old form after switching back and forth between apps, with your app being destroyed in the background then, you need to only set values in onSaveInstanceState like you did, and in onCreate(Bundle savedInstance), you should do something like this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstance == null) {
//read values from getIntent()
key = getIntent().getString("key);
LayoutId = getIntent().getInt("LayoutId");
} else {
//read values from savedInstanceState
key = savedInstanceState.getString("key");
LayoutId = savedInstanceState.getInt("LayoutId");
}
}

Related

how to use onSaveInstanceState button that change the background layout?

I'm new to android develop. i just stated this week.
i dont know if im asking stupid question but i want to learn.
i have created an app just click a button change the background color.
my layout is this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.seluhadu.colorpicker.MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteX="136dp"
tools:layout_editor_absoluteY="1dp"
android:elevation="8dp"
android:layout_alignBaseline="#+id/button3"
android:layout_alignBottom="#+id/button3"
android:layout_alignParentEnd="true"
android:layout_marginEnd="52dp"/>
</RelativeLayout>
and i have a class "java" like this
public class MainActivity extends AppCompatActivity {
Button button;
RelativeLayout relativeLayout;
Integer[] colors = {
R.color.color1,
R.color.color2,
R.color.color3,
R.color.color4,
R.color.color5,
R.color.color6,
R.color.color7,
R.color.color8,
R.color.color9,
R.color.color10,
R.color.color11,
R.color.color12,
R.color.color13,
R.color.color14,
R.color.color15,
R.color.color16,
R.color.color17,
R.color.color18,
R.color.color19,
R.color.color20
};
Random random;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
random = new Random();
relativeLayout = (RelativeLayout) findViewById(R.id.background);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
relativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(),
colors[random.nextInt(colors.length)]));
}
});
}
it just change the background color random.
when it change the color if i rotat the screen it change to default back.
my question is how to make a onSaveInstanceState and onRestoreInstanceState method to save the change color even if i reopen the app to stay the color that i change.
OR how can i do like that in other way?
thank you for your help!
When your activity is recreated after it was previously destroyed, you can recover your saved state from the Bundle that the system
passes your activity. Both the onCreate() and onRestoreInstanceState()
callback methods receive the same Bundle that contains the instance
state information.
Because the onCreate() method is called whether the system is creating
a new instance of your activity or recreating a previous one, you must
check whether the state Bundle is null before you attempt to read it.
If it is null, then the system is creating a new instance of the
activity, instead of restoring a previous one that was destroyed.
public class MainActivity extends AppCompatActivity {
Button button;
RelativeLayout relativeLayout;
Integer[] colors = {
R.color.color1,
R.color.color2,
R.color.color3,
R.color.color4,
R.color.color5,
R.color.color6,
R.color.color7,
R.color.color8,
R.color.color9,
R.color.color10,
R.color.color11,
R.color.color12,
R.color.color13,
R.color.color14,
R.color.color15,
R.color.color16,
R.color.color17,
R.color.color18,
R.color.color19,
R.color.color20
};
Random random;
Boolean backgroundChanged = false;
int colorIndex;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore background color from saved state
backgroundChanged = savedInstanceState.getBoolean("backgroundChanged", false);
colorIndex = savedInstanceState.getInt(colorIndex, 0);
}
random = new Random();
relativeLayout = (RelativeLayout) findViewById(R.id.background);
if(backgroundChanged) {
relativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), colors[colorIndex]));
}
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
backgroundChanged = true;
colorIndex = random.nextInt(colors.length);
relativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), colors[colorIndex]));
}
});
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean("backgroundChanged", backgroundChanged);
if(backgroundChanged) {
savedInstanceState.putInt("colorIndex", colorIndex);
}
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
Update
Here's my code below, plugged into your posted example:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
random = new Random();
relativeLayout = (RelativeLayout) findViewById(R.id.background);
button = (Button) findViewById(R.id.button);
SharedPreferences settings = getSharedPreferences("myPrefs", 0);
int colorIndex = settings.getInt("colorIndex", 0);
updateBackground(colorIndex);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int colorIndex = random.nextInt(colors.length);
SharedPreferences settings = getSharedPreferences("myPrefs", 0);
settings.edit().putInt("colorIndex", colorIndex).apply();
updateBackground(colorIndex);
}
});
}
private void updateBackground(int colorIndex) {
relativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), colors[colorIndex]));
}
If you have to store the color even through app restarts, you should use SharedPreferences instead of using onSaveInstanceState().
In your onClick(), when you generate the random index for your color array, write that value to your SharedPreferences object. In onCreate() when you set everything up, read the value out of the SharedPreferences.
To write:
int colorIndex = random.nextInt(colors.length);
SharedPreferences settings = getSharedPreferences("myPrefs", 0);
settings.edit().putInt("colorIndex", colorIndex).apply();
To read:
SharedPreferences settings = getSharedPreferences("myPrefs", 0);
int colorIndex = settings.getInt("colorIndex", 0);

Use shared preferences in checkbox to make checked for always when button is clicked

I am using shared preferences to make the ckeckbox checked for always when button is clicked. But I'm getting errors, unknown type 'getChecked'. , code is givenbellow:
#Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SharedPreferences sharedPreferences = this.getSharedPreferences("pref", 0);
boolean checkedSearch = sharedPreferences.getBoolean("checkedSearch", false);
Button button = (Button) dialog.findViewById(R.id.button);
final CheckBox checkBox1 = (CheckBox) dialog.findViewById(R.id.checkBox1);
checkBox1.setChecked(checkedSearch ? true : false );
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if(
checkBox1.getChecked()==false){
checkBox1.setChecked(true);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("checkedSearch",true)
.commit();
}
final SharedPreferences sharedPreferences=this.getSharedPreferences("pref", 0);
you have missed = sign

Android: Accessing SharedPreferences inside a DialogFragment

So I have an activity with a few buttons each one with a TextView bellow, when I click on the button appears a Dialog Fragment with an EditText and a 'Done' button, I write something in the EditText, click 'Done' and ti changes the Text bellow the button I clicked, that is working fine. What I need is to replace the previous text with the new text in the shared preferences I that I already have.
My SharedPreferences: SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
Opening the Dialog and passing the TextView's ID:
fm = getFragmentManager();
myFragment = new Fragment_Subject_Edit();
FirstButton.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Bundle data = new Bundle();
data.putInt("ID", FirstText.getId());
myFragment.setArguments(data);
myFragment.show(fm, "ClassEditor");
return false;
}
});
Recieve ID in the Dialog Fragment:
if (getArguments() != null) {
Bundle data = getArguments();
int id = data.getInt("ID");
mTextView = (TextView) getActivity().findViewById(id);
}
Adding the new text to the TextView bellow the button:
DoneButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String newText = mEditText.getText().toString();
mTextView.setText(newText);
getDialog().dismiss();
}
});
The question here is really just how to update the Shared Preferences
You will simply use Editor to save your new data on SharedPreferences
So in this case your code will be like this
DoneButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String newText = mEditText.getText().toString();
mTextView.setText(newText);
SharedPreferences.Editor e = getActivity().getPreferences(Context.MODE_PRIVATE).edit();
editor .putString ("key","your_value");
editor .commit();
getDialog().dismiss();
}
});

Reload SharedPreferences

I'm quite new to Android Prorgramming and have a problem understandig SharedPreferences.
I have a Main Activity and a Settings Activity.
I want to be able to change a SharedPreference (here called firstWaitTime) in the Settings Activity and work with it in the Main Activity.
I can Set the new value in the settings, but in the Main Activity i only see the new value when i close and reopen the app.
I Think i would need a OnPrefrenceChanged Listender but i have no idea how to implement it...
The Main one looks like this:
public class MainActivity extends ActionBarActivity {
//Radio Button
private int stufe;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences settings = this.getSharedPreferences("settings", Context.MODE_PRIVATE);
int firstWaitTime = settings.getInt("firstWaitTime", 12);
int secondWaitTime = settings.getInt("secondWaitTime", 8);
int thirdWaitTime = settings.getInt("thirdWaitTime", 6);
//TEST
final TextView test = (TextView) findViewById(R.id.test);
test.setText("" + firstWaitTime);
}
The Settings Activity looks like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
final SharedPreferences settings = this.getSharedPreferences("settings", MODE_PRIVATE);
//BUTTON
final EditText edit1 = (EditText) findViewById(R.id.edit1);
Button save=(Button) findViewById(R.id.savebtn);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//prefs = getSharedPreferences(prefName, MODE_PRIVATE);
//SharedPreferences.Editor editor = prefs.edit();
SharedPreferences.Editor editor = settings.edit();
//---save the values in the EditText view to preferences---
editor.putInt("firstWaitTime", Integer.parseInt(edit1.getText().toString()));
//---saves the values---
editor.commit();
Toast.makeText(getBaseContext(), "Saved", Toast.LENGTH_SHORT).show();
}
});
}
What is the best way to achieve this?
onCreate() will not be called as Android hasn't killed the Activity. Try putting your code in onResume() instead. For more info read up on the Android Activity lifecycle.

How to maintain CheckBox state across the activities

How to maintain CheckBox state across the activities
I checked a CheckBox in FirstActivity.java but when i move back to FirstActivity.java from any other activity, say from SecondActivity.java..
Then, I am not getting my CheckBox as check which i checked earlier.
Using onSaveInstanceState & onRestoreInstanceState, see complete code below:-
public class FirstActivity extends Activity {
CheckBox cb1;
Button btnNext;
private boolean boolCheck1 = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cb_cb1 = (CheckBox) findViewById(R.id.cb1);
btnNext = (Button) findViewById(R.id.btnNext);
// control status of body frame checkboxes
cb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked){
}
}
});
btnNext.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putBoolean("Enable", cb1.isChecked());
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
boolCheck1 = savedInstanceState.getBoolean("Enable");
}
}
Your best option is to use sharedPreferences.
In your activity where the checkbox is located, in your onCreate() put the following:
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
Editor editor = pref.edit();
Then, in your intent to go to another activity, or "save" button, or whatever you want, use the following:
editor.putBoolean("checkbox", yourCheckbox.isChecked());
editor.commit(); // commit changes
Now, the setting is saved.
When you come back to your activity, use this in your onCreate:
if (pref.getBoolean("checkbox", false) == true){ //false is default value
yourCheckbox.setChecked(true); //it was checked
} else{
yourCheckbox.setChecked(false); //it was NOT checked
}
You can read more here.
Hope this helped
Use SharedPreferences or SQLiteDatabase to store the value of check box and you can use it after fetching from Database or SharedPreference.
If you use onSaveInstanceState & onRestoreInstanceState all reference will clear when user close the app and the app is no longer in Memory.
Tutorial for SharedPreference
Tutorial for Database
To maintain state across activities you have to use SharedPreferences, or database. In your case SharedPreferences is the best option
You have used OnSavedInstance it will only save the instance until the activity is not destroyed i.e it stays on the stack.
Check activity lifecycle to understand more about when an activity is destroyed.
For each checkbox you can store its value in sharedPreference and on
onCreate() of you activity you should check the checkboxes according
to the sharedPreference values
Here is how you use shared prefs
SharedPreferences prefs= context.getSharedPreferences("myPrefs", 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("checkbox1", true);//true if checked
editor.commit();
// get stored value , if no value is stored then assume its false
prefs.getBoolean("checkbox1", false);

Categories