2014-04-25 19 views
15

Mi registro in GCM con GoogleCloudMessaging.getInstance (contesto); e salva il token ricevuto sul dispositivo. Quindi inviarlo al server ed è associato all'account utente. Se disinstalla la mia app senza disconnetterla e installarla di nuovo e accedere con un altro utente, ricevo un nuovo token e lo invii al server. E quando i push vengono inviati al primo utente, li vedo quando ho effettuato l'accesso con il secondo utente.GCM Android e token multipli

Perché GCM mi invia token diversi e come posso gestirlo?

+0

possibile duplicato di [fare vecchi gettoni GCM vivono anche dopo una disinstallazione?] (http://stackoverflow.com/questions/17328654/do-old-gcm- token-live-on-anche-dopo-an-disinstallazione) –

risposta

11

Benvenuti nel meraviglioso mondo dei messaggi duplicati da Google Cloud Messaging. Quando ciò accade, il motore GCM consente a Canonical IDs di risolverlo. Ciò potrebbe accadere perché ti sei registrato con diversi ID per lo stesso dispositivo o perché il server GCM non ha ricevuto la chiamata unregister() quando l'app è stata disinstallata. L'uso di ID canonici imposterà il tuo ID come ultima registrazione effettuata.

Come per la GCM reference su questo:

ID canoniche

Sul lato server, a patto che l'applicazione si comporta bene, tutto dovrebbe funzionare normalmente. Tuttavia, se un bug nell'applicazione attiva più registrazioni per lo stesso dispositivo, può essere difficile riconciliare lo stato e si potrebbe finire con messaggi duplicati.

GCM fornisce una funzione denominata "ID di registrazione canonica" per recuperare facilmente da queste situazioni. Un ID di registrazione canonico è definito come l'ID dell'ultima registrazione richiesta dall'applicazione. Questo è l'ID che il server deve utilizzare quando invia messaggi al dispositivo.

Se in seguito si tenta di inviare un messaggio utilizzando un ID di registrazione diverso, GCM elaborerà la richiesta normalmente, ma includerà l'ID di registrazione canonica nel campo registration_id della risposta. Assicurati di sostituire l'ID di registrazione memorizzato nel tuo server con questo ID canonico, in quanto l'ID che stai utilizzando smetterà di funzionare.

Ulteriori informazioni here.

Inoltre v'è un caso pratico su come procceed, potrebbe essere utile:

5

ho vissuto cambiamenti ID di registrazione quando si disinstalla l'applicazione, cercando di inviare messaggi all'app mentre è disinstallato (fino a quando ottengo un errore NotRegistered) e poi di nuovo l'installazione.

Costin Manolache da Google suggests per gestire ID di registrazione cambia in questo modo:

Il suggerimento/soluzione è di generare il proprio identificativo casuale, salvata come preferenza condivisa per esempio. Su ciascun aggiornamento dell'app è possibile caricare l'identificatore e l'ID di registrazione potenzialmente nuovo. Questo può anche aiutare a tracciare e debuggare le modifiche di aggiornamento e registrazione sul lato server.

Ovviamente, questo funziona solo quando l'app rimane installata (poiché le preferenze condivise vengono cancellate con l'app).Tuttavia, se il dispositivo dispone di una memoria esterna, è possibile memorizzare l'identificatore lì e, quando l'app viene nuovamente installata, caricare l'identificatore memorizzato dalla memoria esterna. In questo modo saprai che il nuovo ID di registrazione e il vecchio ID di registrazione appartengono allo stesso dispositivo.

Inoltre, è necessario gestire le risposte di ID di registrazione canoniche di Google nel proprio server, come indicato nell'altra risposta.

1

È possibile inviare un ID dispositivo Android insieme all'ID di registrazione. L'ID del dispositivo Android è unico e rimane invariato durante la reinstallazione dell'app, e cambia solo se il dispositivo viene ripristinato in fabbrica.

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

0

Invio Push Notification su più dispositivi è la stessa come trasmettiamo dispositivo individuo. Basta memorizzare il token di registrazione di tutti i dispositivi registrati sul server. E quando si chiama la notifica push con arricciatura (presumo che tu stia usando php come lato server) Metti tutto l'ID di registrazione in un array. Si tratta di un codice di esempio

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

Nel codice di cui sopra cercando di caricare il token di registrazione dalla tabella mysql. Per inviare a tutti i dispositivi abbiamo bisogno di tutti i token. E per inviare un singolo dispositivo abbiamo bisogno di token solo per quel dispositivo.

Fonte: Google Cloud Messaging Example

0

prima quando si invia la notifica all'utente Invia ID con esso e chiedere se id in sharedpreference == comming o nessuna

se si inviano notifiche a tutti gli utenti e può essere un po 'uno prendi 2 notifiche mentre lui deve ottenere solo uno fare che

creare il file sul server e con un numero qualsiasi dire 0 poi quando si desidera inviare la notifica inviare questo numebr con esso quindi aggiungere uno a questo numero ++ essere nuovo numero i n la prossima notifica stessa ad ogni nuova

In applicazione Android Aggiungi variabile e lascia questa variabile = variabile ritornassi dal server dopo aggiungere la notifica ma è necessario chiedere if(number_in_your_service!=server_number) // aggiunge notifica

qualsiasi numero di notifiche si inviano solo apparirà uno

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