Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

app restarts if select app from recent apps only when activity is start from Notification

My app has activity stack like below

  • A: loading activity
  • B: main activity
  • C: detail activity

and manifest is like this

<activity A>
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>
<activity B android:launchMode="singleTask"/>
<activity C/>

when I start app from launcher, it acts as A -> B -> C . press Home button at activity C and recall it from recent app list(long press Home), C is shown. this is OK.

but when I starts app from Notification, as I don't want to show loading screen, starts activity B. so, user can navigate B -> C.

but when user press Home at activity C and select app from recent app list, B is restarted and state is not preserved. So C activity is always disappears.

I've tried many flag options, but I didn't find a solution. What I want is that app behaves just like when user starts app from launcher.

I created pending intent for notification like this. In my app, I should use Intent.FLAG_ACTIVITY_CLEAR_TOP for activity B.

Notification notice = new Notification(R.drawable.icon_notification, context.getString(R.string.app_name), System.currentTimeMillis());

Intent intent = new Intent(context, B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtras(i);

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

I think the recent app list send same intent with notification, so always activity B is called. But when I launch app from launcher, it just send me to the last activity C, not B.

plz help me. :(

UPDATE

I've solved this problem like below.

  • Add new activity D with different task affinity. This activity just starts B(main activity)
  • In notification, start activity D
  • In activity D, start activity B with some flags and finish itself
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)  != 0 ) {
  i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | Intent.FLAG_ACTIVITY_NEW_TASK);
} else {
  i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

And I've registered activity D like below

   <activity
            android:name="D"
            android:clearTaskOnLaunch="true"
            android:excludeFromRecents="true"
            android:exported="false"
            android:launchMode="singleInstance"
            android:noHistory="true"
            android:taskAffinity="xxx"
            android:theme="@android:style/Theme.NoDisplay">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
    </activity>
like image 573
kingori Avatar asked Apr 04 '12 09:04

kingori


2 Answers

Since the notification has launched the app, it's now part of the history - you probably want to only handle it when it's actually tapped. Check for:

(getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0

If it's true, the activity is being opened from the history, not the notification's intent.

like image 56
Groxx Avatar answered Sep 20 '22 11:09

Groxx


I suppose that you deal with 2 separate tasks with their own activities back stacks because of using the Intent.FLAG_ACTIVITY_NEW_TASK. First task is created when you start A from the launcher, while the second being created when you start B from notification. If so then you should be sure that 2 separate tasks is what you really need.

like image 32
a.ch. Avatar answered Sep 19 '22 11:09

a.ch.