2012-07-18 165 views
32

這似乎是一個普遍的問題,我經歷了所有相關的問題去,我能找到已經: Activity isn't picking up new intentWhy extra data (integer) is not sent in android notification intent?Notification passes old Intent ExtrasCan't put extras for an intent in notificationandroid pending intent notification problem;但仍然無法弄清楚。意圖沒有額外

問題是一樣的。我用PendingIntent設置了一個通知,其中攜帶了一些額外的信息,但我不知道它的另一面。

下面是用於生成通知的代碼:

Notification notification = new Notification(R.drawable.icon, getResources().getString(R.string.notification_ticker), System.currentTimeMillis()); 
notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONLY_ALERT_ONCE; 

Intent start_test = new Intent(this, MyActivity.class); 
start_test.putExtra("start_test", true); 
start_test.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

PendingIntent pi = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), start_test, PendingIntent.FLAG_CANCEL_CURRENT); 
notification.setLatestEventInfo(this, getResources().getString(R.string.notification_title), getResources().getString(R.string.notification_content, expired), pi); 
nm.notify(NOTIFICATION_ID, notification); 

而在另一側上:

boolean start_test=getIntent().getBooleanExtra("start_test", false); 

束實際上不存在(getExtras()返回null)。

我試過PendingIntent.getActivityFLAG_UPDATE_CURRENT,FLAG_CANCEL_CURRENT,FLAG_ONE_SHOT)的不同標誌,這些都沒有幫助。

如上代碼所示,我用getCurrentMillis確保的RequestID變化....

還發現,在MyActivity,onCreateonNewIntent沒有得到調用。只有onResume是。即使FLAG_ACTIVITY_NEW_TASK已設置...?

我錯過了很簡單的東西嗎?

+0

如果你只想把一個額外然後用'Bundle'忘記。只需使用'new_intent.putExtra(「start_test」,真)'然後在另一端只使用'getIntent.getBooleanExtra(「start_test」,假)' – Squonk 2012-07-18 22:32:28

+0

是的,我想這樣也,它並沒有改變任何東西...仍然沒有得到它在另一邊 – Matthieu 2012-07-18 22:43:38

+0

當這種情況發生時,你的應用程序是否正在運行(或在後臺)?活動堆棧頂部是否有「MyActivity」? – 2012-07-19 14:38:13

回答

41

的通知意向設置FLAG_ACTIVITY_NEW_TASK將導致以下後果:

  • 如果活動是在任務已經運行,新的任務將被啓動,並且打算將交付給活動在onCreate()

  • 但是,如果活動已在任務中運行,那麼該任務將被帶到前臺。就這樣。意圖將而不是交付和onNewIntent()將不會被調用。

如果你想意圖實際交付你需要指定:

start_test.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 
        Intent.FLAG_ACTIVITY_SINGLE_TOP); 

它使沒有區別活動的launchMode是否singleTop與否,你仍然必須在意圖中指定Intent.FLAG_ACTIVITY_SINGLE_TOP

注:如果該活動已在任務運行和活動是在該任務的活動堆棧的頂部,任務將被推上前臺。就這樣。意向將而不是被交付。實現這一點的唯一方法是將Intent.FLAG_ACTIVITY_CLEAR_TOP添加到其他2個標誌,但這可能不是您想要發生的情況(取決於您的具體情況)。

見我(還)在谷歌代碼開放問題在http://code.google.com/p/android/issues/detail?id=17137

+2

感謝了很多詳細的解釋。還必須將PendingIntent.getActivity中的標誌設置爲FLAG_CANCEL_CURRENT,否則將多次調用onNewIntent。不完全確定爲什麼,但現在似乎按預期工作。 – Matthieu 2012-07-19 17:49:28

+2

因爲它總是把首要意圖傳遞給它,而不是通知。所以你將需要覆蓋 - '@Override 保護無效onNewIntent(意圖意圖){ super.onNewIntent(intent); setIntent(intent); }' 所以你的意圖將被收到。 – Darpan 2014-10-08 10:29:25

0

更簡單的方法:真正的問題是,意向,爲同一個目標,被替換。我剛剛創建了一個新服務「NotificationDismissalService」來解決這個問題。唯一的意圖去那個服務是setDeleteIntent項目。因爲這是一項獨特的服務,所以參數不會被替換。 NotificationDismissalService的主體(和這將真正是每個唯一意圖類型一個這樣解僱服務)是一種簡單的實現發送的意圖的優選服務(讀/寫正確的參數)「onStartCommand」的。因爲這是一個服務的實際發送,而沒有在它之間的pendingintent,它工作得很好。

24

我剛添加的PendingIntent.FLAG_UPDATE_CURRENT標誌,以待處理的意圖,並開始爲我工作(跳過意圖所有標誌)。

示例代碼:

PendingIntent pendIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
+0

謝謝,這工作! :)沒有必要再添加任何東西。 – Makalele 2015-05-03 16:05:08

+0

這應該是公認的答案,因爲它更容易實現 – leoderprofi 2015-10-23 23:31:46

+0

接受的答案不適用於我在api 16 - 但是,這完成了16 - 23完美 – runfaj 2016-04-25 04:44:04

3
  1. 如果不需要那麼避免設置在明顯的活動作爲一個單一的任務。省略這一行,或者你可以把它改成singleTop:

    android:launchMode="singleTask」 
    
  2. 如果你必須有一個任務,然後在待定意圖的標誌集合到: 意圖。 FLAG_ACTIVITY_NEW_TASK |意圖。 FLAG_ACTIVITY_CLEAR_TASK 和的PendingIntent。 FLAG_CANCEL_CURRENT

    resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK); 
    pIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_CANCEL_CURRENT); 
    
  3. 如果你有一個單一的任務 - 通過setIntent(意向)重置您的臨時演員在裏面onNewIntent()的活動;

    protected void onNewIntent(Intent intent) { 
         setIntent(intent); 
         ... 
    } 
    
+0

在我的情況下,它有效地處理了FLAG_UPDATE_CURRENT到未決意圖 – 2017-11-04 08:54:32

0

你可以故意發送額外以下方式

PendingIntent contentIntent ; 
Intent intent = new Intent(this,TestActivity.class); 
intent.putExtra("extra","Test"); 
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); 

stackBuilder.addParentStack(ArticleDetailedActivity.class); 

contentIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT); 

要獲得測試Activity類意向額外的價值,你需要編寫如下代碼:

Intent intent = getIntent(); 
String extra = intent.getStringExtra("extra") ; 
0

我使用了這樣的事情

Intent myIntent = new Intent(context, DoSomething.class); 
PendingIntent pendingIntent = PendingIntent.getActivity(
     context, 
     0, 
     myIntent, 
     Intent.FLAG_ACTIVITY_NEW_TASK); 

檢查出完整的例子here