CM получает канонический идентификатор

#java #android #push-notification #google-cloud-messaging

#java #Android #push-уведомление #google-облако-обмен сообщениями

Вопрос:

Я новичок в GCM и я не знаю, как получить канонический идентификатор из ответа. Это то, что я прочитал:

GCM предоставляет средство под названием «канонические регистрационные идентификаторы», позволяющее легко восстанавливаться в таких ситуациях. Канонический регистрационный идентификатор определяется как идентификатор последней регистрации, запрошенной вашим приложением. Это идентификатор, который сервер должен использовать при отправке сообщений на устройство.

Если позже вы попытаетесь отправить сообщение, используя другой регистрационный идентификатор, GCM обработает запрос как обычно, но он будет включать канонический регистрационный идентификатор в поле registration_id ответа. Обязательно замените регистрационный идентификатор, хранящийся на вашем сервере, на этот канонический идентификатор, поскольку в конечном итоге используемый вами идентификатор перестанет работать.

Это моя функция для отправки сообщения GCM на устройство с моего сервера:

     private string SendMessageUsingGCM(String sGCMRegistration, string sMessage, string sCollapseKey)
    {
        String GCM_URL = @"https://android.googleapis.com/gcm/send";

        bool flag = false;
        string sError = "";
        StringBuilder sb = new StringBuilder();

        sb.AppendFormat("registration_id={0}amp;collapse_key={1}", sGCMRegistration, sCollapseKey);
        sb.AppendFormat("amp;time_to_live=30amp;delay_while_idle=0"); //Para que se reciba cuanto antes
        sb.AppendFormat("amp;data.msg="   sMessage);

        string msg = sb.ToString();
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(GCM_URL);
        req.Method = "POST";
        req.ContentLength = msg.Length;
        req.ContentType = "application/x-www-form-urlencoded";

        req.Headers.Add("Authorization:key="   sGcmApiKey); //Here goes my Api Key 

        using (StreamWriter oWriter = new StreamWriter(req.GetRequestStream()))
        {
            oWriter.Write(msg);
        }

        using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
        {
            using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
            {
                string respData = sr.ReadToEnd();

                if (resp.StatusCode == HttpStatusCode.OK)   // OK = 200
                {
                    if (respData.StartsWith("id="))
                        flag = true;
                    else
                        sError = respData;
                }
                else if (resp.StatusCode == HttpStatusCode.InternalServerError)   // 500
                    sError = "Internal server error. Try later.";
                else if (resp.StatusCode == HttpStatusCode.ServiceUnavailable)    // 503
                    sError = "Server not available temnporatily. Try later.";
                else if (resp.StatusCode == HttpStatusCode.Unauthorized)          // 401
                    sError = "The API Key is not valid.";
                else
                    sError = "Error: "   resp.StatusCode;
            }
        }

        if (flag == true)
            return "1";

        return "0 "   sError;
    }
  

Итак, как я могу получить канонический идентификатор регистрации в поле registration_id ответа?

Спасибо

Ответ №1:

Вот пример того, как ответ анализируетсяSender.java в sendNoRetry методе :

    try {
      BufferedReader reader =
          new BufferedReader(new InputStreamReader(conn.getInputStream()));
      try {
        String line = reader.readLine();

        if (line == null || line.equals("")) {
          throw new IOException("Received empty response from GCM service.");
        }
        String[] responseParts = split(line);
        String token = responseParts[0];
        String value = responseParts[1];
        if (token.equals(TOKEN_MESSAGE_ID)) {
          Builder builder = new Result.Builder().messageId(value);
          // check for canonical registration id
          line = reader.readLine();
          if (line != null) {
            responseParts = split(line);
            token = responseParts[0];
            value = responseParts[1];
            if (token.equals(TOKEN_CANONICAL_REG_ID)) {
              builder.canonicalRegistrationId(value);
            } else {
              logger.warning("Received invalid second line from GCM: "   line);
            }
          }

          Result result = builder.build();
          if (logger.isLoggable(Level.FINE)) {
            logger.fine("Message created succesfully ("   result   ")");
          }
          return resu<
        } else if (token.equals(TOKEN_ERROR)) {
          return new Result.Builder().errorCode(value).build();
        } else {
          throw new IOException("Received invalid response from GCM: "   line);
        }
      } finally {
        reader.close();
      }
    } finally {
      conn.disconnect();
    }
  

Как вы можете видеть, идентификатор канонической регистрации ищется во второй строке ответа, но только в том случае, если первая строка ответа содержит идентификатор сообщения.

Комментарии:

1. Извините. Я не понимаю. В какую часть моего кода я должен вставить ваш код?

2. @Ton Вы не можете скопировать его как есть, поскольку вы используете разные классы для обработки ответа от Google. Это всего лишь пример. Вы получаете свой ответ в виде respData строки. Вы должны проверить, содержит ли он две строки, и если это так, проверьте, начинается ли вторая строка с registration_id .

Ответ №2:

Канонический идентификатор получается в результате, возвращаемом после отправки уведомления.

Предполагая, что сообщение уже создано и у вас есть регистрационный идентификатор устройства, ниже приведен метод отправки сообщения GCM на одно устройство с моего сервера и получения канонического идентификатора из ответа:-

 private void sendNotificationToSingleDevice(Message message, String registrationId) {

    try {
        //Send a message to a single device 
        Result result = sender.send(message, regtoken, 1);
        String canonicalId = result.getCanonicalRegistrationId();
        // do code to replace existing registration id with the canonical id
    } catch (Exception e) {
        e.printStackTrace();
    }
}
  

Ниже приведен метод трансляции сообщения с моего сервера и получения канонического идентификатора из ответа:-

 private void sendNotificationToMultipleDevices(Message message, List<String> registrationIds) {

    try {
        //Send a message to a multiple devices
        MulticastResult result = sender.send(message, registrationIds, 1);
        if (result.getResults() != null) {
            // this for loop loops through the response returned after pushing the message to each device.
            for(int i = 0; i < result.getResults().size(); i  ) {
               String canonicalId = result.getResults().get(i).getCanonicalRegistrationId(); 
               // do code to replace existing registration id with the canonical id
            }
        } 
    } catch (Exception e) {
        e.printStackTrace();
    }
}