從Notification發通知跳轉引發的幾個問題

這兩天做了一個Notification 通知消息的東西,需要從通知點擊調到指定的Activity,一般來說,這個需求挺簡單的,直接在通知中添加,一個Intent 然後使用PendingIntent就可以完成需求。問題出現在了需求是要跳轉到正在運行的MainActivity中的Fragment中去。結果發現使用原來的方法getIntent去獲取數據就獲取不到了。經過一通的搜索Google才找到了解決方案,這會特地記錄一下。

正常使用一個Notification 打開一個activity:

 NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        Intent intent = new Intent();
        intent.putExtra(MainActivity.FLAG_MAINACTIVITY, MainActivity.PAGEINDEX_2);
        builder.setContentText("您有新的任務!");
        builder.setContentTitle("這個是標題");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher));
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setPriority(NotificationCompat.PRIORITY_HIGH);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        builder.setContentIntent(pendingIntent);
        Notification notification = builder.build();
        //notification.flags = Notification.FLAG_NO_CLEAR | Notification.DEFAULT_SOUND;
        notificationManager.notify(1, notification);
正常的邏輯在MainActivity中我們可以使用getIntent方法獲取到這個通知附帶的數據。這裏要說明的是這個activity要在沒有運行的情況下這樣是可以的。當前的MainActivity就是應用的主界面,所以我一直獲取不數據。

在stackoverflow找到了一篇文章,差不多和我的情況一樣,參考這裏我找到了一些解決的方法。

1.notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);  //設置這個參數

2.在MainActivity中重寫onNewIntent()方法 。並且設置setIntent().

3. PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); //設置參數

 @Override
    protected void onNewIntent(Intent intent) {
        //super.onNewIntent(intent);
        this.setIntent(intent);
        LogUtils.e("TAG", "main-onNewIntent");
        obtainFragmentIndex = getIntent().getIntExtra(MainActivity.FLAG_MAINACTIVITY, -1);
        setRadioChecked(obtainFragmentIndex);
    }
上面兩個方式基本上就解決的這個問題。這樣我們遇到的問題就先解決了,然後來看看原因。在上面搜索的文章中有說到,這個是因爲我們給Activity設置了一個SingleTask的啓動模式。這樣正在運行的MAinActivity就不會再啓動,所以之前一直沒有拿到數據。onNewIntent就是用來解決這個問題的,在onNewIntent中調用setIntent從新設置Intent後我們就可以拿到數據了。總的來說,還是自己太菜,四種啓動模式沒有搞清楚。

在解決了問題之後又查了一些資料對於上述的幾個概念做一些解釋:

1.FLAG_ACTIVITY_NEW_TASK

在新任務中啓動Activity,如果已經爲正在啓動的Activity運行任務,則改任務會轉到前臺並恢復期最後狀態,同時Activity會在onNewIntent() 中收到新的Intent。這個就會和SingleTask 的啓動模式一樣的行爲。

2.FLAG_ACTIVITY_SINGLE_TOP

如果正在啓動的Activity是當前的Activity(位於返回棧的頂部),則現在實例會接受對onNewIntent()的調用,而不是創建Activity的新實例。這個行爲和SingleTop 啓動模式相同。

3.FLAG_ACTIVITY_CLEAR_TOP

如果正在啓動的Activity已在當前的任務中運行,則會銷燬當前任務頂部的所有Activity,並通過onNewIntent()將Intent 傳給Activity已恢復的實例(現在位於頂部)而不是啓動該Activity的新實例。產生這個行爲沒有對應的啓動模式。

FLAG_ACTIVITY_CLEAR_TOP一般和FLAG_ACTIVITY_NEW_TASK結合使用。一起使用時,通過這些標誌,可以找到其他任務中現有的Activity,並將其放入可以從中相應的Intent的位置。

這些事從Android開發文檔中找到的。開發文檔 中詳細介紹了四種啓動模式的使用,以及這些參數的關聯使用方式。這應該是最好的學習文檔了。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章