26

My application is in running mode[foreground] and user clicks on home button, which puts application to background[and still running]. I have alarm functionality in my application which fires up. I want is when my alarm goes off i want to bring my background running application in foreground and from last state in which it was.

    <application
            android:name="com.abc.android.state.management.MainEPGApp"
            android:icon="@drawable/icon"
            android:label="@string/app_name"
            android:largeHeap="true"
            android:logo="@drawable/app_logo" >
            <activity
                android:name=".SplashScreen"
                android:label="@string/app_name"
                android:launchMode="singleTop"
                android:screenOrientation="nosensor"
                android:theme="@style/Theme.Sherlock" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        <activity
                    android:name=".Starter"
                    android:configChanges="orientation|screenSize"
                    android:screenOrientation="behind"
                    android:launchMode="singleTop"
                    android:uiOptions="none"
                    android:windowSoftInputMode="adjustPan" />
</application>
Zoombie
  • 3,590
  • 5
  • 33
  • 40

7 Answers7

74
Intent intent = new Intent(context, MyRootActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

You should use your starting or root activity for MyRootActivity.

This will bring an existing task to the foreground without actually creating a new Activity. If your application is not running, it will create an instance of MyRootActivity and start it.

EDIT

I added Intent.FLAG_ACTIVITY_SINGLE_TOP to Intent to make it really work!

Second EDIT

There is another way to do this. You can simulate the "launching" of the app the same way that Android launches the app when the user selects it from the list of available apps. If the user starts an application that is already running, Android just brings the existing task to the foreground (which is what you want). Do it like this:

Intent intent = new Intent(context, SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // You need this if starting
                                                //  the activity from a service
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • 2
    Yes, it worked intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) did a trick, but i start root activity as new one, which do not preserve its state from which it left of. Actually i am working with 5 Fragment inside that Root activity. But your answer it starts of new root activity with 1st fragment initialized. Anyways that is another problem i have to resolve, But so far above answer works for me. Thanks – Zoombie Aug 23 '12 at 06:03
  • Post your manifest please. If you have an existing task in the background with the root activity still active (ie: not **finished**), it shouldn't create any new activities, just bring that task to the foreground. – David Wasser Aug 23 '12 at 06:44
  • yes exactly same thing happening here, activity still active but in background mode, just needed to bring it in front. But how to do it, i am still looking after it – Zoombie Aug 23 '12 at 07:00
  • Please post add your manifest to the question. It will help to troubleshoot this problem. – David Wasser Aug 23 '12 at 07:01
  • I figured out myself, actually `Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT` is useful for bringing your activity to front rather than `New_Task`. As well in manifest, keep your root acitivity with launchMode = "singleInstance" so no more than one instance can flow for root activity in Android system. – Zoombie Aug 23 '12 at 10:54
  • 1
    Um...no. `Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT` is set by Android when it brings a background task to the foreground. You can set it if you want but it doesn't **do anything**. Also, `launchMode="singleInstance"` is intended for HOME-screen replacements only. Be aware that if your root activity now starts another activity, that activity will not be launched into the same task, but will be launched into a **new task**. If it is one of your application's activities you will have created mass confusion as you will now have 2 tasks which both have the same name and icon in the list of recents. – David Wasser Aug 23 '12 at 11:33
  • Yes i have to agree, what i did is wrong, singleInstance creates another issue that is it creates its own task for one root activity and other activity launches in different task, So 2 tasks for same app running at same time. – Zoombie Aug 24 '12 at 03:25
  • You should try to solve this in the way I originally suggested. Please post your manifest and maybe we can see something in there. – David Wasser Aug 24 '12 at 08:21
  • With `intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);` it starts new acitivity itself which is duplicate of which is running in background. – Zoombie Aug 24 '12 at 08:57
  • Did you start the application for the first time from the list of available applications? or did you launch it from a debugger or from the installer? How does the application get launched? I don't see the `intent-filter` for MAIN/LAUNCHER. – David Wasser Aug 24 '12 at 10:10
  • Main launcher application is different from this, for that i will edit my question again – Zoombie Aug 24 '12 at 10:24
  • Right. So, you need to use the **root** activity as I said in my answer. You need to call `startActivity()` on `SplashScreen` with `Intent.FLAG_ACTIVITY_NEW_TASK` to get your task to come to the foreground from the background. – David Wasser Aug 24 '12 at 12:26
  • Sure, i should try this thing too, But do you think should i set launchMode="singleTop" or launchMode="singleTask" – Zoombie Aug 24 '12 at 12:49
  • I don't know exactly how your application works. If your application is **not** started by other applications, but only by the user, then you do **not** need `singleTask` or `singleInstance` launch mode. I would try to use the standard launch mode first and see where that may cause you a problem. – David Wasser Aug 24 '12 at 13:00
  • Tried with singleTask and singleTop launchMode and also way you have mentioned to startActivity for SplashScreen with Intent.FLAG_ACTIVITY_NEW_TASK, But still no luck. Sorry if am asking too much of help now. – Zoombie Aug 24 '12 at 14:08
  • See my edit. I wrote a small test program to test all of this and discovered (again) that the documentation isn't 100% correct. Sigh. I'm so sorry about this. You should be able to set the launch modes in the manifest to "standard" – David Wasser Aug 24 '12 at 14:54
  • 7
    Just want to mention, in case any one else sees this, the solution in David's "Second EDIT" worked perfectly for me. – Paul Richter Feb 06 '13 at 19:46
  • The "Second Edit" behavior works for me when testing on HTC One and Nexus 7, but it doesn't work on a Samsung Galaxy Tab: it causes a new instance of the root activity to be displayed. (Why is simply redisplaying your app's existing task so difficult?) – Kristopher Johnson Aug 19 '13 at 14:24
  • @KristopherJohnson are you sure you aren't seeing symptoms of another Android bug? Did you start your app for the first time directly from the Installer screen or from an IDE (Eclipse, IntelliJ, etc.)? If so, try force stopping your app then starting it again by clicking on the app icon. Then put the app in background with HOME button and see how it behaves. – David Wasser Aug 19 '13 at 14:41
  • @DavidWasser: The app actually works "as expected" when I launch from IDE. It does the wrong thing when I launch from app icon and use HOME button. However, it looks like maybe I don't have FLAG_ACTIVITY_NEW_TASK set. – Kristopher Johnson Aug 19 '13 at 15:15
  • `SplashScreen.class` reminds me the **IMSDroid** application:) – Fer Jan 28 '15 at 12:59
  • I used the first option but had to do `getApplicationContext().startActivity(intent);` because it seems I can't start the activity from the very same activity. – Ferran Maylinch Dec 12 '15 at 16:54
  • 1
    @FerranMaylinch see http://stackoverflow.com/a/29769255/769265 there is an issue pre-Android 4.4 that prevents this from working if you call `startActivity()` from an Activity `Context`. – David Wasser Dec 12 '15 at 20:07
  • Thanks David! You could comment that on your solution. – Ferran Maylinch Dec 12 '15 at 20:12
  • The solution David Wasser suggested is not working reliably with recent Android APIs. Specifically with API 23, it seems to work on some of my builds and not on others. Sometimes it works when I Run the code from Eclipse, but not when I export the same code to a file and sideload. I think it is not a problem with the solution itself, but I have no clue what is causing this behavior..... – SoloPilot Feb 26 '16 at 18:33
  • @SoloPilot you should post a new question for your specific problem. Adding a comment to this answer won't get your problem the attention it deserves. – David Wasser Feb 27 '16 at 08:57
  • Two things that got me stuck: 1. context is getApplicationContext() if you don't already have it. 2. Use the name of the activity that is launched at start, NOT the one you are in. – FlorianB Sep 12 '16 at 22:10
  • Definition of "root activity": https://stackoverflow.com/questions/46436787/what-is-the-root-activity-in-android – ban-geoengineering Sep 30 '19 at 16:43
  • I am using React Native for Android and would like to use this approach. Is it possible for me to add this code in my Java project using React Native? Where can I put my code? I am receiving `Firebase Cloud Messaging ` data only messages when the app is in the background or killed successfully. Thank in advance. – Mr. Robot Oct 27 '19 at 11:40
  • @DavidWasser how do I bring back terminated app? – BIS Tech Feb 02 '21 at 18:29
11

A combination that works for me is to use:

Intent bringToForegroundIntent = new Intent(context, RootActivity.class);
bringToForegroundIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(bringToForegroundIntent);

If you check the logs on the device whenever you start an activity from a launcher icon this is the intent that gets passed to launch the app or move it back to foreground if e.g. user clicked the Home button.

Piotr Zawadzki
  • 1,678
  • 1
  • 18
  • 24
  • 1
    No part in the accepted answer has worked for me, but this did exactly what I wanted - same behavior as clicking your app from the Recent apps. – Cord Rehn Jan 27 '17 at 21:38
11

I find a new way to bring app to foreground, It imitate click Icon to launch application.

    PackageManager packageManager = context.getPackageManager();
    Intent intent = packageManager.getLaunchIntentForPackage(pkName);
    if (intent != null)
    {
            //模拟点击桌面图标的启动参数
            intent.setPackage(null);
         // intent.setSourceBounds(new Rect(804,378, 1068, 657));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
           context.startActivity(intent);

    }

it work for me, But who can tell me why package must be null

jiaqiang huang
  • 161
  • 1
  • 6
  • For why the package is null, `Set an explicit application package name that limits the components this Intent will resolve to. If left to the default value of null, all components in all applications will be considered. If non-null, the Intent can only match the components in the given application package.` – Hamza Khurshid Jun 09 '22 at 19:15
10

You can use the below code to bring the application to front:

private void bringApplicationToFront()
    {

        Log.d(TAG, "====Bringging Application to Front====");

        Intent notificationIntent = new Intent(this, MainActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        try 
        {
            pendingIntent.send();
        }
        catch (CanceledException e) 
        {
            e.printStackTrace();
        }
    }
Smeet
  • 4,036
  • 1
  • 36
  • 47
  • 2
    This only works if the application has one Activity. If the application has more than one Activity, and the user is not in the root Activity, this code will not bring the application to the foreground in the same state it was in, which is OP's requirement. – David Wasser Dec 13 '15 at 22:22
  • @David Wasser. No my launcher activity is splash screen and I am bringing the MainActivity in front and it is working fine. Your solution is not working so I place the code here. Actually the flow is something like that : I have a broadcast receiver in my main activity, and when it receives the broadcast and if my main activity in in background then I want main activity to bring to front. – Smeet Dec 14 '15 at 06:55
  • 1
    My solution should work and I don't know why it doesn't. Maybe you can open a new question and we can see why it doesn't work. In general, your solution doesn't work if you don't know exactly what `Activity` the user is in. It only works if you know exactly that the user is in `MainActivity`. Your answer isn't a good general solution, although it may work in a specific case. – David Wasser Dec 14 '15 at 07:31
5

From my test, to mimic the Launcher behavior, the key is to:

intent.setPackage(null);

after

Intent intent = packageManager.getLaunchIntentForPackage(pkName);

Other methods in this thread doesn't work in my case.

Thanks to jiaqing's answer, I post this answer as I don't have the right to comment. I don't know the logic behind this either, I guess it's related with the task owner. Anyone knows, would be glad to know.

Chaofan Zhang
  • 51
  • 1
  • 3
  • intent.setPackage(null); weardly also worked for me! This now resumes an existing activity from another app – keno Jul 06 '22 at 09:22
4

Using the ActivityManager class you can bring a running task to front

void bringToFront(){

 ActivityManager activtyManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
 List<ActivityManager.RunningTaskInfo> runningTaskInfos = activtyManager.getRunningTasks(3);
 for (ActivityManager.RunningTaskInfo runningTaskInfo : runningTaskInfos)
            {
              if (this.getPackageName().equals(runningTaskInfo.topActivity.getPackageName()))
                {
                     activtyManager.moveTaskToFront(runningTaskInfo.id, ActivityManager.MOVE_TASK_WITH_HOME);
                     return;
                 }
             }
}
sonal balekai
  • 395
  • 4
  • 10
1

For an alarm, you want to take a look at starting an Android Service

This service will be more resilient than your application which may be killed while in the background and can fire off an intent to bring your application to the front (or restart it if it was killed) when it is time for the alarm to go off.

Community
  • 1
  • 1
Guykun
  • 2,780
  • 23
  • 28
  • Alarm functionality is running using AlarmManager and PendingIntent fired through application, which do not include any Android Service. – Zoombie Aug 23 '12 at 06:00