My application has 4 activities. If the user clicks the home button, the next time the application is launched, I want it to start on the main activity not the last activity it was on. If the phone's display turns off, as long as the application hasn't been closed, I want it to resume where it left off. What is the proper way to go about this?
Just set clearTaskOnLaunch="true" in your manifest main activity declaration.
http://developer.android.com/guide/topics/manifest/activity-element.html#clear
This doesn't answer all parts of your question, but it sounds as though you'd benifit from looking at these attributes in the manifest; launchmode, finishOnTaskLaunch, clearTaskOnLaunch.
I suppose it is a problem of affinity and recent list. Here is how i solved it.
android:taskAffinity="com.packageName.Excluded"
android:excludeFromRecents="true"
so all tasks with the same affinity will not be listed in recent list.
Note : excludeFromRecents will exclude all the tasks with same affinity in one go, so if you don't set the affinity of the activity, your application will be excluded from recent list(app activities use same affinity by default if not set)
#Override
protected void onResume(){
super.onResume();
keeper += 1;
if (keeper == 2){
Intent iii = new Intent(MainActivity.this, SplashActivity.class);
startActivity(iii);
finish();
}
}
You should implement all theses cases on the onPause and onResume methods of your Activity.
You should learn the Activity lifecycle
http://developer.android.com/reference/android/app/Activity.html
Related
This question already has answers here:
Finish all activities at a time
(21 answers)
Closed 3 years ago.
I want to kill my app from a exit button on my navigation drawer. the drawer has a exit button that is suppose to just kill the whole app (all activity) and gets the user out of the app .
When i am using finish() in the first activity its working but when i go into the app and call finish() the activity gets killed and returns to previous activity but never really kills the app.
Tried to use System.exit(0) but no luck.
Extra Information Might Help
I have all my activity started with android:launchMode="singleTop" . it means all those activities that are already created will not be created again and just reordered to front on calling.
Do anyone have any suggestion for this , please do help.
Update
I want to make some updates here as my question looks like this SO Question.
As i have already said i am using a android:launchMode="singleTop" . and this answer is not working for my case. I have to call onCreate() to make this happen but it is not my case.
Use below code
public void AppExit()
{
this.finish();
Intent intent= new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
System.exit(0);
}
Call above function to exit from App.
First, you need to decide if you just need to take the user out of the app, or if you also need to finish() all of your activities. It depends on your needs, but my guess is that in most cases most users won't know the difference, and Android is designed to have many apps having activities still running. If this is all you need, then you can just use an Intent to take the user to the home screen.
Intent intent = new Intent(Intent.
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
If you actually want to finish() your activities, then you need a mechanism to inform all currently running activities that the user is exiting the app. You can use something like EventBus to send an event that will be received by all registered subscribers; if you don't want to use a third-party library, you can do the same type of thing with LocalBroadcastManager. To do that, you would register a BroadcastReceiver with an IntentFilter for a custom action and broadcast an Intent with that action when the user wants to exit.
In either case, every activity should receive the signal and call finish() on itself. Note that the subscription (in the EventBus case) or the registration of a receiver (in the LocalBroadcastManager case) must be still active after onStop(), so I would register in onCreate() and unregister in onDestroy().
Use below code in your exit button
Intent intent = new Intent(this, ActivityOne.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);
And, in your ActivityOne.class oncreate() method just put below code
if (getIntent().getBooleanExtra("EXIT", false))
{
finish();
}
As a few answers say, call finish(); after you start an intent from an activity. That will make sure the current activity is the only running activity. Also try super.finish(), which will call finish() at parent activity.
You can alternatively use only one activity with many fragments. That way, if you call finish() in the exit button OnClickListener code, you'll exit the app. This will also save a lot of coding since you will be defining the navigation drawer once.
First of all, Android apps are not intended to be killed other that by the system, which attempts to keep them in memory in case the user will return.
But, if you have to do it, try this:
android.os.Process.killProcess(android.os.Process.myPid());
My app, running in background, at some point displays activity to purposefully interrupt user's flow. My activity starts a new task, which appears in "Recent Tasks" lists while being in foreground. Is there any way it could be prevented? Setting android:excludeFromRecents does not work - activity is not presented anymore in "Recent Tasks" only after is has been paused.
Manifest looks like:
<activity
android:name="com.example.recenttasks.MainActivity"
android:excludeFromRecents="true">
</activity>
and activity is started this way:
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
The key thing you mentioned is
appears in "Recent Tasks" lists while being in foreground
I think you can't change that behavior. I just tested on my app and the same thing happens. If I press the "recent tasks" button while having my activity in the foreground, it appears listed there. The moment I move out of it to another activity or to my phone's main screen, the activity is not listed anymore.
I also tested this on the built-in DeskClock app that comes with recent Android versions and the same behavior is present there when a new alarm is triggered. Note that the AlarmAlertFullscreen activity of that app has the same parameters you mentioned in your question.
I'm not sure you can circumvent this or why you would need to in the first place since the activity is not listed anymore once it loses the focus.
you are defined it in manifest that is enough but it is not coming..
ok..try add this flag also to your Intnet and start the Activity..
intnet.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Should the user be able to return to it? (Meaning if it shows and user clicks recents, have they lost their chance to see the hidden activity or should it still be there?)
If they cannot return to it anyway then the best action would be to finish() the activity onPause(). This will mean that as long as you have used android:excludeFromRecents and android:noHistory="true", there will be no item in recents.
If however you do wish to return to the 'interruption' activity (but do not want a recents entry) you could consider still finishing the activity onPause - but also recording a preference flag (something like IS_INTERSTITIAL). Your other activities can then check this preference in onResume and, if it is true, send an Intent to restart the Interstitial instead - To the user it will just appear they are resuming the app in the same state as they left it (interstitial)
Edit: If the screen needs to stay (rather than be re-instantiated) it may be possible to use a DialogFragment, although then you must worry about configuration changes. There is one hack you could try (explained in this answer) -
Set your label empty By using android:label="" your recent task is excluded. however this is a definite hack which may produce inconsistent results (as I haven't tested it to be sure)
I know that Activities can be declared in manifest as being excluded from recents with android:excludeFromRecents:
http://developer.android.com/guide/topics/manifest/activity-element.html#exclude
However, that's not what I'm looking for, I would like to know if there is a way to remove the app from recent apps programmatically
Yes, generally when you want to have special properties for an Activity when starting it you supply special flags to the Intent. In this case FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.
Updated:
If you need to hide the current already running activity, you might be able to use this flag in combination with FLAG_ACTIVITY_CLEAR_TOP which would send the new Intent to the existing Activity. You'll have to think and perhaps experiment with what happens as the user moves around your stack though and whether that will make your app re-appear in the recent apps.
This can be done using the ActivityManager.AppTask functionality (starting in API 21)
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
if(am != null) {
List<ActivityManager.AppTask> tasks = am.getAppTasks();
if (tasks != null && tasks.size() > 0) {
tasks.get(0).setExcludeFromRecents(true);
}
}
Add these lines to the Activity from which you are exiting the application:
#Override
public void finish() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
super.finishAndRemoveTask();
}
else {
super.finish();
}
}
Following is the definition of the flag android:excludeFromRecents (which i know you have already seen):
Whether or not the task initiated by this activity should be excluded from the list of recently used applications ("recent apps").
That is, when this activity is the root activity of a new task, this
attribute determines whether the task should not appear in the list of
recent apps. "true" if the task should be excluded from the list;
"false" if it should be included. The default value is "false".
so to remove the app from the list of recent app you can set this flag on the first activity in your application since that activity launches the the task for you application. If you have multiple tasks (unlikely for most apps) in your application then you need o set this flag for root activity of all the task.
Call this when your activity is done and should be closed and the task should be completely removed as a part of finishing the root activity of the task.
finishAndRemoveTask();
After receiving the other answers, I managed to get to the following workaround: I have an Activity, let's call it XPTO, declared in manifest with
and basically, when I want app to disappear from the recents list, I finish all other activities, then start the XPTO, which basically kills the app (calling android.os.Process.killProcess(android.os.Process.myPid()); in its onResume()
If anyone has a better way of doing this, please share it
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);
i have a button to close my app with this code:
finish();
the problem is that this button doesn't exit of my app... it simply closes the current intent ant returns to the previous intent (window) of my app....
how i can do a real exit/close button?
i tryed with this:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
but it doesn't works, because when i turn back into my app, the app comes in the last opened window, and not in the first window of the app, how i can do that? i need that when i re-open my app it starts on the first window of my app
If you really want your app to die. You could initiate each intent with startActivityForResult(). then before each finish() set the result to send back. in each parent activity you can override onActivityResult() to test whether the result received means the application needs to end. if so you can call another set result and finish(). repeat this in all activities and you will find that your application terminates entirely.
Incidentally I'm writing this from memory. function names may not be exact.
Hope that helps.
p.s. re-read your requirements. you can always stop the finish loop at your first activity.
I would do it this way:
I would define my initial activity (i.e. MainMenu) with a Launch Mode of singleTop
I would then invoke my MainMenu from the activity that is going to close the application.
startActivity(new Intent(this, MainMenu.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP).putExtra("closeProgram", true);
Then override the onNewIntent in the MainMenu activity; check for the extra boolean of "closeProgram", if the value is true, then do a finish();
Haven't tried it but I think it should work.
I recommend you read this: http://blog.radioactiveyak.com/2010/05/when-to-include-exit-button-in-android.html
Chances are, you don't want an exit button. Perhaps a logout button, but that's it.
finish() closes activity (this is what you call intent, but it's not correct), not application. Application can not be finished at all (only forcefully killed like task killers do). You should design your activity stack in such a way that it will suit your needs. May be you should look at stack rearrangement examples in ApiDemos.
you can try this: System.exit(0);