2

Ich habe eine App, wo ich GCM Push-Benachrichtigungen in einem GcmListenerService (wie in der gcm Android Probe gegeben). Immer wenn ich die Benachrichtigung erhalte, erhalte ich JSON mit Daten, die sich auf die Anzeige der Benachrichtigung beziehen.Push-Benachrichtigungen öffnen nicht die richtigen Bildschirme

Nun nehme ich an, ich bekomme eine Benachrichtigung, dass "jemand mich vorgemerkt", dafür bekomme ich die pk (Kennung) dieses Benutzers und wenn ich auf die Benachrichtigung klicke, wird pk empfangen in der Push-Benachrichtigung angezeigt Profil.

Das Problem: Wenn ich 2 Benachrichtigungen der oben genannten Art, dann egal welche Benachrichtigung ich klicke, gehe ich immer das Profil der Person, deren Benachrichtigung ich zuletzt erhielt.

Werden beim Übernehmen einer Benachrichtigung alle vorherigen Benachrichtigungen überschrieben, sodass nur die letzte gültig ist? Bedeutet das, dass ich nur eine Push-Benachrichtigung von einer App zeigen kann? Ich kann den Code veröffentlichen, wenn dies erforderlich ist.

Relevante Code:

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

Andere interne Codes:

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

bearbeiten Dieses Problem wird nicht mit zwei Meldungen unterschiedlicher Art passiert (verschiedene Aktivitäten zu öffnen), ist es nur geschieht mit Benachrichtigungen öffnen den gleichen Bildschirm.

Edit 1 Hier ist der Wert in der Push-Benachrichtigung erhalten:

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}] 

Dieser hat notificationId als 4267, jetzt nehme ich eine andere Meldung für denselben Bildschirm zu bekommen, mit notificationId sagen, 4268, dann, wenn Ich logge die notificationId empfangen auf dem Bildschirm Bild, ich bekomme 4268 beim Öffnen beider Benachrichtigungen.

Edit 2 Ich denke, das Problem ist im Zusammenhang mit PendingIntent.FLAG_UPDATE_CURRENT. Hier ist, was in der Dokumentation geschrieben wird:

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

Dies ist, was passiert ist. Der Inhalt der Absichtsextras wurde durch die Absichtsextras der letzten Benachrichtigung überschrieben. Also habe ich versucht, FLAG_ONE_SHOT zu verwenden, aber damit kann ich die alte Absicht öffnen, aber es öffnet sich, wenn ich auf die neueste Absicht klicke.

Ich möchte beide Benachrichtigungen auf der Push-Benachrichtigungsliste sein und dass beide die jeweiligen Bildschirme mit unterschiedlichen Werten der Absicht Extras sein sollten.

+0

Können Sie den Code Ihres benutzerdefinierten JSON-Empfänger teilen, wenn überhaupt? Sie könnten den Zielwert in einer Variablen festlegen, die durch den letzten Push überschrieben wird. – SlashG

+0

Sie müssen in Ihrer Antwort verschiedene Benachrichtigungen auf Basis der Benachrichtigungsart unterscheiden, zB: {msg_typ: "profile"} oder {msg_type: "bookmark"}, dann können Sie zu einem bestimmten Bildschirm navigieren. –

+0

@SlashG Ich werde den Code teilen. –

Antwort

1

Sie müssen für jede Benachrichtigung einen eindeutigen Anforderungscode haben, sonst wird er durch einen neuen ersetzt.

Ein Ausschnitt aus PendingIntent documentation:

Die letzten Absicht in der Anordnung stellt den Schlüssel für das PendingIntent. Mit anderen Worten, es ist das signifikante Element für die Übereinstimmung (wie getan mit der einzigen Absicht gegeben, um GetActivity (Context, Int, Intent, int), sein Inhalt wird der Gegenstand der Ersetzung von senden sein (Context, int, Intent) und FLAG_UPDATE_CURRENT, etc. Dies ist, weil es die speziellsten der gelieferten Absichten ist, und die Benutzeroberfläche der Benutzer tatsächlich sieht, wenn die Absichten gestartet

So die unterhalb der Linie ersetzen.

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

Assum notification_id g ist einzigartig ganze Zahl ist, ersetzen Sie einfach es unten wie:

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