2012-07-21 14 views
31

Dopo l'ultima sezione della guida GCM: Getting Started, è necessario eseguire una conservazione dei libri dopo aver ricevuto i risultati.GCM: MulticastResult - quale risultato proviene da quale dispositivo?

Citando dalla guida:

E 'ora necessario analizzare il risultato e prendere l'azione corretta nei seguenti casi:

  • Se il messaggio è stato creato, ma il risultato restituito una registrazione canonica ID, è necessario sostituire la registrazione attuale
    ID con quella canonica.
  • Se l'errore restituito è NotRegistered, è necessario rimuovere tale ID di registrazione, poiché l'applicazione è stata disinstallata dal dispositivo .

Ecco un frammento di codice che gestisce questi 2 condizioni:

if (result.getMessageId() != null) { 
String canonicalRegId = result.getCanonicalRegistrationId(); 
if (canonicalRegId != null) { 
    // same device has more than on registration ID: update database 
} 
} else { 
String error = result.getErrorCodeName(); 
if (error.equals(Constants.ERROR_NOT_REGISTERED)) { 
    // application has been removed from device - unregister database 
} 
} 

La guida sopra si riferisce ad un singolo risultato , e non al caso multicast. Non sono sicuro di come gestire il caso multicast:

ArrayList<String> devices = new ArrayList<String>(); 

    for (String d : relevantDevices) { 
     devices.add(d); 
    } 

    Sender sender = new Sender(myApiKey); 
    Message message = new Message.Builder().addData("hello", "world").build(); 
    try { 
     MulticastResult result = sender.send(message, devices, 5); 

     for (Result r : result.getResults()) { 
      if (r.getMessageId() != null) { 
       String canonicalRegId = r.getCanonicalRegistrationId(); 
       if (canonicalRegId != null) { 
        // same device has more than on registration ID: update database 
        // BUT WHICH DEVICE IS IT? 
       } 
      } else { 
       String error = r.getErrorCodeName(); 
       if (error.equals(Constants.ERROR_NOT_REGISTERED)) { 
        // application has been removed from device - unregister database 
        // BUT WHICH DEVICE IS IT? 
       } 
      } 
     } 
    } catch (IOException ex) { 
     Log.err(TAG, "sending message failed", ex); 
    } 

invio un elenco dei dispositivi, e ricevere indietro un elenco di risultati. L'oggetto Risultato non contiene l'ID di registrazione, ma solo un id canonico se il primo è obsoleto. Non è documentato se i due elenchi sono correlati (cioè conserva l'ordine e le dimensioni).

Come posso sapere quale risultato si riferiscono a quale dispositivo?

- AGGIORNAMENTO

ho incollato un frammento della soluzione in una risposta separata sotto

risposta

21

I risultati sono nell'ordine dell'array registration_id che hai inviato al server GCM. per esempio. se i vostri registration_ids sono:

[id1, id4, id7, id8] 

poi i risultati di matrice si ottiene avranno stesso ordine per id1, ID4, ID7 e ID8.

Hai solo bisogno di analizzare ogni risultato di conseguenza, ad es. se il secondo risultato ha 'message_id' e 'registration_id' di 'id9', sai che 'id4' è ora obsoleto e dovrebbe essere sostituito da id9.

+0

Grazie! Ho appena trovato queste informazioni nel gruppo Google GCM (https://groups.google.com/forum/#!argomento/android-GCM/DCHHQwqTs8M). Ci vuole tempo per le nuove API per ottenere documenti adeguati .. – auval

+0

grazie! mi stava ponendo la stessa domanda! –

5

Per la comodità dei lettori, ecco un frammento che gestisce la risposta per più dispositivi

public void sendMessageToMultipleDevices(String key, String value, ArrayList<String> devices) { 

     Sender sender = new Sender(myApiKey); 
     Message message = new Message.Builder().addData(key, value).build(); 
     try { 
      MulticastResult result = sender.send(message, devices, 5); 
      MTLog.info(TAG, "result " + result.toString()); 


      for (int i = 0; i < result.getTotal(); i++) { 
       Result r = result.getResults().get(i); 

       if (r.getMessageId() != null) { 
        String canonicalRegId = r.getCanonicalRegistrationId(); 
        if (canonicalRegId != null) { 
         // devices.get(i) has more than on registration ID: update database 

        } 
       } else { 
        String error = r.getErrorCodeName(); 
        if (error.equals(Constants.ERROR_NOT_REGISTERED)) { 
         // application has been removed from devices.get(i) - unregister database 
        } 
       } 
      } 
     } catch (IOException ex) { 
      MTLog.err(TAG, "sending message failed", ex); 
     } 
    } 
+0

cosa c'è nei valori? – Noman

+0

La classe Result ha 3 campi: messageId, canonicalRegistrationId e errorCode. Tutti i casi rilevanti sono trattati nello snippet di codice. canonicalRegistrationId è una chiave gcm aggiornata. – auval

+0

'devices.get (i) ha più di un ID di registrazione: aggiornamento del database' - cosa si dovrebbe fare qui? Eliminare devices.get (i) dal database o eliminare il dispositivo con canonicalRegistrationId dal risultato? O controllare se nel database esiste un dispositivo con canonicalRegistrationId? Se sì, allora cancella l'altro, se falso, cambia l'id dell'altro? – Konsumierer

3

Questa soluzione è fatto da campione sviluppatore Google GCM Demo application nota la asyncSend per il multicasting gestire

List<GcmUsers> devices=SearchRegisterdDevicesByCourseCommand.execute(instructorId, courseId); 
    String status; 
    if (devices.equals(Collections.<GcmUsers>emptyList())) {  
     status = "Message ignored as there is no device registered!"; 
    } else { 
     // NOTE: check below is for demonstration purposes; a real application 
     // could always send a multicast, even for just one recipient 
     if (devices.size() == 1) { 
     // send a single message using plain post 
     GcmUsers gcmUsers = devices.get(0); 
     Message message = new Message.Builder().build(); 
     Result result = sender.send(message, gcmUsers.getGcmRegid(), 5); 
     status = "Sent message to one device: " + result; 
     } else { 
     // send a multicast message using JSON 
     // must split in chunks of 1000 devices (GCM limit) 
     int total = devices.size(); 
     List<String> partialDevices = new ArrayList<String>(total); 
     int counter = 0; 
     int tasks = 0; 
     for (GcmUsers device : devices) { 
      counter++; 
      partialDevices.add(device.getGcmRegid()); 
      int partialSize = partialDevices.size(); 
      if (partialSize == MULTICAST_SIZE || counter == total) { 
      asyncSend(partialDevices); 
      partialDevices.clear(); 
      tasks++; 
      } 
     } 
     status = "Asynchronously sending " + tasks + " multicast messages to " + 
      total + " devices"; 
     } 
    } 
    req.setAttribute(HomeServlet.ATTRIBUTE_STATUS, status.toString()); 






private void asyncSend(List<String> partialDevices) { 
    // make a copy 
    final List<String> devices = new ArrayList<String>(partialDevices); 
    threadPool.execute(new Runnable() { 

     public void run() { 
     Message message = new Message.Builder().build(); 
     MulticastResult multicastResult; 
     try { 
      multicastResult = sender.send(message, devices, 5); 
     } catch (IOException e) { 
      logger.log(Level.SEVERE, "Error posting messages", e); 
      return; 
     } 
     List<Result> results = multicastResult.getResults(); 
     // analyze the results 
     for (int i = 0; i < devices.size(); i++) { 
      String regId = devices.get(i); 
      Result result = results.get(i); 
      String messageId = result.getMessageId(); 
      if (messageId != null) { 
      logger.fine("Succesfully sent message to device: " + regId + 
       "; messageId = " + messageId); 
      String canonicalRegId = result.getCanonicalRegistrationId(); 
      if (canonicalRegId != null) { 
       // same device has more than on registration id: update it 
       logger.info("canonicalRegId " + canonicalRegId); 
       Datastore.updateRegistration(regId, canonicalRegId); 
      } 
      } else { 
      String error = result.getErrorCodeName(); 
      if (error.equals(Constants.ERROR_NOT_REGISTERED)) { 
       // application has been removed from device - unregister it 
       logger.info("Unregistered device: " + regId); 
       Datastore.unregister(regId); 
      } else { 
       logger.severe("Error sending message to " + regId + ": " + error); 
      } 
      } 
     } 
     }}); 
    } 
+0

c'è una nota in app campione si collega a:. "Le informazioni contenute in questo documento è stata sostituita dalla GCM Server e GCM client Si prega di utilizzare l'API GoogleCloudMessaging invece della libreria client di supporto GCM La libreria del server di supporto GCM è ancora valido.. ". La tua risposta è aggiornata? – auval

+0

le sue 2 settimane aggiornate sembra che Google abbia aggiornato la libreria e la demo non sia ancora stata aggiornata :) – shareef

Problemi correlati