Android PendingIntent附加功能更新,如何预防?

时间:2014-06-05 18:59:05

标签: android google-cloud-messaging android-pendingintent

我在我的应用程序中实现了GCM客户端:http://developer.android.com/google/gcm/client.html

但在我的GcmIntentService中,我想发送2个不同附加内容的通知 在第一次通知中,我将notif1额外设置为true,我没有设置notif2额外费用。
在第二次通知中,我将notif2额外设置为true,我没有设置notif1额外费用。

但是当我点击通知并检查其额外数据时,我发现第一个和第二个PendingIntents都有相同的额外数据。

关于documentation FLAG_UPDATE_CURRENT导致此行为。所以我将其更改为FLAG_ONE_SHOTFLAG_CANCEL_CURRENT。但在这种情况下,早期的通知' PendingIntents被取消。

那么如何使用不同的额外数据从GcmIntentService发送2个通知?

最低服务代码如下:

public class GcmIntentService extends IntentService {
    Context mContext;

    public GcmIntentService() {
        super("GcmIntentService");
        mContext = this;
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(mContext);
        String messageType = gcm.getMessageType(intent);

        if (extras != null) {
            if (!extras.isEmpty()) {
                if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {

                    // first notification
                    Map<String, Boolean> pExtrasMap1 = new HashMap<String, Boolean>();
                    pExtrasMap1.put("notif1", true);
                    sendNotification(mContext, "My Title 1", "Hello 1..", pExtrasMap1);

                    // second notification
                    Map<String, Boolean> pExtrasMap2 = new HashMap<String, Boolean>();
                    pExtrasMap2.put("notif2", true);
                    sendNotification(mContext, "My Title 2", "Hello 2..", pExtrasMap2);

                }
            }
        }
    }


    public static void sendNotification(Context pContext, String pTitle, String pText, Map<String, Boolean> pExtras) {
        Integer notifId = 1 + (int)(Math.random() * ((100000 - 1) + 1));

        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(pContext)
                        .setContentTitle(pTitle)
                        .setContentText(pText)
                ;
        Intent targetIntent = new Intent(pContext, MyPrettyActivity.class);
        for (Map.Entry<String, Boolean> entry : pExtras.entrySet())
        {
            targetIntent.putExtra(entry.getKey(), entry.getValue());
        }

        //PendingIntent contentIntent = PendingIntent.getActivity(pContext, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        //PendingIntent contentIntent = PendingIntent.getActivity(pContext, 0, targetIntent, PendingIntent.FLAG_ONE_SHOT);
        PendingIntent contentIntent = PendingIntent.getActivity(pContext, 0, targetIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        builder.setContentIntent(contentIntent);
        NotificationManager nManager = (NotificationManager) pContext.getSystemService(Context.NOTIFICATION_SERVICE);
        nManager.notify(notifId, builder.build());
    }

}

3 个答案:

答案 0 :(得分:0)

在您当前的实施中(如下所述),两个通知都具有相同的ID,因此第二个通知将替换第一个通知。如果要同时查看两者,则应使用唯一ID。

public static void sendNotification(Context pContext, String pTitle, String pText, Map<String, Boolean> pExtras) 
{
     Integer notifId=1;
    ...
     nManager.notify(notifId, builder.build());
}

此外,正如pskink建议的那样,尝试对两个通知使用不同的请求代码(这是下面的0参数):

PendingIntent contentIntent = PendingIntent.getActivity(
    pContext, 0, targetIntent, PendingIntent.FLAG_CANCEL_CURRENT);

答案 1 :(得分:0)

我遇到了类似的问题。所以我使用setAction()来克服这一点,因为我只需要传递一个值并使用 ACTION 就可以了。

答案 2 :(得分:0)

正如用户pskink在另一个答案的评论中指出的那样,您需要使用不同的请求代码。 PendingIntents实际上并不是唯一存储在Android Framework端的每个对象,它们仅在PendingIntent的几个部分上进行哈希处理并以这种方式存储。如果在这些特定部分中有两个相同的PendingIntents,则框架认为它们是相同的。

  

由于这种行为,为了检索PendingIntent,重要的是要知道两个Intent何时被认为是相同的。人们常犯的一个错误是使用Intents创建多个PendingIntent对象,这些对象只在其“额外”内容中有所不同,期望每次都获得不同的PendingIntent。这不会发生。用于匹配的Intent部分与Intent.filterEquals定义的部分相同。如果你使用两个相当于Intent.filterEquals的Intent对象,那么你将获得两个相同的PendingIntent。

     

有两种典型的方法可以解决这个问题。

     

如果您确实需要多个不同的PendingIntent对象同时处于活动状态(例如用作同时显示的两个通知),那么您需要确保关联它们的某些内容有所不同他们有不同的PendingIntents。这可以是Intent.filterEquals考虑的任何Intent属性,也可以是提供给getActivity(Context, int, Intent, int)getActivities(Context, int, Intent[], int)getBroadcast(Context, int, Intent, int)getService(Context, int, Intent, int)的不同请求代码整数。

我在GCM实现中解决这个问题的方法是为每个PendingIntent为requestCode分配一个随机整数。