In my app I want a string to be passed to the server only at the startup of application.
I have used SharedPreferences to check if the string is sent or not.
this code runs at star of MainActivity
pref=getPreferences(MODE_PRIVATE);
Sent=pref.getString("ID_SENT", "");
if(Sent.equals(""))
{
SharedPreferences.Editor editor=pref.edit();
editor.putString("ID_SENT","NO");
editor.commit();
Sent=pref.getString("ID_SENT","");
}
Now after the string is sent to the server in onPostExecute of AsyncTask this code is used to set the variable ID_SENT to YES:
Sent=pref.getString("ID_SENT", "");
if(Sent.equals("NO"))
{
SharedPreferences.Editor editor=pref.edit();
editor.putString("ID_SENT","YES");
editor.commit();
}
Now the problem is when I close the app and start the app again it doesn't send the string to server because it finds ID_SENT set to YES.
So is there any way so that I can set ID_SENT to no as the back button is pressed while on MainActivity?
EDIT:
I set launch mode of MainActivity to singleTop. So now activity resumes whenever I press home button from another activities. And the string is not sent everytime because MainActivity is only resumed.
So is there any way so that I can set ID_SENT to no as the back button is pressed while on MainActivity?
Yes,
#Override
public void onBackPressed()
{
// do your save logic here
}
Or you could override onDestroy(), this may be safer in case Android destroys the Activity to reclaim memory
Related
I am trying to re-open last activity on icon press. But it starts from splash when I remove launchMode SingleTask from main.
Below is the scenario -
A = Splash , B = Activity1 , C = Activity 2.
I want to launch C on icon press.
On Start
A ---->B---->C (Here home icon pressed)
On Click Icon It runs A but I want C . Can any one solve this?
Launching C-
Intent urlIntent = new Intent(this,C.class);
urlIntent.putExtra("stt",Str);
startActivityForResult(urlIntent,REQUEST_CODE);
CASE I. Check if your app is in background after pressing the home button. If it is then it should open activity C.
CASE II. If your app is killed due to low on memory then it will start from launcher activity i.e. activity A.
I also faced this issue. This issue occurred due to changed setting of device.If user enable "Don't keep activities" then all activities will be destroyed if you press home or start new activity.
Note: I used the default launch mode
Your app will always start from the Activity with the filter intent.action.MAIN in the Manifest.xml.
And if your application is already running then the next time time your app starts it will automatically resume from the last opened activity.
Now if your app gets killed or swiped out then you can store the activity in SharedPreferences when activity is resumed or paused and on next start check in your spash which is Activity 'A' in your case, which was the last opened activity as you had stored the Activity name in SharedPreferences.
Example :
If you have three activities A-->B-->C
store the name in onPause() of all activities use SharedPreference to store its name :
#Override
protected void onPause() {
super.onPause();
SharedPreferences prefs = getSharedPreferences("Pref", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("lastOpenedActivity", getClass().getName());
editor.apply();
}
And in your Splash which is here Activity A use this preference to checfk in your onCreate() -
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Class lastActivity;
try {
SharedPreferences prefs = getSharedPreferences("Pref", MODE_PRIVATE);
lastActivity = Class.forName(prefs.getString("lastOpenedActivity", ParentActivity.class.getName()));
} catch (ClassNotFoundException ex) {
lastActivity = ParentActivity.class;
}
startActivity(new Intent(this, lastActivity));
this.finish();
}
I have two activities. Activity A has a button which starts activity B. When you hit the back button in activity B it restarts activity A. Also when the back button is hit it goes to the onStop method for activity B and in this point I update shared preferences for the user. Basically I'm storing player data on the shared preferences but the problem is when activity A is restarted I also load the same shared preferences but it doesn't show the updated data that I saved while activity B was stopped. I reload the app and it shows the up to date data. So it seems that while it is being saved while activity B is being stopped there isn't enough time for when it is loaded while activity A is being restarted. So how can I tell whether the shared preferences have finished being written to or not? Basically I want to load the shared preferences once I know for sure the shared preferences has been updated, is that possible?
I am using commit method:
#Override
protected void onStop()
{
Long dist = (long)treadmill_.Mod.distance_;
Long newdist = dist + PlayerInfoManager.getInstance().getDistanceTraveled();
PlayerInfoManager.getInstance().setDistanceTraveled(newdist);
float fastestSaved = PlayerInfoManager.getInstance().getFastestSpeedAcheived();
float fastestInSess = treadmill_.Mod.fastestSpeed;
if(fastestSaved<fastestInSess)
PlayerInfoManager.getInstance().setFastestSpeedAcheived(fastestInSess);
Long time = (long)treadmill_.Mod.time_;
Long newTime = time + PlayerInfoManager.getInstance().getTotalTimeRan();
PlayerInfoManager.getInstance().setTotalTimeRan(newTime);
Log.e("OnStop", "at Run, run, run");
super.onStop();
}
In PlayerInfoManager.getinstance().setDistanceTraveled(newdist):
public void setDistanceTraveled(Long distanceTraveled)
{
DistanceTraveled = distanceTraveled;
Editor edit = SP.edit();
edit.putLong("DistanceTraveled", distanceTraveled);
edit.commit();
}
SP is the sharedPreference instance:
private SharedPreferences SP;
For activity A when it restarts:
#Override
protected void onRestart() {
super.onRestart();
LoadStats();
Log.e("onrestart", " ");
}
public void LoadStats()
{
PIM.loadAll();
Dis.setText(Long.toString(PIM.getDistanceTraveled()));
FastestSpeed.setText(Float.toString(PIM.getFastestSpeedAcheived()));
TotalTime.setText(Long.toString(PIM.getTotalTimeRan()));
KeepItUp.setText(Long.toString(PIM.getLongestTimeInKeepItUp()));
}
public void loadAll()
{// load all saved player data from sharedpreferences
DistanceTraveled = SP.getLong("DistanceTraveled", 0L);
FastestSpeedAcheived = SP.getFloat("FastestSpeed", 0.0f);
TotalTimeRan = SP.getLong("TotalTime", 0L);
LongestTimeInKeepItUp = SP.getLong("KeepItUp", 0L);
}
using .commit() method will make sure your data has been saved.
see the android doc for sharedPreferences.
see the commit and apply method
Use onPause instead since this occurs before onStop
From the documentation
Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.
You might want to see the description of an Activity's lifecycle.
i make app with two activities.
firs has:
2 ExitText(login and password);
button(confirm, save data with SharedPreferences, intent to second activity).
second one:
2 TextView(get login and password with SharedPreferences);
button(clear data on SharedPreferences, intent to firsActivity).
how to make next: while there are some data on SharedPreferences - app will be started from the 2nd screen.
for example, i made:
if (user!=null && pass!=null){ Intent enterIntent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(enterIntent);
}
but, technically it first run the firstActivity and than go to the secondOne. if there are some method to start app with the another activity (not mainOne)?
You won't be able to check to see if there are values in SharedPreferences before entering one Activity.
What you can do is check the value before displaying the UI (before calling setContentView(R.layout.my_layout)), and either continue along, or start the next Activity.
public class MyStartActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences preferences = getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
if (preferences.contains("my_key")) {
// start next Activity
}
setContentView(R.layout.my_layout);
}
}
If you don't want the first one on the back stack, you can call finish() after starting the second one (or use appropriate flag(s) on intent).
Another approach would be to have only one activity with to fragments and decide dynamically which one set on start. With fragments you can also easily change layouts on button click or on back pressed.
I'm not sure if it will work, because app has to start at the first activity. First activity checks login and pass at share preferences and then you can go to the second activity
try this
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences preference = getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
if (preference.getSting("key",null)!= null) {
// start new Activity
//finish this activity so it not in back stack
} else {
setContentView(R.layout.my_layout);
}
}
I created a MainActivity in which the user has a few app options, displayed in a grid menu, which access subsequent specific activities. However, when the application starts, I use an AlertDialog for the user to enter login details, inflated just after the grid layout definition.
The problem is, each time I select an item in the grid menu (and, consequently, a new activity), the AlertDialog pops-up again. How can I avoid this?
Moreover, I have an uploading service which should start with the beginning of the MainActivity (or after the login, perhaps), but should not be restarted each time a new activity is called. I assume this problem is related to the previous one, although I have managed to temporarily solve it by using a startService button via an OptionsMenu. This is no permanent solution.
Thank you in advance.
EDIT: I tried to use getSharedPreferences as follows:
private SharedPreferences prefs;
private String prefName = "MyPref";
int hasLoggedIn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mm_gridmenu);
SharedPreferences prefs = getSharedPreferences(prefName, MODE_PRIVATE);
hasLoggedIn = prefs.getInt("hasLoggedIn", 0);
if (hasLoggedIn == 0) {
showDialog(SHOW_DIALOG);
prefs = getSharedPreferences(prefName , MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("hasLoggedIn", 1);
editor.commit();
}
However, this way the hasLoggedIn value is saved as 1 and the dialog never pops-up again. I tried setting the back button to fix that, but this seems to prevent the app from being minimized. Is there a way to add that action to the button? (Which I would duplicate on the Home button as well)
#Override
public void onBackPressed() {
prefs = getSharedPreferences(prefName , MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("hasLoggedIn", 0);
editor.commit();
Log.i("hasLoggedIn", hasLoggedIn + "");
return;
}
Moreover, I believe this action will affect subsequent activities (setting the alertDialog back on). Which should be a valid alternative to this?
Basically you need to keep track of your applications states, you have a few options to do this. One simple way would be to use a SharedPreferences to store a boolean variable called something like hasLoggedIn after the user logs in you set this value to true. Each time your main activity launches simply check the value of hasLoggedIn if its is set to false require the user log in again. If it is already true don't show the log in dialog
You can try this:
Add a boolean flag in your MainActivity:
private boolean dialogFlag = true;
in the onCreate/onResume method:
if(dialogFlag) {
createDialog();
dialogFlag = false;
}
If you want to pop up just once the app is installed, you can save this flag into a property file. And read it first whenever the app is getting started.
I'm designing an application that has an activity for registration process, this activity launches on default. I want this activity to be disabled forever once the registration process has been completed successfully and then it should be replaced by a different activity as the default activity for the rest of the lifetime of the application.I've tried to search my way through this problem but I've hardly found anything.Any help will be much appreciated.
Thanks in advance.
Once registration is complete, commit some value to the SharedPreferences, then in your splash screen or some other opening Activity, check the preferences. If the value indicates that the registration is complete, start a different Activity instead of the Registration one...
Example:
public class SplashScreen extends Activity {
public void onCreate(Bundle state) {
super.onCreate(state);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean regComplete = prefs.getBoolean("registration", false);
if(regComplete) {
startActivity(new Intent(this, SomeActivity.class));
} else {
startActivity(new Intent(this, Registration.class));
}
}
Better still:
Always launch the registration, but in onCreate(), simply launch a different Activity immediately and finish() the registration Activity if the prefs indicate that registration is complete.
Edit
SharedPreferences explained:
SharedPreferences lets you persist primitive values in your app. You grab the SharedPreferences by doing:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
then you write to SharedPreferences by getting the Editor. To do this, you call
SharedPreferences.Editor editor = prefs.Edit();
then you can commit values to the editor by using key/values:
editor.putBoolean("some string as a key here", true/false);
Then to actually save that, you call editor.commit();
Then you grab values back from SharedPreferences by simply calling
prefs.getBoolean("some previously chosen string as a key here", true/false);
where true/false is the default value that will be returned if no such key exists...
This is convenient and lets you do simple things like:
editor.putInt("some important number", 55);
editor.commit();
......later
int i = prefs.getInt("some important number", -1);
if(i != -1) {
//do stuff
} else {
//do other stuff
}
Also, please see: http://developer.android.com/guide/topics/data/data-storage.html#pref
Don't have the registration Activity be the default. Instead have another Activity as the default, and then at runtime it can check to see which Activity it should send the user to. If they haven't registered then startIntent( RegistrationActivity.class ).