从通知打开应用程序时如何应用正常 Activity 订单

How to Apply the Normal Activity Order When the App is Opened from the Notification

这是我的场景:我有一个播放流媒体音乐并创建(和更新)通知的服务。当按下通知时,用户将被带到 B activity.

我的应用程序的结构是 A -> B。

当用户按照以下流程进入主屏幕时:B -> A -> 主屏幕(服务继续播放音乐),按下通知会将用户带到 activity B,但是现在他无法返回 activity A。他被带到主屏幕。

我需要针对每种情况执行 B -> A 命令。

这是我的代码片段:

AndroidManifest.xml:

<activity
    android:name=".ChannelListActivity"
    android:configChanges="locale|keyboard|keyboardHidden|screenLayout|fontScale|uiMode|orientation|screenSize"
    android:launchMode="singleTask" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity
    android:name=".NowPlayingActivity"
    android:parentActivityName=".ChannelListActivity"
    android:launchMode="singleTop" >
</activity>

以及创建通知的代码:

Intent intentGoToApp = new Intent(this, NowPlayingActivity.class);
intentGoToApp.putExtra(NowPlayingFragment.EXTRA_CHANNEL_ID, mUserData.getPlayingChannelId());
intentGoToApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent piGoToApp = PendingIntent.getActivity(getApplicationContext(), 0, intentGoToApp, PendingIntent.FLAG_CANCEL_CURRENT);

那么,我需要更改或添加什么才能实现该行为?提前致谢...


编辑: 我尝试添加以下代码,但仍然没有得到想要的结果...

Intent intentGoToApp = new Intent(this, NowPlayingActivity.class);
intentGoToApp.putExtra(NowPlayingFragment.EXTRA_CHANNEL_ID, mUserData.getPlayingChannelId());
intentGoToApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//PendingIntent piGoToApp = PendingIntent.getActivity(getApplicationContext(), 0, intentGoToApp, PendingIntent.FLAG_CANCEL_CURRENT);

Intent intentMainActivity = new Intent(this, ChannelListActivity.class);

PendingIntent piGoToApp = TaskStackBuilder.create(this)
// add all of DetailsActivity's parents to the stack,
// followed by DetailsActivity itself
    .addNextIntentWithParentStack(intentMainActivity)
    .addNextIntentWithParentStack(intentGoToApp)
    .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);*/

您需要将 Activity A 添加到您的 backstack 以便 Android 知道每个 Activity.

退出的顺序

您可能会发现此 official documentation 有用。

Beginning in Android 4.1 (API level 16), you can declare the logical parent of each activity by specifying the android:parentActivityName attribute in the <activity> element. This allows the system to facilitate navigation patterns because it can determine the logical Back or Up navigation path with this information.

通过在 AndroidManifest.xml 文件中声明这种关系,使 Activity A 成为 Activity B 的父级,这样每次按下后退按钮时,父级 activity将被称为:

<activity
    android:name=".ActivityB"
    android:label="Activity B"
    android:parentActivityName=".ActivityA">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.yourpackage.MainActivity" />
</activity>

你可以做的技巧很少:

  1. 在 Activity B 的 public void onBackPressed() {} 中开始 Activity A 如果 Activity B 已经开始通知(并完成 Activity B);

    public class ActivityB extends Activity {
        static final String ACTION_NOTIFICATION = "ACTION_NOTIFICATION";
        boolean isStartedWithNotification;
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            setIntent(intent);
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ....
        }
    
        // OR onResume() if you don't use fragments
        @Override
        protected void onResumeFragments() {
            super.onResumeFragments();
            handleIntent();
        }
    
        void handleIntent() {
            Intent intent = getIntent();
            if (intent != null && ACTION_NOTIFICATION.equals(intent.getAction())) {
                // handle intent, populate UI based on it's information;
                isStartedWithNotification = true;
                setIntent(null);
            }
        }
    
        @Override
        public void onBackPressed() {
            if (isStartedWithNotification) {
                startActivity(new Intent(this, ActivityA.class)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                finish();
            } else {
                super.onBackPressed();
            }
        }   
    }
    
  2. 而不是通过通知启动 Activity B - 启动 Activity A 来处理意图并立即启动 Activity B;

    public class ActivityA extends Activity {
        static final String ACTION_NOTIFICATION = "ACTION_NOTIFICATION";
    
        @Override
        protected void onNewIntent(Intent intent) {
            super.onNewIntent(intent);
            setIntent(intent);
        }
    
        // OR onResume() if you don't use fragments
        @Override
        protected void onResumeFragments() {
            super.onResumeFragments();
            handleIntent();
        }
    
        void handleIntent() {
            Intent intent = getIntent();
            if (intent != null && ACTION_NOTIFICATION.equals(intent.getAction())) {
                setIntent(null);
                //START ACTIVITY B
            }
        }
    }
    

第一种方法更 hacky,但对于第一种方法,在低端设备上您可能会看到 "blinking" 的活动开关。所以我将从第一个开始。

希望对你有所帮助