android - 推送通知未打开正确的屏幕

标签 android notifications google-cloud-messaging gcmlistenerservice

我有一个应用程序,可以在 GcmListenerService 中获取 GCM 推送通知(如 gcm android 示例中所示)。每当我收到通知时,我都会收到一些 JSON ,其中包含与显示通知相关的数据。

现在假设我收到一条通知“有人给我添加了书签”,为此我获得了该用户的pk(标识符),当我单击该通知时,它会使用pk 在推送通知中收到以显示该用户的个人资料。

问题:如果我收到 2 个上述类型的通知,那么无论我点击哪一个通知,我总是会转到最近收到通知的人的个人资料。

在其他通知之上获取通知是否会覆盖先前通知的值,以便只有最新的通知才有效?这是否意味着我只能显示来自应用程序的一条推送通知?如果需要的话我可以发布代码。

相关代码:

@Override
    public void onMessageReceived(String from, Bundle data) {
        tinyDB = new TinyDB(this);
        if (tinyDB.getBoolean(AppConstants.LOGIN_STATE, false)) {
            try {
                Log.i("NOTIF", data.toString());
                String screen = data.getString("screen");
                String dataJson = data.getString("data");
                String displayJson = data.getString("display");
                String notification_id = data.getString("notif_id");
                String priority = data.getString("priority");
                String style = data.getString("style");

                Gson gson = new GsonBuilder().disableHtmlEscaping().create();
                NotificationVal notificationVal = gson.fromJson(displayJson, NotificationVal.class);

                String title = notificationVal.getTitle();
                String text = notificationVal.getText();
                String largeText = notificationVal.getLargeText();
                String smallIcon = notificationVal.getSmallIcon();
                String largeIcon = notificationVal.getLargeIcon();

                Bitmap smallImage = null;
                Bitmap largeImage = null;

                if (!TextUtils.isEmpty(smallIcon)) {
                    smallImage = getBitmapFromURL(smallIcon);
                }

                if ("big_picture".equalsIgnoreCase(style) && (largeImage != null)) {
                    NotificationCompat.BigPictureStyle notificationStyle = new NotificationCompat.BigPictureStyle();
                    notificationStyle.setBigContentTitle(title);
                    notificationStyle.setSummaryText(text);
                    notificationStyle.bigPicture(largeImage);

                    Intent intent = NotificationIntentBuilder.get(this, dataJson, screen, smallIcon, largeIcon, notification_id);

                    TaskStackBuilder stackBuilder = NotificationStackBuilder.get(this, screen, dataJson);
                    stackBuilder.addNextIntent(intent);

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

                    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);

                    mBuilder.setSmallIcon(R.drawable.white_square);
                    mBuilder.setAutoCancel(true);
                    mBuilder.setColor(Color.parseColor("#fac80a"));
                    mBuilder.setLargeIcon(largeImage);
                    mBuilder.setContentTitle(title);
                    mBuilder.setContentText(text);
                    mBuilder.setContentIntent(resultPendingIntent);
                    mBuilder.setDefaults(NotificationCompat.DEFAULT_VIBRATE);
                    mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
                    mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
                    mBuilder.setStyle(notificationStyle);

                    mBuilder.setContentIntent(resultPendingIntent);

                    NotificationManager mNotificationManager =
                            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                    if (notification_id != null) {
                        mNotificationManager.cancel(Integer.parseInt(notification_id));
                        mNotificationManager.notify(Integer.parseInt(notification_id), mBuilder.build());
                    }
                } else {
                    Log.i("GCM", "Dummy Notification");
                }
            } catch (Exception e) {
                Log.i("NOTIF", "An exception occurred");
            }
        }
    }

其他内部代码:

public class NotificationStackBuilder {
    public static TaskStackBuilder get(Context context, String screen, String data) {
        if ("IMAGE".equalsIgnoreCase(screen)) {
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            stackBuilder.addParentStack(ImageActivity.class);
            return stackBuilder;
        } else {
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            stackBuilder.addParentStack(NewHomeActivity.class);
            return stackBuilder;
        }
    }
}

public class NotificationIntentBuilder {
    public static Intent get(Context context, String data, String screen, String smallIcon, String largeIcon, String notificationId) {
        if ("IMAGE".equalsIgnoreCase(screen)) {
            String pk = "";
            JSONObject jsonObject = null;
            try {
                jsonObject = new JSONObject(data);
                if (jsonObject.has("pk")) {
                    pk = jsonObject.getString("pk");
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            Intent intent = new Intent(context, ImageActivity.class);
            intent.putExtra("ID", pk);
            intent.putExtra("notificationId", notificationId);
            return intent;
        } else if ("GALLERY".equalsIgnoreCase(screen)) {
            String pk = "";
            JSONObject jsonObject = null;
            try {
                jsonObject = new JSONObject(data);
                if (jsonObject.has("pk")) {
                    pk = jsonObject.getString("pk");
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            Intent intent = new Intent(context, GalleryActivity.class);
            intent.putExtra("ID", pk);
            intent.putExtra("notificationId", notificationId);
            return intent;
        } else {
            return new Intent(context, NewHomeActivity.class);
        }
    }
}

编辑两个不同类型的通知(打开不同的 Activity )不会出现此问题,只有打开同一屏幕的通知才会出现此问题。

编辑 1 以下是推送通知中收到的值:

Bundle[{google.sent_time=1469254984538, priority=0, screen=IMAGE, data={"pk":650}, style=big_picture, google.message_id=0:1469254984541527%e07f0e28f9fd7ecd, notif_id=4267, display={"large_icon":"https:\/\/d2r0rrogy5uf19.cloudfront.net\/photos\/971c03f8-6a5d-30a3-9e49-0ab416cb8fa0.jpg","small_icon":"","text":"Random hi5'd your photo to 'Diwali'","title":"random","large_text":""}, collapse_key=do_not_collapse}]

此通知的 notificationId 为 4267,现在假设我在同一屏幕上收到另一个通知,notificationId 为 4268,然后当我记录 notificationId 在图像屏幕中收到,打开这两个通知时收到 4268。

编辑 2 我猜这个问题与 PendingIntent.FLAG_UPDATE_CURRENT 有关。以下是文档中的内容:

Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this new Intent.

这就是正在发生的事情。 Intent 附加内容被最新通知的 Intent 附加内容覆盖。因此,我尝试使用FLAG_ONE_SHOT,但是这样我就可以打开旧的 Intent ,但当我单击最新的 Intent 时,注释会打开。

我希望这两个通知都出现在推送通知列表中,并且它们都应该在各自的屏幕上具有不同的 Intent 附加值。

最佳答案

您需要为每个通知提供唯一的请求代码,否则它将被新的通知替换。

摘自 PendingIntent documentation :

The last intent in the array represents the key for the PendingIntent. In other words, it is the significant element for matching (as done with the single intent given to getActivity(Context, int, Intent, int), its content will be the subject of replacement by send(Context, int, Intent) and FLAG_UPDATE_CURRENT, etc. This is because it is the most specific of the supplied intents, and the UI the user actually sees when the intents are started.

因此替换以下行:

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

假设notification_id是唯一的整数,只需将其替换如下:

PendingIntent resultPendingIntent =
          stackBuilder.getPendingIntent(Integer.parseInt(notification_id)
              , PendingIntent.FLAG_UPDATE_CURRENT);

关于android - 推送通知未打开正确的屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38451644/

相关文章:

react-native - 清除以前的世博会推送通知

Android - 用于开发的 GCM,我需要物理设备吗?

android - gcm 可以用于在 android 设备之间发送和接收消息吗?

android - 在 Android Studio 中加载插件时发现问题

android - 如何使 Phonegap 应用程序中的图像加载更顺畅

java - Firebase Firestore,如何抢夺Collection中最新(新)对象的变化?

android - 如何更改 PushNotification 的消息内容?

android - 创建和定位 float 操作按钮

java - 单击通知后 Alarmmanager 未取消

ios - 我怎样才能继续播放 UILocalNotification 声音直到用户关闭它?