Bring task to front on android.intent.action.USER_PRESENT

android, android-activity, task

Solution

Here's a slightly hackish implementation that works for me:

Create a simple BringToFront activity that simply `finish()` itself on its `onCreate()`:

public class BringToFront extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        finish();
    }

}

In your BroadcastReceiver, start the BringToFront activity above instead of your activity_A if the action is USER_PRESENT:

@Override
public void onReceive(Context context, Intent intent) {
    Class<? extends Activity> activityClass = activity_A.class;

    if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
        activityClass = BringToFront.class;
    }

    Intent i = new Intent(context, activityClass);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);
}

This works because the BringToFront activity has the same `taskAffinity` as your activity_A and starting it will make the system bring the existing task to the foreground. The BringToFront activity then immediately exit, bringing the last activity on your task (activity_B in your scenario) to the front.

It's worth noting that on API level 11 (Honeycomb), a `moveTaskToFront()` method is added to the system's ActivityManager service that might probably be the better way to achieve what you want.

Problem

BACKGROUND I have a task (i.e. app) with multiple activities. QUESTION How do I bring a task to the front w/o re-ordering the activity stack for that task? USER SCENARIO When the device boots (i.e. after android.intent.action.BOOT_COMPLETED broadcast is received) my app starts, call this task 1, and displays activity A (code below). As the user interacts with task 1, he/she opens activity B on the stack (activity B is now currently displayed on screen). Next the user taps the home key and opens some other task, call it task 2, then locks the screen. The user unlocks the screen, and the android.intent.action.USER_PRESENT intent is broadcast and received by my app (see manifest snippet below). My executes the startActivity() call in my IntentReceiver class as expected, but instead of just bringing the task to the foreground it creates a new task, call it task 3. CHANGES I'VE TRIED If I modify or change the Intent.FLAG_ACTIVITY_NEW_TASK to any other intent then I get this error message: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? ...so it looks like I have to use Intent.FLAG_ACTIVITY_NEW_TASK. If I change the main activity's lauchMode to "singleTask" the correct task is brought to the foreground (i.e. no new task is created), but the activity stack is reordered such that activity_A is on top of the stack. At this point I am at a loss as to how to bring an existing task to the foreground w/o re-ordering the activity stack while listening for the android.intent.action.USER_PRESENT intent, any help would be appreciated. BTW, This app is being delivered on to a group of employees, not the general public, on company owned android devices. CODE SNIPPETS To start the app I setup a broadcast receiver in my manifest file. ``` <application : <activity android:label="@string/app_name" android:launchMode="singleTop" android:name=".activities.activity_A" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> : <receiver android:enabled="true" android:name=".utilities.IntentReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" > <intent-filter > <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.USER_PRESENT" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver> ``` In my IntentReceiver class, I start my main activity... ``` public class IntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(context, activity_A.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } } ```

Original source