Android dynamic shortcuts not opening proper activity second time

2.5k views Asked by At

Hi I am developing shortcuts for android application. My code looks like

private void setShortMenu() {

    ArrayList<ShortcutInfo> shortcutInfos = new ArrayList<>();

    Intent intent = new Intent(this, SampleActivity2.class);
    intent.setAction(Intent.ACTION_VIEW);
    intent.putExtra("val",1);
    intent.addCategory("android.shortcut.conversation");
    ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);

    ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id2")
            .setShortLabel("Web site")
            .setLongLabel("Open the web site")
            .setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
            .setIntent(intent)
            .build();
    shortcutInfos.add(shortcut);

    Intent intent2 = new Intent(this, SampleActivity3.class);
    intent2.setAction(Intent.ACTION_VIEW);
    intent.addCategory("android.shortcut.conversation");
    intent.putExtra("val",2);

    ShortcutInfo shortcut2 = new ShortcutInfo.Builder(this, "id1")
            .setShortLabel("Web site...")
            .setLongLabel("Open the web site...")
            .setIcon(Icon.createWithResource(this, R.mipmap.ic_launcher))
            .setIntent(intent2)
            .build();
    shortcutInfos.add(shortcut2);

    shortcutManager.setDynamicShortcuts(shortcutInfos);
}

My manifest looks like this :

<application
    android:name=".SampleApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
            <!--<meta-data android:name="android.app.shortcuts"
            android:resource="@xml/shortcuts" />-->
    </activity>
    <activity android:name=".SampleActivity" />
    <activity android:name=".SampleActivity2" />
    <activity android:name=".SampleActivity3"></activity>

Issue with this code is like this. I killed application from background. click on first shortcut. It opens SampleActivity2. I minimised the application by clicking home button and click on second shortcut. It opens SampleActivity3. Till this point everything is correct. But now if I click on first menu or second menu it always opens SampleActivity3 which is last minimised activity. If I do same thing thing with static way of shortcuts then it works fine:

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
    android:shortcutId="compose"
    android:enabled="true"
    android:icon="@mipmap/ic_launcher"
    android:shortcutShortLabel="@string/compose_shortcut_short_label1"
    android:shortcutLongLabel="@string/compose_shortcut_short_label1"
    android:shortcutDisabledMessage="@string/compose_shortcut_short_label1">
    <intent
        android:action="android.intent.action.VIEW"
        android:targetPackage="com.example.nilkash.shortcutmenu"
        android:targetClass="com.example.nilkash.shortcutmenu.SampleActivity2" >
        <extra android:name="val" android:value="1" />
    </intent>
    <categories android:name="android.shortcut.conversation" />
</shortcut>

<shortcut
    android:shortcutId="compose1"
    android:enabled="true"
    android:icon="@mipmap/ic_launcher"
    android:shortcutShortLabel="@string/compose_shortcut_short_label2"
    android:shortcutLongLabel="@string/compose_shortcut_short_label2"
    android:shortcutDisabledMessage="@string/compose_shortcut_short_label2">
    <intent
        android:action="android.intent.action.VIEW"
        android:targetPackage="com.example.nilkash.shortcutmenu"
        android:targetClass="com.example.nilkash.shortcutmenu.SampleActivity3" >
        <extra android:name="val" android:value="2" />
    </intent>
    <categories android:name="android.shortcut.conversation" />
</shortcut>

and in manifest I added :

<activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
            <meta-data android:name="android.app.shortcuts"
            android:resource="@xml/shortcuts" />
    </activity>

Is there any thing wrong in my code. Need some help. Thank you.

1

There are 1 answers

11
David Wasser On BEST ANSWER

This can be confirmed after you post your manifest, but I'm guessing the following is happening:

When you use the first shortcut, Android creates a new task for your app and launches SampleActivity2 into the task. You then press HOME, which just sends this task to the background.

Now you use the second shortcut. Because SampleActivity3 has the same taskAffinity as SampleActivity2, Android brings the existing task containing SampleActivity2 to the foreground and launches SampleActivity3 into that task. Your task now contains SampleActivity2->SampleActivity3. You now press HOME again. The task is moved to the background.

If you now use the first shortcut, Android recognizes that you are trying to launch the "root" Activity of an existing task, and just brings the existing task to the foreground and does not launch any new Activity into it. The task contains SampleActivity2->SampleActivity3 so you will see SampleActivity3 since this is the top Activity in the task. This behaviour is exactly the same as when you have, for example, Whatsapp running, press HOME, then press the Whatsapp icon on your HOME screen. This doesn't "start Whatsapp from the beginning", it just brings the current task containing Whatsapp to the foreground in whatever state it was in when it was moved to the background.

If you now press HOME and use the second shortcut, Android finds your task with the same taskAffinity as SampleActivity3 and brings the existing task to the foreground. Android will now either do nothing (if SampleActivity3 has launchMode="singleTop") or create a new instance of SampleActivity3 and launch that into the task. In that case your task will contain 3 Activity instances: SampleActivity2->SampleActivity3->SampleActivity3 and you will see SampleActivity3 since this is the top Activity in the task.


NOTE: As can be seen in the comment discussion below, it is important to add

addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

to the Intent used to launch the Activity if you want to ensure that a new instance of the Activity is created. Otherwise, Android will just bring the existing task to the foreground and won't launch any new Activity.