Stack Exchange
Android Saved Instance State Not Saving (Dual Activity)
Hi my MainActivity and MainActivity2 are supposed to be saving the instance state, but when I rotate the device into landscape it does not save the time, the timer restarts. My app is a log in verication that displays time stamps when you click the verify button, right now I am trying to save the timer when I rotate the device, but it is not saving I will include the code below thanks. Update when I comment out onRestoreInstanceState and run the program it says that I am getting a NumberFormatException in onSaveInstanceState not sure.
 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.security_token_app, PID: 15284
    java.lang.NumberFormatException: For input string: "seconds remaining: 50"
        at java.lang.Long.parseLong(Long.java:594)
        at java.lang.Long.parseLong(Long.java:636)
        at com.example.security_token_app.MainActivity.onSaveInstanceState(MainActivity.java:117)
        at android.app.Activity.performSaveInstanceState(Activity.java:1609)
        at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1447)
        at android.app.ActivityThread.callActivityOnSaveInstanceState(ActivityThread.java:5071)
        at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:4400)
        at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:4364)
        at android.app.ActivityThread.handleStopActivity(ActivityThread.java:4439)
        at android.app.servertransaction.StopActivityItem.execute(StopActivityItem.java:41)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1955)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7078)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

package com.example.security_token_app;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.PersistableBundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.Calendar;

public class MainActivity extends AppCompatActivity
{
    private static String SHARED_PREF_NAME = "SharedPrefFile";
    SharedPreferences sharedPreferences;
    SharedPreferences.Editor editor;
    private static String TIMESTAMP_KEY = "TIMESTAMP_KEY";
    private TextView countDownTextView;
    TextView passCodeTextView;
    static int passCode;
    static String currentDateTime;
    static ArrayList<String> arrayIntegerList = new ArrayList<String>();
    Button verifyButton;

    private static String LOG_TAG = "log state 1";
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        countDownTextView = (TextView)findViewById(R.id.textView4_time_remaining);
        passCodeTextView= (TextView)findViewById(R.id.textView3_passCode_int);
        verifyButton = (Button)findViewById(R.id.button1);
        sharedPreferences = getSharedPreferences(SHARED_PREF_NAME,MODE_PRIVATE);

        createPassCode();
            new CountDownTimer(60000, 1000)
            {
                @Override
                public void onTick(long timeUntillFinished)
                {
                    countDownTextView.setText("seconds remaining: " + timeUntillFinished / 1000 % 60);
                }

                @Override
                public void onFinish()
                {
                    createPassCode();
                    start();
                }
            }.start();
            verifyButton.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View view)
                {
                    String check = sharedPreferences.getString(TIMESTAMP_KEY, null);
                    Log.i("k1","timestamp: "+check);
                    if(check != null)
                    {
                        arrayIntegerList.add(check);
                        Toast.makeText(getBaseContext(), "restored", Toast.LENGTH_SHORT).show();
                    }
                    openSecondaryActivity();
                }
            });
    }
    public void createPassCode()
    {
        int minute = Calendar.getInstance().get(Calendar.MINUTE);
        passCode=minute*1245 + 10000;
        String timeStamp = getTimeStamp();
        arrayIntegerList.add(timeStamp);
        String passCodeStr = Integer.toString(passCode);
        passCodeTextView.setText(passCodeStr);
    }

    public void openSecondaryActivity()
    {
        Intent intent = new Intent(this, MainActivity2.class);
        intent.putExtra("timestamp_list", arrayIntegerList);
        startActivity(intent);
    }

    public static int getPassCode()
    {
        return passCode;
    }

    public static String getTimeStamp()
    {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        currentDateTime = dateFormat.format(new Date());
        return currentDateTime;
    }

@Override
public void onSaveInstanceState(@NonNull Bundle outState)
{
    super.onSaveInstanceState(outState);
    TextView textView = (TextView) findViewById(R.id.textView4_time_remaining);
    long savedData = Long.parseLong(textView.getText().toString());
    outState.putLong("outStateKey", savedData);

}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState)
{
    super.onRestoreInstanceState(savedInstanceState);
    long storedData = savedInstanceState.getLong("outStateKey");
    TextView textView = (TextView)findViewById(R.id.textView4_time_remaining);
    textView.setText(Long.toString(storedData));
}

}

package com.example.security_token_app;
import androidx.appcompat.app.AppCompatActivity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;

public class MainActivity2 extends AppCompatActivity
{
    SharedPreferences sharedPreferences;
    private static String SHARED_PREF_NAME = "SharedPrefFile";
    private static String TIMESTAMP_KEY = "TIMESTAMP_KEY";
    ArrayList<String> arrayList = new ArrayList<String>();
    ListView listView;
    Button clearButton;
    int count;
    String item;
    static ArrayAdapter<String> adapter;
    static boolean isSaved = false;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        listView = (ListView) findViewById(R.id.listView1);
        clearButton = (Button) findViewById(R.id.passButton);
        sharedPreferences = getSharedPreferences(SHARED_PREF_NAME,MODE_PRIVATE);

        ArrayList<String> timestampList = (ArrayList<String>)getIntent().getSerializableExtra("timestamp_list");
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, timestampList);
        listView.setAdapter(adapter);

        clearButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                count = adapter.getCount();
                String checkFirstPass = sharedPreferences.getString(TIMESTAMP_KEY,null);
                Log.i("k2","timestamp: "+checkFirstPass);
                if(checkFirstPass==null)
                {
                    item = adapter.getItem(count - 1);
                }
                else if(checkFirstPass!=null)
                {
                    item = adapter.getItem(count-2);
                }
                adapter.clear();
                adapter.add(item);
                saveTimeStamp(item);
            }
        });
    }

    public void saveTimeStamp(String lastItem)
    {
        if(!lastItem.isEmpty())
        {
            sharedPreferences = getSharedPreferences(SHARED_PREF_NAME,MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putString(TIMESTAMP_KEY, lastItem);
            editor.apply();
            Toast.makeText(getBaseContext(), "time stamp saved", Toast.LENGTH_SHORT).show();
        }
        else
        {
            Toast.makeText(getBaseContext(), "nothing saved", Toast.LENGTH_SHORT).show();
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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/root_constraint_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/linear_layout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:layout="@layout/activity_main">

        <TextView
            android:id="@+id/textView1_blueBox"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_gravity="center"
            android:layout_weight="0.25"
            android:background="@color/sky_blue"
            android:text="test" />

        <TextView
            android:id="@+id/textView2_passCode_string"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.5"
            android:textAlignment="center"
            android:text="PASS CODE"
            android:textStyle="bold"
            android:textSize="38sp"/>

        <TextView
            android:id="@+id/textView3_passCode_int"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.5"
            android:textAlignment="center"
            android:textSize="38sp"
            android:textStyle="bold"
            android:text="test" />

        <TextView
            android:id="@+id/textView4_time_remaining"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.5"
            android:textAlignment="center"
            android:textSize="24sp"
            tools:text="1:00 seconds remaining"/>

        <Button
            android:id="@+id/button1"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_gravity="center"
            android:text="Verify"
            android:textStyle="bold"
            />




    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity2">

    <LinearLayout
        android:id="@+id/linear_layout1"
        android:layout_width ="match_parent"
        android:layout_height ="match_parent"
        android:orientation="vertical"
        tools:layout="@layout/activity_main">

        <TextView
            android:id="@+id/textView1_blueBox"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_gravity="center"
            android:layout_weight="0.25"
            android:background="@color/sky_blue" />

        <ListView
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:textStyle="bold"
            android:dividerHeight="32dp"
            />

        <Button
            android:id="@+id/passButton"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_gravity="center"
            android:text="PASS"
            android:textStyle="bold"
            />









    </LinearLayout>


</androidx.constraintlayout.widget.ConstraintLayout>


This might help you

ViewModel
Use ViewModelenter link description here
It's no problem to rotate
You can learn about the login module of Android studio
enter image description here

How can I implement ViewModel can you be more specific please? Thanks.

but these methods that I have written already should work though..?

Use  ViewModel to solve this problem
if you need a practical implementation of how to use this here

but these methods that I have written already should work though..?

save the current value of timer  use inside of OnPause() method it may work

I can try but not exactly sure what you mean, usually people answer these questions with code and test to see if it works, thats how they gain reputation points.

I have updated the code it is getting a numberformat exception from the onsaveinstancestate method
