Start Activity and Bring it to Front - android

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.

Related

Displaying a Specific Activity Without Displaying the Main Activity of the Application

I have an Intent which starts/open an activity/window that is triggered by an alarm. Everything works fine, however the Main activity/window of the Application is also open behind the first activity referenced above when triggered. Thus, when this activity is dismissed (with the help of a button), the Main window of the Application is displayed on the device. How can I open my activity without opening the Main activity of the Application? Basically, the user shound't be seeing the Main activity of the Application upon dismissing the activity triggered by the alarm. Please note that I am not explicitly calling the Main activity upon opening the specific activity mentioned above. Is this normal behaviour, or am I doing something wrong?
The specific activity is launched with the following lines:
Intent intentRead = new Intent(context, myActivity.class);
intentRead.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intentRead);
Problem
Your code starts a new Activity in a new task :
Intent intentRead = new Intent(context, myActivity.class);
intentRead.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intentRead);
The Flags make sure that the new activity gets its own task and the activity will not be launched if it is already running at the top of the history stack.
Now, suppose your MainActivity is already in the background(recent apps) and alarm is triggered which starts your myActivity. If no instance of myActivity is present then a second task is created for it. Else if an instance is present then the all activities on top of myActivity in the second task will be removed.
Solution
In your case, as you want to clear any other activities present you should use :
Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK
Intent.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.
Suppose the first activity is started by your main activity, could you just finish main activity after starting the first activity. I mean like this:
startActivity(MainActivity.this, FirstActivity.class);
MainActivity.this.finish();

How to set no History for all Activities

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

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();

How to resume an existing task in its current state

My application has two activities A and B. A is the root of the task, and is the one that is launched from the launch icon. B can be started from A.
As well as starting A from the launch icon, it is possible to launch A by clicking on a file in another application, e.g. clicking on an email attachment or a file in Drive. I have done this by adding actions and categories to the intent filter in the manifest file.
I want to make it so that when A is launched from another application, instead of creating a new task I want the existing task to resume in the same state it was in before. This could be activity A or B, wherever the user happened to be before they pressed home.
I have tried all kinds of launch modes and intent flags but nothing seems to work.
Broadcast an intent that's identical to the launcher intent in your manifest:
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
I don't know why, but this raises the existing task instead of starting a new one. By contrast, a launcher intent obtained the "official" way will actually start a new task:
Intent intent = context.getPackageManager()
.getLaunchIntentForPackage(context.getPackageName());
change launchmode to singletask. and listening onNewIntent()

FLAG_ACTIVITY_CLEAR_TOP and android:launchMode="singleInstance"

I think I've just found a really strange bug... But it can just be somekind of feature that I never heard of.
On my application if I have any Activity on the AndroidManifest with android:launchMode="singleInstance" when you try to "clean" the stack to a certain point with the following code:
Intent intent = new Intent(this, Xpto.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
It goes to that activity. But when you press back, it returns to the previous.that should have been finished...
Example:
A -> B -> C
Then from C I call A with Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP having A singleInstance on the Manifest. It goes to A but it only brings it to front. And does not finishes C and B.
Can somebody explain this behaviour?
The Xpto class I'm calling is at the time the root activity of the stack.
from reading this thread:
http://groups.google.com/group/android-developers/browse_thread/thread/5eb400434e2c35f4
it seems that:
"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(). "
which means that you need to set your launchMode to multiple instance, and use only FLAG_ACTIVITY_CLEAR_TOP.
Intent intent = new Intent(this, Xpto.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
In the scenario you described, activity's B and C are not finished when you start activity A (which is the root activity). The documentation describes that with launch mode of singleInstance and the flag FLAG_ACTIVITY_SINGLE_TOP set, activities B and C will NOT be finished. If you want to have activities B and C finished, then you must set the launch mode to multiple instance and NOT set the flag FLAG_ACTIVITY_SINGLE_TOP.

Categories

Resources