2012-07-21 12 views
31

Después de la última sección en la guía GCM: Getting Started, hay que hacer algunas reservas después de recibir los resultados.GCM: MulticastResult: ¿qué resultado es desde qué dispositivo?

Citando de la guía:

Ahora es necesario analizar el resultado y tomar la acción apropiada en los siguientes casos:

  • Si se creó el mensaje pero el resultado devuelto un registro canónica ID, es necesario reemplazar el registro actual
    ID con el canónico.
  • Si el error devuelto es No registrado, es necesario eliminar ese ID de registro, porque la aplicación se desinstaló del dispositivo .

Así es un fragmento de código que se encarga de estas 2 condiciones:

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 guía anterior se refiere a un solo resultado , y no con el caso de multidifusión. No estoy seguro de cómo manejar el caso de multidifusión:

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

envío una lista de dispositivos, y recibir de vuelta una lista de resultados. El objeto Resultado no contiene el ID de registro, pero solo un ID canónico si el primero está obsoleto. No está documentado si las dos listas están relacionadas (es decir, conserva el orden y el tamaño).

¿Cómo puedo estar seguro de qué resultado se refiere a qué dispositivo?

- ACTUALIZACIÓN

me ha pegado un fragmento de la solución en una respuesta por separado a continuación

Respuesta

21

Los resultados están en el orden de la matriz registration_id que ha enviado al servidor de GCM. p.ej. si sus registration_ids son:

[id1, id4, id7, id8] 

entonces los resultados matriz que reciba va a mismo orden para ID1, ID4, ID7, y ID8.

Solo necesita analizar cada resultado en consecuencia, p. si el segundo resultado tiene 'message_id' y 'registration_id' de 'id9', sabrá que 'id4' ahora está obsoleto y debe reemplazarse por id9.

+0

¡Gracias! Acabo de encontrar esta información en el grupo de GCM google (https://groups.google.com/forum/#!topic/android-gcm/DCHHQwqTs8M). Lleva tiempo que las nuevas API obtengan los documentos adecuados. – auval

+0

¡gracias! me estaba haciendo la misma pregunta! –

5

Para la comodidad lectores, aquí es un fragmento de código que se encarga de respuesta para múltiples dispositivos

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

¿qué hay en los valores? – Noman

+0

La clase de resultado tiene 3 campos: messageId, canonicalRegistrationId y errorCode. Todos los casos relevantes están cubiertos en el fragmento de código. canonicalRegistrationId es una clave gcm actualizada. – auval

+0

'devices.get (i) tiene más de un ID de registro: actualizar la base de datos': ¿qué debe hacer uno aquí? ¿Eliminar devices.get (i) de la base de datos o eliminar el dispositivo con el canonicalRegistrationId del resultado? ¿O verificar si existe un dispositivo con canonicalRegistrationId en la base de datos? Si es así, entonces borre el otro, si es falso, cambie el ID del otro? – Konsumierer

3

Esta solución se hace por Google muestra desarrollador GCM Demo application nota del asyncSend para la multidifusión manejar

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

hay una nota en la aplicación de ejemplo a la que se vincula: "La información en este documento ha sido reemplazada por GCM Server y GCM Client. Use la API GoogleCloudMessaging en lugar de la biblioteca auxiliar de GCM. La biblioteca auxiliar del servidor GCM sigue siendo válida. ". ¿Tu respuesta está actualizada? – auval

+0

sus 2 semanas de actualizaciones se ve google ha actualizado la biblioteca y la demo aún no se ha actualizado :) – shareef

Cuestiones relacionadas