broadcastreceiver launch several activities - android

I'm launching a MainActivty from a BroadcastReceiver when Android starts:
Intent miIntent = new Intent(this, MainActivity.class);
miIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(miIntent);
This works fine; the MainActivity is launched. The problem is when I press the home button on MainActivity and then I open the application again. It doesn't resume the app, but instead it creates a new Activty. If I press a button finish (the MainActivity contains a button to finish()) MainActivity appears again, because the last doesn't close. Help me please, I dont know what to do.
I think the problem is in the flags, because if I open the app again, it works fine (without booting from broadcastreceiver).
Thanks!!

You can try adding the FLAG_ACTIVITY_CLEAR_TASK and FLAG_ACTIVITY_CLEAR_TOP flags to your intent.
mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Flag Activity Clear Top:
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP
Flag Activity Clear Task:
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TASK
OR
You can try adding the android:launchMode="singleTop" to your MainActivity in the manifest, this says that only one instance of the activity will run. So if another instance of it does exist it will resume it instead of replacing it with a new one.
Good Luck!

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

Previous activity stays on activity stack

I'm using this library which is a Wizard.
When user is done with the Wizard and clicks Done button he moves to another Activity.
I have added to Manifest file android:noHistory="true" for the WizardActivity and also when I start the next activity im doing it like this :
Intent intent = new Intent(this, ProjectsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Nevertheless when user click backs he still goes to the WizardActivity. I'd like the user either to exit or go the activity that started the WizardActivity.
Thank you
finish() the activity after launching the other Activity. i.e after startActivity(intent) add finish()

how to start launcher activity after app goes to background?

I want to always start launcher activity after app goes to the background. I tried android:clearTaskOnLaunch="true" but it not work. How can i do this? For example i have A,B,C,D,E,F activity. A is launcher activity.
now i open app so A activity is called then A>B>C. now i minimize the application. Now i open application from the icon so app is start from C but i want it start from A so how can i do this? some said use onResume intent with Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK. but what if i press back button then onResume is called and my app start with A activity.... so it is not work..any solutions???
You can check the App is in foreground or is in background and when the application goes to the background state at the same time do some logic that when your application comes to foreground it will always show the root activity.
How you can identify application is in which state is well explained here
When you start Activity B, use these flags. That way Activity B and C will always be in a separate stack. That means that when someone starts Activity A from the home screen they will see Activity A always.
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
Intent intent = new Intent(context, B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intent);
Also this might help, you can add this flag to your root Activity.
<activity
android:name=".ui.MainActivity"
android:clearTaskOnLaunch="true"/>
This does because device store data about application. For short time data are stored. if you want to start application from rot class. use service with application, so that whenever your application goes in background and pause then choose your action to do that will be easier.

Clear all activities in a task?

I have a splash screen activity, then a login activity. My history stack looks like:
SplashActivity
LoginActivity
when the user successfully logs in via LoginActivity, I want to start WelcomeActivity, but clear the entire stack:
SplashActivity
LoginActivity // launches WelcomeActivity ->
WelcomeActivity
// but now all three are in the history stack, while I only
// want WelcomeActivity in the stack at this point.
Is there some flag I can use to do that?
// LoginActivity.java
Intent intent = new Intent(this, WelcomeActivity.class);
intent.addFlag(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
Not sure if using the FLAG_ACTIVITY_CLEAR_TASK will clear out all activities in my task or not. I can do this 'manually' by unwinding the stack by using startActivityForResult() calls, but will be more fragile and more code to maintain.
Thanks
Yes that should work fine. You could use:
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
FLAG_ACTIVITY_CLEAR_TASK
FLAG_ACTIVITY_NEW_TASK
which ensures that if an instance is already running and is not top then anything on top of it will be cleared and it will be used, instead of starting a new instance (this useful once you've gone Welcome activity -> Activity A and then you want to get back to Welcome from A, but the extra flags shouldn't affect your case above).
Intent intent = new Intent(this, NextActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Use android:noHistory="true" on the splash activity in the manifest file.
<activity
android:name=".activity.SplashActivity"
android:theme="#style/theme_noActionBar"
android:noHistory="true">
finish() removes the activity from the stack. So, if you start LoginActivity and call finish() on SplashActivity, and then you do exact the same to start WelcomeActivity you will get the desired behaviour. No need to use extra flags.
Intent.FLAG_ACTIVITY_NO_HISTORY can work in your case too if you do not want the activity on the history stack.
Just do this to clear all previous activity in a task:
finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)
In case that all of three activity is involved in the same app(same taskAffinity), you can pick either 1,2 or 3 below. otherwise you should pick 1,2 below.
If you don't want to return back SplashActivity from LoginActivity, you can define activity attribute noHistory in AndroidManifest.xml or you can set FLAG_ACTIVITY_NO_HISTORY into the intent to launch SplashActivity. if SplashActivity is started from Launcher, you should pick way to set activity attribute noHistory.
If you don't want to return back LoginActivity from WelcomeActivity, you can use either activity attribute noHistory or FLAG_ACTIVITY_NO_HISTORY like number 1 above.
If you want to clear back stack on specific situation, you can use FLAG_ACTIVITY_CLEAR_TASK in conjunction with FLAG_ACTIVITY_NEW_TASK(FLAG_ACTIVITY_CLEAR_TASK always must be used in conjunction with FLAG_ACTIVITY_NEW_TASK). But, if the activity being started is involved in other app(i.e different taskAffinity), the task will be launched other task after the task is cleared, not current task. so make sure that the activity being launched is involved in the same app(taskAffinity).

Why does starting an activity from a widget cause my main activity to start as well?

When I start an activitiy from a widget I want the back button to go to the home screen but instead it goes to the app's main activity. After toying around I found that if I somehow close the main app activity, this problem doesn't occur. Strange.
I found a solution here that said to call finish(); in my main activity's onPause(). Obviously this is the wrong solution e.g. reorientation of the screen causes an onPause() so the will activity will die whenever the phone is rotated.
This is how I start my activity:
#Override
public void onReceive(Context context, Intent intent) {
[...]
//new Emergency().emDialog(context).show();
Intent myIntent = new Intent(context, EmergencyActivity.class);
// FLAG_ACTIVITY_NEW_TASK is needed because we're not in an activity
// already, without it we crash.
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
You can see the rest of the code at http://code.google.com/p/emergencybutton/source/browse
edit: I tried running the activity differently, but still it doesn't work correctly:
Intent myIntent = new Intent();
myIntent.setClassName("com.emergency.button", "com.emergency.button.EmergencyActivity");
Ok, so I'm not exactly sure what happened here but android:launchMode="singleInstance" in the activity in AndroidManifest.xml fixed it somehow.
<activity android:name=".EmergencyActivity"
android:launchMode="singleInstance"
#Octavian - I should have clarified that I start the activity from an onReceive in an AppWidgetProvider. I'm at the home screen, starting an activity titled B, but somehow both A and B are in the activity stack instead of just B.
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Although I've never used widgets, I believe that when you click the widget you are resuming an existing task. Hence, when you are in that task, you will return to the latest activity in that task (instead of Home).
See this link and choose the proper launch mode for your widget
http://developer.android.com/guide/topics/fundamentals.html#lmodes
The behavior is not strange it is just the way Android works. The activity stack just keeps track of the all the activities. Now when you start an activity A which starts another activity B then your stack looks like (B, A). If you press the back key then activity B is going to get popped off the stack and A is going to be brought to foreground again.
The right solution is to just call finish() right after firing off the Intent.
Sometimes it's not possible to use launchMode singleInstance in application for some reasons.
In this case, you should start your activity and clear activity stack. You can archive this using flags. There is an example:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Categories

Resources