2012-07-18 86 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