2

У меня есть приложение, где я получаю GCM push-уведомления в GcmListenerService (как указано в примере андроида gcm). Всякий раз, когда я получаю уведомление, я получаю JSON с данными, связанными с показом уведомления.Push-уведомления не открывают правильные экраны

Теперь предположим, что я получил уведомление о том, что «кто-то добавил мне закладки», для этого я получаю pk (идентификатор) этого пользователя, и когда я нажимаю на уведомление, он использует pk, принятый в push-уведомлении, для отображения этого пользователя профиль.

Вопрос: Если у меня есть 2 уведомления вышеупомянутого вида, то независимо от того, какое уведомление я нажимаю, я всегда перехожу к профилю человека, уведомление которого я получил совсем недавно.

Получает ли уведомление поверх других, переопределяет значения предыдущих уведомлений, так что действует только последний? Означает ли это, что я могу показать только одно push-уведомление из приложения? Я могу опубликовать код, если это необходимо.

Соответствующий код:

@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); 
     } 
    } 
} 

Редактировать Эта проблема не происходит с двух уведомлений различного типа (открытие различных видов деятельности), это происходит только с уведомления, открывающие один и тот же экран.

Edit 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. 

Это то, что происходило. Содержание дополнительных заданий было переписано с помощью дополнительных намерений уведомления. Итак, я пробовал использовать FLAG_ONE_SHOT, но с этим я могу открыть старое намерение, но заметка открывается, когда я нажимаю последнее намерение.

Я хочу, чтобы оба уведомления были в списке push-уведомлений и что оба они должны иметь соответствующие экраны с разными значениями дополнительных настроек.

+0

Вы можете поделиться код пользовательского JSON приемника, если таковые имеются? Вы можете установить целевое значение в переменной, которая переопределяется последним нажатием. – SlashG

+0

, вы должны различать различные уведомления в зависимости от типа уведомления в своем ответе, например: {msg_typ: «profile»} или {msg_type: «bookmark»}, затем вы можете перейти к определенному экрану. –

+0

@SlashG Я поделюсь кодом. –

ответ

1

Для каждого уведомления требуется уникальный код запроса, иначе он будет заменен новым.

Отрывок из PendingIntent documentation:

Последнее намерение в массиве представляет собой ключ для PendingIntent. Другими словами, это важный элемент для сопоставления (как сделано с единственным намерением, данным getActivity (Context, int, Intent, int), его содержимое будет заменено на send (Context, int, Намерение) и FLAG_UPDATE_CURRENT и т.д. Это происходит потому, что это наиболее специфичным из поставленных намерений, а пользовательский интерфейс пользователя фактически видит, когда запускаются намерения

Так замените строку ниже:.

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

Ассумин г notification_id является уникальным числом, просто заменить его, как показано ниже:

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