推送通知未打开正确的屏幕
Push notifications not opening correct screens
我有一个应用程序,我可以在 GcmListenerService
中获得 GCM
推送通知(如 gcm android 示例中所示)。每当我收到通知时,我都会得到一些 JSON
与显示通知相关的数据。
现在假设我收到 "someone bookmarked me" 的通知,为此我得到了该用户的 pk
(标识符),当我单击该通知时,它使用 pk
在推送通知中收到以显示该用户的个人资料。
问题 : 如果我收到 2 个上述类型的通知,那么无论我点击哪个通知,我总是转到最近收到通知的人的个人资料.
是否在其他通知之上获得通知,覆盖以前通知的值,以便只有最近的通知有效?这是否意味着我只能显示一个来自应用程序的推送通知?如果需要,我可以 post 代码。
相关代码:
@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);
}
}
}
编辑 两个不同类型的通知(打开不同的活动)不会发生此问题,它只会在通知打开同一屏幕时发生。
编辑 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 extras 的内容被最新通知的 intent extras 覆盖。所以,我尝试使用 FLAG_ONE_SHOT
,但这样我就可以打开旧的意图,但当我单击最新的意图时,注意会打开。
我希望这两个通知都在推送通知列表中,并且它们都应该在各自的屏幕上具有不同的 intent extras 值。
您需要为每个通知设置唯一的请求代码,否则它将被新的替换。
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);
我有一个应用程序,我可以在 GcmListenerService
中获得 GCM
推送通知(如 gcm android 示例中所示)。每当我收到通知时,我都会得到一些 JSON
与显示通知相关的数据。
现在假设我收到 "someone bookmarked me" 的通知,为此我得到了该用户的 pk
(标识符),当我单击该通知时,它使用 pk
在推送通知中收到以显示该用户的个人资料。
问题 : 如果我收到 2 个上述类型的通知,那么无论我点击哪个通知,我总是转到最近收到通知的人的个人资料.
是否在其他通知之上获得通知,覆盖以前通知的值,以便只有最近的通知有效?这是否意味着我只能显示一个来自应用程序的推送通知?如果需要,我可以 post 代码。
相关代码:
@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);
}
}
}
编辑 两个不同类型的通知(打开不同的活动)不会发生此问题,它只会在通知打开同一屏幕时发生。
编辑 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 extras 的内容被最新通知的 intent extras 覆盖。所以,我尝试使用 FLAG_ONE_SHOT
,但这样我就可以打开旧的意图,但当我单击最新的意图时,注意会打开。
我希望这两个通知都在推送通知列表中,并且它们都应该在各自的屏幕上具有不同的 intent extras 值。
您需要为每个通知设置唯一的请求代码,否则它将被新的替换。
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);