Android prevent going back to previous activities - java

I am developing on an Android app in which I want to prevent going back to SignIn activity after user logged in. I have tried Intent.FLAG_ACTIVITY_CLEAR_TASK, but it doesn't work
Intent intent = new Intent(SignInActivity.this, FirstPage.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
And I have also tried adding finish right after start Activity, but that simply gives me a leaked window error.
Intent intent = new Intent(SignInActivity.this, FirstPage.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
The path of my activities is:
MainActivity(description of my app) <-> SignInActivity(sign in) -> First(logged in).
User can go back and forward between MainActivity and SigInActivity. How can I prevent users going back to SignInActivity or MainActivity from FirstPage?
Any idea? Thank you!

Calling finish() will end the activity and not have it on the stack as an activity you can go back to. You need to look into what is causing your leaked window error (such as leaving a notification on screen when you finish the activity) and resolve that rather than not using finish because you have a leaked window error.

With the FLAG_ACTIVITY_NEW_TASK your activity will become the start of a new task of the history stack. Try to use both flags (NEW_TASK and CLEAR_TOP).
You also could override your onBackPressed method.
#Override
public void onBackPressed() {
return;
}
This post has solved a very similar problem, worth to look at it!

Related

Intent filter not working with annotations

i'm using andorid annotations library in my project.I'm stuck with one little problem .
When a user login using his credential, MainActivity.class will be opened. And token will be saved in database. Next time user will open the app, it checks (in SplashScreen) whether the user previously logged in or not. If he did logged in, MainActivity will be opened & i'm using intent filter to clear the stack/task.
if (!id.equalsIgnoreCase("default")) {
Intent intent = new Intent(this, MainActivity_.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else {
Intent intent = new Intent(this, LoginActivity_.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
Everything is working fine except intent filters. In MainActivity.class when i press the Back Button, the SplashActivity opens and app is not minimizing. It feels like that the stack is not cleared. Any help would be appreciated.
Just finish the splash activity while starting MainActivity.class/LoginActivity_.class from SplashActivity.java
startActivity(intent);
finish();

Decide which activity to start from a subclass of Application

I have a simple application in which before I do anything, I must check whether the user is logged in or not.
To do this, I inherited the Application class like this:
public class GBApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
if (userIsLoggedIn()) {
Intent overviewActivity = new Intent(this, Overview.class);
overviewActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(overviewActivity);
}
}
}
userIsLoggedIn() returns a boolean stored in the SharedPreferences file.
Everything works, but when I press back from the Overview activity, it redirects me to the default activity (MainActivity), and removing it from the AndroidManifest.xml files gives error.
Also, I can't call finish() since this is a non activity class.
How can I terminate my program after I return from the Overview class? I found solutions where they pass a value to the MainActivity, call finish() from there. But this seems to complicated.
What else I can do?
This is my application tag in AndroidManifest.xml
Your plan is going to cause problems. Every time your process is created, you are starting an activity, even if an activity is not needed for this particular process.
Displaying a launcher activity — such as in response to the user tapping on a home screen launcher icon — is one way that a process might be created for your app. But there are many others:
AlarmManager
JobScheduler
a Notification
a push message (e.g., from Firebase Cloud Messaging)
a request sent to a ContentProvider that you export from your app
a request sent to a Service that you export from your app
a manifest-registered BroadcastReceiver
the user returning to your task in the overview screen
and so on
In none of those scenarios is displaying this activity necessarily appropriate. Yet, your code will display the activity in all of them, because any time Android forks a process for your app, you display this activity.
Have all of your activities (other than the login one) see if the user is logged in, and route the user to the login activity if that is needed. When the user completes the login, and the login activity finishes, the user is returned to where they were trying to go, whether that is your launcher activity or some other activity (e.g., they returned to your task after your app had been in the background for a while, so your process was terminated, but Android tries to send them back to whatever activity of yours they had been in last).
You could simply override the onBackPressed() of your overviewActivity and pilot the direction your app goes when the back button is pressed (which in your case is to shut down the app):
#Override
public void onBackPressed(){
startActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
The code above just shuts down your app immediately the back button is clicked once (which is pretty boring.. but simple). You could also try the code snippet below; it pops up a dialogue box:
#Override
public void onBackPressed(){
new AlertDialog.Builder(this)
.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
startActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
})
.setNegativeButton("No", null)
.show();
}

Check whether an activity is active or not from a different activity

I have a flow in my application like this:
For new users:
Splash Screen --> Login Activity --> Home Activity
For already registered users:
Splash Screen --> Home Activity
Basically the Splash Screen has an if else to decide which activity to go to. Once a first time user logs in, his status is saved in a preference variable for the splash screen to decide next time not to open the login activity.
Now the situation is that. If a new user logs in and goes to the home activity, and then logs out. He is redirected to the Login screen which is pretty much what should happen. But, in case an existing user opens the app, he is shown the Splash screen and directly moved to the Home Activity. Now if the user logs out, he gets out of the app. This happens because the Login Activity does not have any instance created and thus finishing the Home Activity finishes the whole app. Logout actually finishes the Home Activity, naturally the last active activity should open up. Which is not happening.
What I want to do is that, I want to implement a logic which will check that the Login Activity is available or not. If its available then finish() will be called else the Login Activity will be called via intent.
Please tell me how to achieve this.
P.S: My app uses a custom theme with a customized action bar. If I call finish and Intent together or I use flags to clear existing activities then there is a weird transition effect which shows the black standard action bar for a split second thus creating a bad user experience.
Now if the user logs out, he gets out of the app. This happens because
the Login Activity does not have any instance created and thus
finishing the Home Activity finishes the whole app.
If i understood your question, why dont you just call the Login Activity manually after user click a logout button?
Its what i always did with apps that have flow like yours
when user login finish login activity and start home activity.
when user logout finish home activity and start login activity
You always can call Login Activity via intent. If the activity is available, android will show this activity. Else android will create new activity automatically.
Actually that's why we use intents to show activity instead of creating activityes manually. System catches this intents and does all dirty work.
EDIT:
Hmm, but wouldn't you have the transition problem anyways? (If you were already logged in, and then log out - using intent/finish() you will have the same black action bar issue no?)
Maybe consider following ( I actually did this in my app):
Merge Splash screen and Login into one activity and depending whether you are logged in - display the login fields or proceed to home screen. Then you have a out of box consistent stack of activities regardless of use cases and no mambo-jumbo with do I already have this or not.
I can't comment because of I lack 4 rep, so I'll post as answer here:
I think #Blaze Tama is right. You can also use FLAG_ACTIVITY_CLEAR_TOP on intent to avoid stack flow problems:
From docs:
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
Always start Login activity and start Home activity right away if the user already logged in.
In the Splash Screen activity
Intent intent = new Intent(this, Login.class);
If (user already logged in)
{
intent.putextra("Logged in", true);
}
startActivity(intent);
In the Login activity
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null)
{
if (intent.getBooleanExtra("Logged in", false))
{
startActivityForResult(new Intent(this, Home.class), requestCode);
}
}
else
{
// The existing code here
}
}
In Home activity send back a code to indicate if the user logged out or just BackPress. If BackPress finish this Login activity.

Using FLAG_ACTIVITY_NEW_TASK with FLAG_ACTIVITY_CLEAR_TOP

I have an android app that starts a foreground service as follows:
In the calling activity:
serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);
And in the service's onStart():
startForeground(...
At some point, the service needs to display a message to the user, then transition back to the "home screen", which is defined as the activity marked with the LAUNCHER intent-filter (but it could be any activity for this example). I accomplish this by creating an Intent inside of MyService to an activity with the flag FLAG_ACTIVITY_NEW as follows:
Intent i = new Intent(getApplicationContext(), ShowMessageActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("MESSAGE", "Show me to the user");
getApplicationContext().startActivity(i);
From this new activity, I display a message, then attempt to take the user back to the "home screen" by creating a new Intent with the flag FLAG_ACTIVITY_CLEAR_TOP:
finish();
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
The issue I seem to be having is that since the MessageActivity was created with FLAG_ACTIVITY_NEW_TASK, it seems to be on it's own activity stack, so that when I get back to the "home screen", the back button takes me to the previous activity on the stack instead of exiting the app (as this should be the only activity on the stack).
Here's a better picture of what I'm experiencing:
Launch app which creates MainActivity
MainActivity starts MyService
User performs some action which causes them to transition to AnotherActivity
MyService creates MessageActivity
MessageActivity takes user back to MainActivity
User clicks the back button
Instead of exising the app (as this should be the only activity on the stack), the user sees AnotherActivity
I tried to create the MessageActivity from MyService without using the FLAG_ACTIVITY_NEW_TASK, but this produces an exception which states FLAG_NEW_ACTIVITY is required.
My question is, how do I get an activity created with FLAG_ACTIVITY_NEW_TASK to clear the activity stack for the entire app. The desired behaviour is that once I transition from MessageActivity to MainActivity, that MainActivity is the ONLY activity on the stack.

How to remove all activity in flow from stack, when calling some new activity in android

I have a problem in my android app, it having the log out functionality in setting screen.
When we Logout it opens the login screen. But when i press back button then it show the setting screen page, which is not required (as it takes me to inside the app without login). I am using the following code but it is not working. Because at the time of logout LoginActiviy is not exist.
Intent intent= new Intent(HomeSetting.this,LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Please suggest me some solution, that LoginActivity get call as a new Activity, and all activity in history will get destroyed.
You can set noHistory property of Activity in manifest file as true.So it will be removed from Activity satck,when it goes to background.
To avoid this, you should set flags as follows:
Intent intent= new Intent(getApplicationContext() , LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Categories