I'm creating an app that require user to enter name, email, date and etc in Main_Activity.xml. Then, the user will click submit. The entered data will be displayed in confirm.xml. In confirm.xml, user need to verify entered data and if the want to edit entered data, they will click back button to edit data again. I tried to do that but once I click back button, all the data I entered in editText field disappeared. I want to keep the data I entered in MainActivity.xml's editText field, so I can change only some field that need to be edited. How can I do this? Thank you.
This can happen when the activity where you entered data is destroyed. How do you open the new confirmation activity? That's the part of the code that probably contains the error.
If you call finish() when you open the new activity then activity will be destroyed and data kept in EditText cleared.
To open a new activity and preserve data of the current one you just need to call startActivity(...) without finish().
Intent intent = new Intent(context, ConfirmationActivity.class);
startActivity(intent);
Anyway, the activity can be destroyed by android to free up memory when needed. That happens when you open another application that needs memory but memory is used by your application, so the system destroys your activities and it's up to you to save data on disk by using Bundles and restoring them.
I suggest you to read this guide https://developer.android.com/guide/components/activities/activity-lifecycle.html
You can overwrite the onSaveInstanceState(Bundle savedInstanceState) function and use the savedInstanceState to save the various data that you want to get back during the onCreate(Bundle instanceState) or onRestoreInstanceState(Bundle instanceState).
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("TextFieldX", "Data To Retrieve");
}
And get it back:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//get back value
String value = savedInstanceState.getString("TextFieldX");
}
https://developer.android.com/reference/android/os/Bundle.html
For longer lived persistance of your data, you would write it to SQLite.
You can save all your information to String's like private String Name;
write/set this Name when user enter's the Name and use it again like as follows:
if(name != null && !name.toString().isEmpty()) {
set name String on your editText widget.
}
You can use shared preference object to save value of edittext value in user's phone. When code execute second time, you just check about variable in shared preference. If variable is not null, fetch value from it and set that string using setText() method.
Related
I'm having a problem with SavedInstanceStates. In the Main Activity of my app, a listview is populated with names from a database. When you click on one of the names, a new activity is opened, which shows another listview drawn from a separate database and details various information about the person. The items on this listview are only shown if their characterID, set according to the person whose name they are created under, and the id of the person in the original database match. So long story short, you can create a person Trevor, there are then a number of pieces of information shown specific to Trevor when you click on Trevor. You can also click on those pieces of information to open a new activity and edit that info/ do stuff with the info. I did this by saving the Uri of the person clicked with setData, and then getting that uri with getData and parsing the id from it for my second query.
When a user clicks a piece of information about Trevor and it opens in a new activity, the variable containing the id is destroyed as is the data I set in the first activity. So when I click back, it crashes due to a NullPointerException. So I now check if the data from getData() is null before performing my database query. But that just leaves the listview empty since it has no id to use when querying the database.
So I tried to used onSaveInstanceState to save the characterId variable. But using onRestoreInstanceState doesn't seem to work. Navigating to the third activity, and then finishing it by clicking back, does not seem to call onRestoreInstanceState. I also tried to check if the savedInstanceState is null in onCreate, see if it contains they key I set, and then withdraw it, but the savedInstanceState is null in onCreate whether Im first navigating to it, or hitting the back button to return to it. I've looked around for a few hours trying to figure out the answer. Is this the wrong tool for the job? Am I missing something?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_catalog);
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(savedCIdString)) {
characterId = savedInstanceState.getInt(savedCIdString);
}...
A snippet of my onCreate where I try to retrieve the variable, but SavedInstanceState is null when I first navigate to it, and when I press back from the activity after it.
#Override
protected void onSaveInstanceState (Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt(savedCIdString, characterId);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
characterId = savedInstanceState.getInt(savedCIdString);
}
When turn the switch on it stays on.. however when i leave the activity and come back to it.. it goes back to off. I want it to stay ON OR OFF depending on whats last pressed. I have tried the code below but does not resolve my issue
SwitchButton.setChecked(true);
SwitchButton.setChecked(false);
What you need to do is override these methods in your activity:
#Override
protected void onSaveInstanceState (Bundle outState){
super.onSaveInstanceState(outState);
outState.putBoolean("CHECKED", SwitchButton.isChecked());
}
then in onCreate:
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstaceState);
if(savedInstanceState != null){
boolean isChecked = savedInstanceState.getBoolean("CHECKED");
SwitchButton.setChecked(isChecked);
}
}
If you are minimizing the activity and then returning back to it, and you want all controls to retain their states, then look into implementing saved instance state. This will persist the control values while you minimize / maximize the activity or rotate it. No data is permanently saved to the device. Sample code here:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
If you are closing the app completely and want the app to remember the settings, then consider SharedPreferences, which can be used to save data locally on the device. The data persists until your app explicitly deletes it or you uninstall the app. Sample code here:
http://developer.android.com/training/basics/data-storage/shared-preferences.html
I am wondering what the best method is to check if it is the first time a certain user has used my app, and also when they update will it reset and make it think they are a new user.
Edit(For more precision): I want to store a user id number in my sql server, and I want every user to create a password when they first download, but I also want them to have the option to select "Already have account" so that they can sync their accounts across devices
Like Illegal Argument mentions, the most reliable way is to use a server, because if you use a Shared preference, the user can delete the data or move to a different device and appear to be a totally new user.
If you don't want to go through the trouble of creating and managing your own server, you might consider using Google's Cloud Save API. When your app starts, check for existing data in the cloud. If there's nothing there it's a new user so create the data. It should be as simple as that.
The most reliable way to know that the user is a first time user is via a server validation. Another way to do it would be to use shared preference and saving certain data in internal or external storage. However storing data in mobile is not so foolproof as data can be easily deleted by user.
Globals
String _StrCode="";
SharedPreferences preferences;
String _responseCode=null;
In oncreate but before set content view check
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
preferences = getSharedPreferences("mypref", 0);
_StrCode= preferences.getString("Code", _StrCode);
if(_StrCode.equalsIgnoreCase("")){
setContentView(R.layout.activity_qdc_status__launcher);
// here you can assign a value to
_StrCode ="some value";
Editor prefsEditor = preferences .edit();
prefsEditor.putString("Code",_StrCode);
prefsEditor.commit();
}else{
Intent _in= new Intent(firstscreen,secondscreen.class);
startActivity(_in);
finish();
}
}
i hope this will halp you and its easy to understand too.
I have an activity that queries a server database and returns a list of results...while querying the app displays a simple progressDialog on the onCreate method like so:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//display progress dialog while querying server for values
final ProgressDialog dialog = ProgressDialog.show(this,"","Retrieving listings please wait...");
dialog.setCancelable(true);
dialog.show();
If the user clicks on an item from the list then another activity placeDetails is opened. Once done a user can press the back button to go back to the previous activity which displays the listings.
When I tested it naturally it shows the above dialog and sends the query back to the server even though the listings can be seen in the background of the progressDialog.
What I want to know is how would I prevent the database being queried again and the above progressDialog from displaying when the user presses the back button.
Do I have to go down the caching route? or is there another way?
1.) To prevent the database from being queried again you can simply cache this data in a local SQLite database as Tom Dignan mentioned.
2.) To prevent the progressDialog from displaying when the user presses the back button, simply override the onBackPressed() method of the current activity (when back is pressed) and set an Intent to the activity that preceeds the progresDialog. I believe there's even a method to do this so that you won't be starting a new instance of that activity but simply accessing a cached version.
I managed to solve this issue the missing link was I did not know how to check for dialog windows the following code helped:
//first declare the dialog so its accessible globally through out the class
public class ListPlaces extends ListActivity {
ProgressDialog dialog;
then on the onCreate first check that a dialog exists or not
if(dialog == null){
dialog = ProgressDialog.show(this,"","Retrieving listings please wait...");
//display progress dialog while querying server for values
dialog.setCancelable(true);
dialog.show();
}
And the mistake was I was using
dialog.hide();
instead of
dialog.dismiss();
Thanks for the contributions
i have an app that has three pages, one of them is the main page. the user can enter in a few fields that i would like to save if the user goes to one of the two sub pages. i have been looking into the onPause() and into onSaveInstanceState(). i guess i just want a clear explanation on the two, and if onPause() is better and example of the code. this is what i ahve for onSaveInstanceState().
protected void onSaveInstanceState(Bundle outState) {
// Save away the original text, so we still have it if the activity
// needs to be killed while paused.
outState.putDouble("quizPts",qpts);
outState.putDouble("quizV",qvalue);
outState.putDouble("tPts",tpts);
outState.putDouble("tValue", tvalue);
outState.putDouble("hPts", hpts);
so that is how i am setting up bundle, by giving it an ID and a value.
public void onRestoreInstanceState(Bundle outState) {
super.onRestoreInstanceState(outState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
qpts = outState.getDouble("quizPts");
qvalue = outState.getDouble("quizV");
tpts = outState.getDouble("tPts");
tvalue = outState.getDouble("tValue");
hpts = outState.getDouble("hPts");
this is how i plan to retore it, the problem is i dont understand how to pass the Bundle around to restore it. i am setting the variables that i need to back to the variables that get set to the UI.
any advice would be great
thanks from a beginner androider
The best option will be a shared preference. The onpause is designed for attending your concerns when app is paused due to a phone call or something. But if you use shared preference it gives you the method for saving your data and recover it wit default values if the saved value is not available. This data will persist across user sessions (even if your application is killed). But it is not a good option if you are planning to save something other than primitive data types like bool,int etc.
see http://developer.android.com/guide/topics/data/data-storage.html#pref
You don't need to pass the bundle around yourself: the Activity framework takes care of that. Use onSaveInstanceState(): if your Activity class is destroyed for any reason by the system it will be called so you should be fine putting your logic in there. onPause will always be called if you leave your Activity, regardless of if the Activity is destroyed.
I would also add a check in your onRestoreInstanceState:
public void onRestoreInstanceState(Bundle outState) {
super.onRestoreInstanceState(outState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
if(outState.containsKey("quizPts")) qpts = outState.getDouble("quizPts");
if(outState.containsKey("quizV")) qvalue = outState.getDouble("quizV");
if(outState.containsKey("tPts")) tpts = outState.getDouble("tPts");
if(outState.containsKey("tValue")) tvalue = outState.getDouble("tValue");
if(outState.containsKey("hPts")) hpts = outState.getDouble("hPts");