I'm developing the login system and currently the flow is as follows:
LoginActivity can call ExecuteLoginActivity to show a screen with a progressbar while it connects to the backend via an AsyncTask to authenticate the user and return the result to the LoginActivity, which can then call the MainActivity, or the LoginActivity can call the SignUpActivity that can then call the ExecuteSignUpActivity which does the same as the ExecuteLoginActivity but for signup, and then return the result to the SignUpActivity that in turn returns the result to the LoginActivity which can then call the MainActivity.
The problem with this approach is that the LoginScreen (and sometimes the SignUpActivity) ends up "flashing" to the user before it can call the MainActivity. I want the Execute activities to call the MainActivity themselves after a sucessfull login/signup and to return to the Login/Signup activities to show an error on a failed attempt.
I tought about using a broadcast to send a signal to finish the Login/Signup activities on a sucessfull login but I don't know if I can finish them while they are waiting for the result of the spawned Execute activities. So my question is, can I finish an activity that is waiting for the result of another activity?
In Sign up and Login Activity do this:
Intent i = new Intent(this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
My theoric question was not directly answered, but I found a solution to the pratictal problem in the answer for this question.
Basically, what I did was calling startActivity() to start the MainActivity directly, and then return success and finishing all the other activities on their respective OnActivityResult() methods.
Related
I have an activity that handles users login.
When user logs in he is forwarded to another activity. But when he presses "back" button he is back to login screen despite he is logged already. How can I avoid that behaviour?
Clear activity stack after user is logged in or use noHistory flag. Start login activity with intent that has these flags : http://developer.android.com/reference/android/content/Intent.html
Here is one way to do it
Intent afterLogin = new Intent(this, AfterLoginActivity.class);
login.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(afterLogin);
You just add this function in your second activity it will give your desired...All the best it will work 100% All the best
#Override
public void onBackPressed() {
// You should write the super function or finish() here...
}
I have a typical Android app where the user has to log in before displaying the main Activity of the application. However, if we've already got a cached username / password, I want to skip the login page.
I could, in my Login onCreate, detect if I've got a user/pass and push a new Activity, but I'm worried that this will make my app startup slower (since I have to load an activity then immediately throw it away), and it also perhaps breaks the back button (i.e. you can hit back and end up back at the login screen).
Is there any way to avoid this and only load the full Login Activity if there is no cached password?
You can make a separate helper activity which launches either your login activity or your main activity. In its onCreate, you'd use startActivity and immediately call finish to remove the helper activity from the back stack.
Intent intent;
if ( /* already logged in */ ) {
intent = new Intent(this, MainActivity.class);
} else {
intent = new Intent(this, LoginActivity.class);
}
startActivity(intent);
finish();
Then, LoginActivity should re-launch MainActivity as normal. This way, the user will never be able to navigate back to the helper activity as it does not appear in the back stack. Do note however that the user can still login, go to the MainActivity, pause that activity, remove his account (through the Android settings) and resume the activity (from the recent apps). If you want to prevent this, you're probably better off placing the login redirect in MainActivity instead (perhaps even in onResume).
You could create a Splash Activity.
On the AndroidManifest.xml's Splash Activity tag, add the android:noHistory="true".
On the Splash Activity, check whatever you need (maybe with an AsyncTask if it may take a long time, to avoid freezing the Activity) and, depending on the result, you start the Login Activity or any other Activity.
Another approach is to transform login screen from Activity to Dialog. That should be easy. And then make your main activity check if there is cached username/password or not. In the second case show LoginDialog to user.
I also have a typical Android app with the same requirement, and I solve it as follows.
First I configure the initial launch activity to be MainActivity, and then inside onCreate(), check if the user has saved credentials (this is all done through AccountManager and authenticator service).
If the check fails and user needs to authenticate, then I start the LoginActivity. If logging in fails or the user presses back, the MainActivity calls finish() on itself to close the whole app. Otherwise, after logging in, the MainActivity is resumed and is presented to the user properly.
The advantage of doing it in this order is that (in my case anyway) the user is more likely to be logged in than out, and so this will avoid any start/stopping of unneeded activities as you say.
A second advantage is that, if the MainActivity (or another activity) is resumed at a later time and the user's session has expired, you can simply start the LoginActivity again to reauthenticate them.
Hope that all makes sense :)
I'm developing a android aplication using login activity how main activity. When the user login the aplication show other activity (intent), but if the user push back button the application show the main activity with the login. ¿How lock login activity after make login in the aplication?
Thank you!
If you want to prevent the user from returning to the login activity, there are two approaches:
After successful login, the login activity can simply call finish() after starting the main activity. This will end the login activity so when the user presses the back button, the app simply finishes.
Have the main activity be the launch activity for the app. In onCreate, you can call startActivityForResult() and launch your login activity. When the login activity finishes, the main activity can either proceed normally if the login was successful, or finish() (or operate in a restricted mode) if the user failed to log in.
Use
finish();
after you switch to another class.
Example :
Intent newIntent = new Intent (firstActivity.this, afterLogin.class)
startActivity(newIntent);
finish();
I have a login screen on my app, and as of now you can press the back button to go back to the login screen. I do not want that to happen.
Once the user logs in, the app should stop the login activity so the user can't go back to it. On the menu screen I have a logout button that I want to use to restart the login activity after already being stopped.
I have been looking and testing for an hour or so and I can't find the answer.
Set noHistory = true in the manifest for your login activity. This prevents the activity from being stored on the back stack.
If you do not want user to be able to get back to login activity, simply exclude it from recent stack, by adding to your activity declaration in application manifest android:excludeFromRecents attribure, like this:
<activity android:name=".Login" android:excludeFromRecents="true"></activity>
then once your login activity finishes it task, you (most likely) go to next activity of your app. And once you call startActivity() to lauch new one, simply call finish(); to finish login actvity:
...
startActivity( intentToLaunchNextActivity );
finish();
On successful login you can call Actvity.finish().
To restart the login activity use Activity.startActivity(intent).
Try either:
After login succeeds in your login activity, call finish() on the activity after launching the next activity. This will effectively destroy the login activity and remove it from the activity back stack (so it can't be navigated to anymore). Something like:
onLoginComplete(){
startActivity(new Intent(this, NextActivity.class));
finish();
}
Or, in the onResume of your login activity check the login status and finish if true. This way, whenever the user comes to this activity it will be closed (and they will never actually see it) if they are already logged in. Something like:
#Override
public void onResume(){
super.onResume();
if(isLoggedIn())
finish();
}
When you leave the login screen on a successfull login, call finish() this will remove your actvity from the stack.
Your logout button should re-call the login page like this:
Intent intent = new Intent(TheCurrentActivity.this, YourLoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
This will load up the login screen and clear the current activity stack ensuring that you can't go back after logout.
I'm trying to write an android application that has two main activities: login screen and display screen. Currently I'm setting it up so that if the user is already logged in, the login screen will be skipped.
In order to work out the best way to do this, I created a generic "Main" activity that looks something like this:
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
// Get preferences
SharedPreferences settings = getSharedPreferences("PREFERENCES", MODE_PRIVATE);
super.onCreate(savedInstanceState);
//setContentView(R.layout.viewusage);
//System.out.println(settings.getBoolean("LOGGEDIN", false));
if (settings.getBoolean("LOGGEDIN", false) == false)
{
Intent intent = new Intent(Main.this, Login.class);
startActivity(intent);
}
else
{
Intent intent = new Intent(Main.this, Display.class);
startActivity(intent);
}
}
}
The idea is when someone logs in successfully, the login activity will save all the details needed to the user preferences, and then finish() the activity. This will return to the Main activity. What I'm trying to do is have the main activity keep looping through the if ... else statement when there aren't any activities running: so when the login page closes, it will re-run the if ... else statement, and should launch the Display activity rather than the Login activity. The reverse will be true if the user logs out from the Display class.
I've thought of using a while (true) loop, but that just hangs the program. I've thought of putting it in a separate thread, but I don't know how to detect if there is already another activity running, so a separate thread will just keep looping and opening new activities (I presume, I haven't tried it)
Any suggestion on how I could work this out?
Thanks.
You can't do it by looping in onCreate, because the activity doesn't actually get off the ground until onCreate returns.
One possibility is to use startActivityForResult and arrange for the Login and Display activities to return a code indicating whether to quit or proceed to the other activity. Then you would place your logic in onActivityResult instead of looping in onCreate.
Another, perhaps cleaner approach is to design the Display activity to directly start the Login activity when the user logs out, and vice versa. That way, the Main activity can just call finish() after it determines which activity to display initially.
Off the top of my head.
Write a login class that timestamps the login and expires the login after a set time interval perhaps with a method isLoginStillValid() and save the login object on a soft kill in onRetainNonConfigurationState. Retrieve the login object in onCreate. Save the login fields, if applicable to preferences in onDestroy(). Set a flag isSavedInstanceState to true in onRetainNonConfigurationState and use this to determine if you need to write to prefs in onDestroy. I know this sound complicated, but this is a reusable template.
So in the end, in onCreate, look for the login object. Check to see if the login has expired. If so, post a GetLogin dialog. In each credentialed call, check to see if the login has expired before allowing access to the credentialed call. If the login has expired, consider posting the GetLogin dialog again. Remember, time may have passed since the app came to the foreground.
Finally, launch GetLoginDialog using startActivityForResult so that you can retrieve the login data and update the login object with a new timestamp.
JAL
I'm a little confused by your question, but I think you want to use startActivityForResult rather than startActivity. This will allow you to return a true/false result from your Login Activity so that you can then launch your Display Activity if the login succeeded. Similarly for your Display Activity, if the user logs out, you would finish() the Activity and return a "logout" result to Main that logs the user out.