I have an app that is supposed to do the following: The first (main) activity displays a passcode that changes every minute.The time remaining in seconds before the passcode changes. The first activity also has a button to verify the passcode. Once the user clicks the “Verify” button in the first activity, the second activity (verification window) should be launched and become visible to the user. The second activity should have a ListView that displays all timestamps for all passcodes that were previously generated, and one button to clear the list. Once the user exits the app, the list will clear but the last timestamp will be stored in a shared preference and will be restored the next time the user opens the application.The application should support landscape and portrait orientations and should handle screen orientation changes at run time.
So far everything should be working until the point where the app's last timestamp is saved in shared preferences. When I exit the app and reload it the timestamp is not saved and unsure why. I have included the code below. Thanks hopefully someone can help.
package com.example.security_token_app;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;
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
{
static String PREF_NAME = "SharedPrefFile";
static SharedPreferences SavedTimeStamp;
static SharedPreferences.Editor editor;
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;
@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);
SavedTimeStamp = getSharedPreferences(PREF_NAME,0);
editor = SavedTimeStamp.edit();
createPassCode();
new CountDownTimer(60000, 1000) //changed from 60000 for test
{
@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)
{
if(MainActivity2.isSaved==true)
{
MainActivity2.restoreTimeStamp();
}
openSecondaryActivity();
}
});
}
public void createPassCode()
{
int minute = Calendar.getInstance().get(Calendar.MINUTE);
passCode=minute*1245 10000;
String timeStamp = getTimeStamp();
//if(isSaved==true) restore
arrayIntegerList.add(timeStamp);
//MainActivity2.isSaved=false;
String passCodeStr = Integer.toString(passCode);
passCodeTextView.setText(passCodeStr);
}
public void openSecondaryActivity()
{
Intent intent = new Intent(this, MainActivity2.class);
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;
}
}
package com.example.security_token_app;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
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
{
ArrayList<String> arrayList = new ArrayList<String>();
ListView listView;
Button clearButton;
int count;
String item;
static ArrayAdapter<String> adapter;
static boolean isSaved = false;
boolean adapterSet = 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);
for(String temp:MainActivity.arrayIntegerList)
{
arrayList.add(temp);
}
//adapter resset here? loses the saved time stamp
if(isSaved==true) //added
{
isSaved=false;
return;
}
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,arrayList);
listView.setAdapter(adapter);
clearButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
count = adapter.getCount();
item = adapter.getItem(count-1);
adapter.clear();
adapter.add(item);
saveTimeStamp();
}
});
}
public void saveTimeStamp()
{
int i = adapter.getCount();
if(isSaved==true) //changed from i==1
{
return;
}
String lastTimeStamp = adapter.getItem(i-1);
if(!lastTimeStamp.isEmpty())
{
MainActivity.editor.putString(MainActivity.TIMESTAMP_KEY, lastTimeStamp);
MainActivity.editor.commit();
Toast.makeText(getBaseContext(), "time stamp saved", Toast.LENGTH_SHORT).show();
isSaved = true;
}
else
{
Toast.makeText(getBaseContext(), "nothing saved", Toast.LENGTH_SHORT).show();
return;
}
}
public static void restoreTimeStamp()
{
String lastTimeStamp = MainActivity.SavedTimeStamp.getString(MainActivity.TIMESTAMP_KEY, "NOT LOCATED");
adapter.add(lastTimeStamp); //adapter is being added not instantiated yet
//Toast.makeText(getBaseContext(), "time stamp restored", 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>
CodePudding user response:
count = adapter.getCount();
item = adapter.getItem(count-1);
adapter.clear();
adapter.add(item);
saveTimeStamp();
Can you try calling saveTimeStamp() before clearing adapter? Like this
saveTimeStamp()
count = adapter.getCount();
item = adapter.getItem(count-1);
adapter.clear();
adapter.add(item);
CodePudding user response:
I recommend you to create SharedPreferences in App class.override oncreate method in this class
public class App extends Application{
public static SharedPreferences prefs;
@Override
public void onCreate(){
super.onCreate();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
}
Then you can use prefs everywhere in your project like this:
editor = App.prefs.edit();