2012-05-18 10 views
5

Estoy desarrollando la parte del servidor de un sistema que tiene que enviar mensajes a un dispositivo. Esto funcionaba bien con el método GoogleLogin, pero quiero migrarlo a OAuth 2.0 ya que el otro método de autenticación ha quedado en desuso.¿Cómo puedo enviar un mensaje a un dispositivo usando C2DM desde un servidor que ha sido autenticado con OAuth2?

En la consola de la API de Google, creé un proyecto y luego creé una clave para una cuenta de servicio.

Este es el código que estoy utilizando para autenticar el servidor:

public boolean authenticateServer(){ 
    try { 
     File privateKey = 
      new File(getClass().getResource("/something-privatekey.p12").toURI()); 

     GoogleCredential cred = 
      new GoogleCredential.Builder().setTransport(new NetHttpTransport()) 
       .setJsonFactory(new JacksonFactory()) 
       .setServiceAccountId("[email protected]") 
       .setServiceAccountScopes("https://android.apis.google.com/c2dm") 
       .setServiceAccountPrivateKeyFromP12File(privateKey) 
       .addRefreshListener(this) 
       .build(); 

     boolean success = cred.refreshToken(); 
     this.credential = cred; 
     return success;   
    } 
    catch (Exception ex) { 
     //handle this 
    } 
    return false; 
} 

Cuando ejecuto esto, el método onTokenResponse es llamada y me sale un access_token con token_type "portador" que expira en 3600 segundos. Hasta aquí todo bien.

Este es el código que estoy usando para enviar el mensaje al dispositivo, que siempre me da un estado 401 (no autorizado). ¿Algunas ideas?

private static String UTF8 = "UTF-8"; 
public void sendMessage(String text, String registrationId) { 
    try { 
     StringBuilder postDataBuilder = new StringBuilder(); 
     postDataBuilder 
      .append("registration_id") 
      .append("=") 
      .append(registrationId); 

     postDataBuilder.append("&") 
      .append("collapse_key") 
      .append("=") 
      .append("0"); 

     postDataBuilder.append("&") 
      .append("data.payload") 
      .append("=") 
      .append(URLEncoder.encode(text, UTF8)); 

     byte[] postData = postDataBuilder.toString().getBytes(UTF8); 

     URL url = new URL("https://android.apis.google.com/c2dm/send"); 

     HostnameVerifier hVerifier = new HostnameVerifier() { 
      public boolean verify(String hostname, SSLSession session) { 
       return true; 
      } 
     }; 

     HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 
     conn.setHostnameVerifier(hVerifier); 
     conn.setDoOutput(true); 
     conn.setUseCaches(false); 
     conn.setRequestMethod("POST"); 
     conn.setRequestProperty(
      "Content-Type", "application/x-www-form-urlencoded"); 
     conn.setRequestProperty(
      "Content-Length", Integer.toString(postData.length)); 
     conn.setRequestProperty(
      "Authorization", "Bearer " + credential.getAccessToken()); 

     OutputStream out = conn.getOutputStream(); 
     out.write(postData); 
     out.close(); 
     int sw = conn.getResponseCode(); 
     System.out.println("" + sw); 
    } 
    catch (IOException ex){ 
     //handle this 
    } 
} 

¡Gracias!

Respuesta

2

Dado que C2DM se encuentra en estado beta a partir de ahora, la única forma de hacerlo funcionar con OAuth2.0 es crear un Id de cliente de aplicación web, en lugar de una cuenta de servicio (en la consola de API de Google).

He seguido los pasos en http://michsan.web.id/content/how-code-android-c2dm-oauth-2 y funcionó perfectamente

Cuestiones relacionadas