How to set no History for all Activities - android

My Android Application is based on four Activities. The last activity starts an Intent Service and set itself to background.
Before I sent the last Activity to background I would like to remove all four Activities from backstack history
I tried already to set the no history = true attribute for the activities. This causes errors when I use startActivityForResult, so I need a different solution

I don't really think there is an "good" way to do this, I would try something like this:
First create a SelfClosingActivity which only job is to close itself after opening:
public void onCreate(Bundle savedInstanceState()) {
super.onCreate(savedInstanceState);
finish();
}
When you want to close all the Activities (after you start your IntentService I guess) run the SelfClosingActivity and add flags to clear the current stack.
Intent intent = new Intent(this, SelfClosingActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
This will clear the current stack before opening SelfClosingActivity and SelfClosingActivity will close itself leaving the stack completely empty.

FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK will do what you want.
FLAG_ACTIVITY_CLEAR_TOP
Added in API level 1 int FLAG_ACTIVITY_CLEAR_TOP 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.
For example, consider a task consisting of the activities: A, B, C, D.
If D calls startActivity() with an Intent that resolves to the
component of activity B, then C and D will be finished and B receive
the given Intent, resulting in the stack now being: A, B.
This launch mode can also be used to good effect in conjunction with
FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task,
it will bring any currently running instance of that task to the
foreground, and then clear it to its root state. This is especially
useful, for example, when launching an activity from the notification
manager.
Refer to Tasks and Back Stack for more info

Related

Destroy All Previous Activities After Specific Activity is Open [duplicate]

This question already has answers here:
Finish all previous activities
(28 answers)
Closed 7 years ago.
This is the scenario
Activity A -> Activity B -> Activity C -> Activity D (I would like to destroy Activity A, B, and C after Activity D is launched.
Any ideas please?
Intent intent = new Intent(ActivityC.this, ActivityD.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
FLAG_ACTIVITY_NEW_TASK
If set, this activity will become the start of a new task on this
history stack. A task (from the activity that started it to the next
task activity) defines an atomic group of activities that the user can
move to. Tasks can be moved to the foreground and background; all of
the activities inside of a particular task always remain in the same
order. See Tasks and Back Stack for more information about tasks.
This flag is generally used by activities that want to present a
"launcher" style behavior: they give the user a list of separate
things that can be done, which otherwise run completely independently
of the activity launching them.
When using this flag, if a task is already running for the activity
you are now starting, then a new activity will not be started;
instead, the current task will simply be brought to the front of the
screen with the state it was last in. See FLAG_ACTIVITY_MULTIPLE_TASK
for a flag to disable this behavior.
This flag can not be used when the caller is requesting a result from
the activity being launched.
FLAG_ACTIVITY_CLEAR_TASK
If set in an Intent passed to Context.startActivity(), this flag will
cause any existing task that would be associated with the activity to
be cleared before the activity is started. That is, the activity
becomes the new root of an otherwise empty task, and any old
activities are finished. This can only be used in conjunction with
FLAG_ACTIVITY_NEW_TASK.
You need to pass flag Intent.FLAG_ACTIVITY_CLEAR_TOP with Intent :
Intent intent = new Intent(getApplicationContext(), D.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Use these lines to clear the activity stack when the Activity C is launched:
Intent i = new Intent(PresentActivityName.this, D.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
finish();

Android: when coming from notification, activities are added on top of already open activities and memory increases

Android: when coming from notification, activities are added on top of already open activities and memory increases.
How to clear all the previous activities or even kill the app when notification is tapped?
Here is how I build my notifications:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)//
.setContentTitle(notificationTitle)//
.setContentText(notificationText)//
.setSmallIcon(R.drawable.app_icon_transparent)//
.setAutoCancel(true)//
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.asd));//
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(context, StarterActivity.class);
resultIntent.putExtra("comingFromNotification", true);
// The stack builder object will contain an artificial back stack for
// the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(StarterActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify((int) now.getTimeInMillis(), mBuilder.build());
Now, when the user receives a notification and clicks it, StarterActivity is started. It initiates all the resources the app needs and then starts the main activity.
If the app had been running up to this moment and had been taking up 50 mb of ram, now ram goes up to 65, which means the previous process is not killed and this one starts on top of it.
Question is, how to kill the app if its running in the moment the user clicks the notification?
EDIT: In some similar question I found this
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_NEW_TASK);
will this help? What do these flags mean?
EDIT2: Nope. those flags didnt help. The application process that has some cached objects in memory still lives and the RAM goes up again.
Your architecture doesn't lend itself to solving this problem. As you mentioned in some comments, StarterActivity is your root activity (ie: the one with ACTION=MAIN and CATEGORY=LAUNCHER), but you don't keep it in the activity stack, so you cannot take advantage of FLAG_ACTIVITY_CLEAR_TOP.
To solve your problem you should not call finish() on StarterActivity when it launches MainActivity. This will allow you to use FLAG_ACTIVITY_CLEAR_TOP (with or without FLAG_ACTIVITY_SINGLE_TOP, depending on whether or not you want to use the existing instance of StarterActivity or create a new instance).
Once you've got that working, you now need to deal with the problem of the user pressing BACK in MainActivity and having it return to StarterActivity, which is obviously not what you want. You can solve that in several ways, here are 2 examples:
Add a boolean member variable to StarterActivity. In StarterActivity.onResume() set that variable to true at the very end of the method. At the start of onResume(), check the variable, and if it is true, you can assume that the user has pressed BACK in MainActivity, so you can just call finish().
In MainActivity override onBackPressed() and instead of calling super.onBackPressed(), call startActivity() with an Intent for StarterActivity with an extra named "exit" and FLAG_ACTIVITY_CLEAR_TOP. This will cause a new instance of StarterActivity to be created. In StarterActivity.onCreate(), check the presence of the extra "exit" in the Intent, and if it is there, it means that the user pressed BACK from MainActivity. In this case, you just want to call finish() to end your application. If you use this mechanism, make sure that StarterActivity has standard launchMode in the manifest, not launchMode="singleTop".
FLAG_ACTIVITY_CLEAR_TOP - Clears intermidiate activities, not every activity e.g:
You have call A > B > C > D >E , then from E you call B. After such call Activities C and D will be removed, activity A will remain.
If you have calls A > B > C > E and from E you call activity F, no activity will be purged.
FLAG_ACTIVITY_SINGLE_TOP ensures the top activity is not recreated if it is called again. eg:
you cal A > B > C , then you call B again. After such call B will not be recreated, but Current existent will be called. If you will call A, it will be recreated as it is not on top of stack.
Activity_new_task - is used for complecated back navigation. You can manage several tasks or in other words several histories of activity calls. Creating new task will not erase previos task. Is an absolute requirenment, when starting app with notification, deeplinks or any other "launcher" behaviour. Purifications inside one task will have no effect on another task history
I assume, a propper reset of history after launch will be achived with those 3 flags together: FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP |FLAG_ACTIVITY_CLEAR_TASK
This shoul, clear task history, close it and create new task. If it does not work try to replace Clear_Task with FLAG_ACTIVITY_RESET_TASK_IF_NEEDED.
You don't need to kill the app and start it again. Use android:launchMode="singleTop" in your manifest for the activity:
<activity
android:name=".StarterActivity"
android:launchMode="singleTop"/>
This will open the same activity rather than creating a new one.

Start Activity and Bring it to Front

I have a service that once it completes a task it launches an intent to start an activity from my application. Like this:
Intent i = new Intent(MyService.this, MyActivityToBringToFront.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
//i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(i);
This service can be running even after my application has been closed. When this is the case and my application is closed I need it to bring the activity to the front of whatever the user is currently doing. So if the user is in a different app I need my activity to pop up in front. Is this possible. None of the flags had any effect. Basically I need it to be like the system phone application. When you get a phone call it always brings the phone to the front. How can I do this? Thanks!
First of all you need to keep context in memory to make intent's.
Secondary you need a mechanism that can re-obtaining your context every 24 hours because usually context stay alive in 24 hours.
After.
Launching Activity from service :
Intent dialogIntent = new Intent(getBaseContext(), myActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(dialogIntent);
source : https://stackoverflow.com/a/3607934/2956344
To push activity on top add
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Intent i = new Intent();
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setAction("android.intent.action.VIEW");
i.setComponent(ComponentName.unflattenFromString("com.example.package/com.example.package.activityName"));
startActivity(i);
Intent i = new Intent(MyService.this, MyActivityToBringToFront.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity( i);
And API reference is
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.
For example, consider a task consisting of the activities: A, B, C, D.
If D calls startActivity() with an Intent that resolves to the
component of activity B, then C and D will be finished and B receive
the given Intent, resulting in the stack now being: A, B.
The currently running instance of activity B in the above example will
either receive the new intent you are starting here in its
onNewIntent() method, or be itself finished and restarted with the new
intent. If it has declared its launch mode to be "multiple" (the
default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same
intent, then it will be finished and re-created; for all other launch
modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be
delivered to the current instance's onNewIntent().
This launch mode can also be used to good effect in conjunction with
FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task,
it will bring any currently running instance of that task to the
foreground, and then clear it to its root state. This is especially
useful, for example, when launching an activity from the notification
manager.
launching an activity from a service isn't always a good idea. You may want to use notification for that. If the user clicks on the notification, thats the time you show the Activity.

Start Activity clearing top in Android

I have the following Activities in my stack:
A , B , C, D
I want to relaunch B in order to get this stack:
A , B'
Where B' is a new B instance (not the old receiving a onNewIntent callback, how can I do it?
By the way I'm using a
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
when launching the B activity but this way the onNewIntent is called instead of start a new instance
Use android:noHistory=true in manifest file for particular activity to clear.Hope this might solve your issue.
here when you use this code the its take you on activity B. in B you Press backbutton the its take you on A.
Intent fromDtoB = new Intent(this,B.class);
fromDtoB.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(fromDtoB);
FLAG_ACTIVITY_CLEAR_TASK: If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started.
FLAG_ACTIVITY_CLEAR_TOP: 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.

FLAG_ACTIVITY_CLEAR_TOP calls onCreate() instead of onResume()

So I have an abstract class extended through the entire app that overrides the back key to reorder Activity A to the front (With the flag).
So, it would be:
A > B > anywhere, and the back key should bring me back to A
I'm using the FLAG_ACTIVITY_CLEAR_TOP, but it is entirely refreshing A for some reason and I don't want that.
So: Flag_activity_clear_top is reloading the onCreate() rather than onResume(). What gives?
If you want the activity to just be brought to the top without restarting it set the launchMode of the activity to singleTop in the manifest. You will receive a call to onNewIntent when the activity is being brought to the top. onNewIntent is called before onResume. If you only want this behavior for the specific intent you can add the FLAG_ACTIVITY_SINGLE_TOP(in addition to FLAG_ACTIVITY_CLEAR_TOP) to the intent with the addFlags call instead of the manifest.
Intent intent = new Intent(CurrentActivity.this, ActivityNeedOnTop.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
CurrentActivity.this.finish();
From the API docs for FLAG_ACTIVITY_CLEAR_TOP
For example, consider a task consisting of the activities:
A, B, C, D. If D calls startActivity() with an Intent that
resolves to the component of activity B, then C and D
will be finished and B receive the given Intent,
resulting in the stack now being: A, B.
**The currently running instance of activity B in the above example
will either receive the new intent you are starting here in its
onNewIntent() method, or be itself finished and restarted with the new intent.**
So I think your activity is itself finished and restarted.

Categories

Resources