2012-07-21 46 views
31

GCM: Getting Started指南中的最后一节后,在收到结果后需要做一些记录。GCM:MulticastResult - 哪个结果来自哪个设备?

从导引用:

它现在有必要来分析结果,并采取在下列情况下采取适当行动:

  • 如果在创建消息,但结果返回的规范登记ID,有必要用当前的注册号码替换当前的注册号码
    ID。
  • 如果返回的错误是NotRegistered,则需要删除该注册ID,因为该应用程序已从设备上卸载 。

这里的一个代码段用于处理这些2个条件:

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

引导上述指单个结果,而不是多播的情况。 我不知道如何处理多播情况:

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

我提交设备的列表,并接收返回结果的列表。 Result对象不包含注册标识,但只包含一个规范标识,如果第一个过时。 如果两个列表是共同关联的(即保留订单和大小),则它是无证的。

如何确定哪个结果指哪个设备?

- UPDATE

我粘贴的解决方案的一个片段如下

回答

21

一个单独的答案,结果是你,你发送到GCM服务器registration_id排列的顺序。例如如果您registration_ids是:

[id1, id4, id7, id8] 

那么结果数组你将有ID1,ID4,ID7和ID8顺序相同。

你只需要相应地解析每个结果,例如,如果第二个结果具有'message_id'和'id9'的'registration_id',那么您知道'id4'现在已经过时,应该由id9替换。

+0

谢谢!我刚刚在GCM google群组中找到了此信息(https://groups.google.com/forum/#!话题/ Android的GCM/DCHHQwqTs8M)。新的API需要时间才能获得正确的文档。 – auval 2012-07-21 20:50:59

+0

谢谢!问自己同样的问题! – 2012-08-23 14:13:05

5

为读者方便起见,这里是处理响应为多个设备

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

值是什么? – Noman 2012-11-12 12:10:56

+0

Result类有3个字段:messageId,canonicalRegistrationId和errorCode。代码片段涵盖了所有相关案例。 canonicalRegistrationId是更新的gcm键。 – auval 2012-11-12 13:14:38

+0

'devices.get(i)有多个注册ID:更新数据库' - 这里应该做什么?从数据库中删除devices.get(i)或从结果中删除具有canonicalRegistrationId的设备?或者检查数据库中是否存在具有canonicalRegistrationId的设备?如果是,那么删除另一个,如果为false,则更改另一个的ID? – Konsumierer 2012-12-10 11:24:12

3

该解决方案是由谷歌开发者样品进行 GCM Demo application 注意asyncSend对组播处理片段

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

示例应用中有一条提示链接到:“本文档中的信息已被GCM服务器和GCM客户端取代,请使用GoogleCloudMessaging API代替GCM客户端助手库,GCM服务器帮助程序库仍然有效。 ”。你的答案是最新的吗? – auval 2013-06-06 19:56:02

+0

其2周更新外观谷歌已更新库和演示未更新:) – shareef 2013-06-07 12:17:43