這兩天做了一個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開發文檔中找到的。開發文檔 中詳細介紹了四種啓動模式的使用,以及這些參數的關聯使用方式。這應該是最好的學習文檔了。