2014-04-25 7 views
15

Ich registriere in GCM mit GoogleCloudMessaging.getInstance (Kontext); und speichern Sie empfangene Token auf dem Gerät. Dann senden Sie es an den Server und es ist mit Benutzerkonto verknüpft. Wenn ich meine App deinstalliere, ohne mich abzumelden und erneut zu installieren, und mich mit einem anderen Benutzer anmelde, erhalte ich ein neues Token und sende es an den Server. Und wenn Pushs an den ersten Benutzer gesendet werden, sehe ich sie, wenn ich mich mit dem zweiten Benutzer anmelde.Android GCM und mehrere Token

Warum sendet GCM mir verschiedene Token und wie kann ich damit umgehen?

+0

möglich Duplikat [Do alten GCM Token weiterleben, auch nach einer deinstallation?] erscheinen (http://stackoverflow.com/questions/17328654/do-old-gcm- Tokens-live-on-even-nach-einer-Deinstallation –

Antwort

11

Willkommen in der wunderbaren Welt der doppelten Nachrichten von Google Cloud Messaging. Wenn dies geschieht, ermöglicht die GCM Engine die Canonical IDs, es zu lösen. Dies kann passieren, weil Sie sich bei mehreren IDs für dasselbe Gerät registriert haben oder weil der Server GCM den unregister()-Aufruf nicht erhalten hat, als die App deinstalliert wurde. Wenn Sie kanonische IDs verwenden, wird Ihre ID als letzte von Ihnen vorgenommene Registrierung festgelegt.

Gemäß der GCM reference dazu:

Canonical IDs

Auf der Serverseite, solange die Anwendung gut verhält, sollte alles normal. Wenn ein Fehler in der Anwendung jedoch mehrere Registrierungen für dasselbe Gerät auslöst, kann es schwierig sein, den Status zu vereinbaren, und Sie können möglicherweise doppelte Nachrichten erhalten.

GCM bietet eine Funktion namens "canonical registration IDs", um leicht aus diesen Situationen zu beheben. Eine kanonische Registrierungs-ID ist definiert als die ID der letzten von Ihrer Anwendung angeforderten Registrierung. Dies ist die ID, die der Server beim Senden von Nachrichten an das Gerät verwenden soll.

Wenn Sie später versuchen, eine Nachricht mit einer anderen Registrierungs-ID zu senden, wird GCM die Anfrage wie gewohnt bearbeiten, jedoch die kanonische Registrierungs-ID in das Feld registration_id der Antwort aufnehmen. Stellen Sie sicher, dass Sie die Registrierungs-ID, die auf Ihrem Server gespeichert ist, durch diese kanonische ID ersetzen, da die von Ihnen verwendete ID schließlich nicht mehr funktioniert.

Weitere Informationen here.

Auch gibt es einen praktischen Fall, wie, um fortzufahren, könnte es hilfreich sein:

5

Ich erlebte Änderungen Registrierungs-ID, wenn die Anwendung zu deinstallieren, versucht Nachrichten an die App senden während es deinstalliert ist (bis ich einen NotRegistered Fehler bekomme) und dann erneut installieren.

Costin Manolache von Google suggests zu Registrierungs-ID Änderungen auf diese Weise handhaben:

Der Vorschlag/Abhilfe ist, Ihre eigene zufällige Kennung zu erzeugen, als gemeinsam genutzter Präferenz beispielsweise gespeichert. Bei jedem App-Upgrade können Sie die ID und die möglicherweise neue Registrierungs-ID hochladen. Dies kann auch beim Verfolgen und Debuggen der Upgrade- und Registrierungsänderungen auf der Serverseite hilfreich sein.

Dies funktioniert natürlich nur, wenn die App installiert bleibt (da gemeinsame Einstellungen mit der App gelöscht werden).Verfügt das Gerät jedoch über externen Speicher, können Sie Ihre Kennung dort speichern. Wenn die App erneut installiert wird, laden Sie die gespeicherte Kennung aus dem externen Speicher. Auf diese Weise wissen Sie, dass die neue Registrierungs-ID und die alte Registrierungs-ID zu demselben Gerät gehören.

Darüber hinaus sollten Sie kanonische Registrierungs-ID-Antworten von Google auf Ihrem Server behandeln, wie in der anderen Antwort erwähnt.

1

Sie können die Android-Geräte-ID zusammen mit der Registrierungs-ID senden. Die Android-Geräte-ID ist einmalig und bleibt während der Deinstallation der App gleich und ändert sich nur, wenn das Gerät auf die Werkseinstellungen zurückgesetzt wird.

Beispiel: How to get unique device hardware id in Android?

0

Senden Push-Benachrichtigung an mehrere Geräte ist die gleiche wie wir auf einzelne Gerät zu senden. Speichern Sie einfach das Registrierungs-Token aller registrierten Geräte auf Ihrem Server. Und beim Aufruf der Push-Benachrichtigung mit curl (ich nehme an, Sie verwenden PHP als Server-Seite) Legen Sie alle Registrierungs-ID in einem Array. Dies ist ein Beispielcode

<?php 
//Define your GCM server key here 
define('API_ACCESS_KEY', 'your server api key'); 

//Function to send push notification to all 
function sendToAll($message) 
{ 
    $db = new DbOperation(); 
    $tokens = $db->getAllToken(); 
    $regTokens = array(); 
    while($row = $tokens->fetch_assoc()){ 
     array_push($regTokens,$row['token']); 
    } 
    sendNotification($regTokens,$message); 
} 


//function to send push notification to an individual 
function sendToOne($email,$message){ 
    $db = new DbOperation(); 
    $token = $db->getIndividualToken($email); 
    sendNotification(array($token),$message); 
} 


//This function will actually send the notification 
function sendNotification($registrationIds, $message) 
{ 
    $msg = array 
    (
     'message' => $message, 
     'title' => 'Android Push Notification using Google Cloud Messaging', 
     'subtitle' => 'www.simplifiedcoding.net', 
     'tickerText' => 'Ticker text here...Ticker text here...Ticker text here', 
     'vibrate' => 1, 
     'sound' => 1, 
     'largeIcon' => 'large_icon', 
     'smallIcon' => 'small_icon' 
    ); 

    $fields = array 
    (
     'registration_ids' => $registrationIds, 
     'data' => $msg 
    ); 

    $headers = array 
    (
     'Authorization: key=' . API_ACCESS_KEY, 
     'Content-Type: application/json' 
    ); 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, 'https://android.googleapis.com/gcm/send'); 
    curl_setopt($ch, CURLOPT_POST, true); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields)); 
    $result = curl_exec($ch); 
    curl_close($ch); 

    $res = json_decode($result); 

    $flag = $res->success; 
    if($flag >= 1){ 
     header('Location: index.php?success'); 
    }else{ 
     header('Location: index.php?failure'); 
    } 
} 

In dem obigen Code, den wir die Registrierungstoken aus der MySQL-Tabelle sind holen. Um an alle Geräte zu senden, benötigen wir alle Token. Um ein einzelnes Gerät zu senden, benötigen wir nur Token für dieses Gerät.

Quelle: Google Cloud Messaging Example

0

zuerst, wenn Sie eine Benachrichtigung senden Benutzer-ID mit ihm senden und fragen, ob id in sharedpreference == comming oder kein

wenn Sie Benachrichtigungen an alle Benutzer senden und einige eine 2-Benachrichtigungen erhalten werden kann während er sollte nur einen tun, dass

Erstelle Datei auf Ihrem Server und mit einer beliebigen Anzahl sagen 0 dann, wenn Sie eine Benachrichtigung senden möchten senden Sie diese Nummer mit dann fügen Sie einen zu dieser Nummer ++ zu neuen Nummer i n die nächste Meldung gleiche mit jedem neuen

In Android-Anwendung hinzufügen, variabel und lassen Sie diese Variable = die comming Variable vom Server nach der Benachrichtigung hinzufügen aber Sie müssen fragen if(number_in_your_service!=server_number) // hinzufügen Benachrichtigung

jeder Anzahl der Benachrichtigungen, die Sie senden nur wird ein

public class GcmIntentService extends IntentService { 
    public static int openintent; 
    public static final int NOTIFICATION_ID = 1; 
    private static final String TAG = "GcmIntentService"; 

    private static String number_in_your_service="somethingneversend"; 
    NotificationCompat.Builder builder; 

    public GcmIntentService() { 
    super("GcmIntentService"); 
    } 

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

    if (!extras.isEmpty()) { // has effect of unparcelling Bundle 
     if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) { 
     } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) { 
     // If it's a regular GCM message, do some work. 
     } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { 
     // This loop represents the service doing some work. 
     for (int i = 0; i < 5; i++) { 
      Log.i(TAG, "Working... " + (i + 1) + "/5 @ " + SystemClock.elapsedRealtime()); 
      try { 
      Thread.sleep(100); 
      } catch (InterruptedException e) { 
      } 
     } 
     Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime()); 
     // Post notification of received message. 
     sendNotification(extras); 
     Log.i(TAG, "Received: " + extras.toString()); 
     } 
    } 
    // Release the wake lock provided by the WakefulBroadcastReceiver. 
    GcmBroadcastReceiver.completeWakefulIntent(intent); 
    } 

    private void sendNotification(Bundle extras) { 

    if((extras.getString("server_number")).equals(number_in_your_service)) { 

     Intent intent = new Intent(this, Main_Page_G.class); 
     intent.putExtra("frame",100); 
     intent.putExtra("bundle",extras); 
     final PendingIntent contentIntent = PendingIntent.getActivity(this, 
      120, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
     NotificationManager mNotificationManager; 
     NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
      GcmIntentService.this).setContentTitle("name") 
      .setContentText("content") 
      .setDefaults(Notification.DEFAULT_SOUND) 
      .setContentInfo("Test") 
      .setSmallIcon(R.drawable.rehablogo2) 
      .setAutoCancel(true); 
     mBuilder.setContentIntent(contentIntent); 
     mNotificationManager = (NotificationManager) GcmIntentService.this 
      .getSystemService(Context.NOTIFICATION_SERVICE); 
     mNotificationManager.notify(id, mBuilder.build()); 
     id=Integer.parseInt(extras.getString("id")); 
    } 
    } 
}