2012-05-18 14 views
5

Sto sviluppando la parte server di un sistema che deve inviare messaggi a un dispositivo. Funzionava perfettamente con il metodo GoogleLogin, ma voglio migrarlo a OAuth 2.0 poiché l'altro metodo di autenticazione è stato deprecato.Come posso inviare un messaggio a un dispositivo utilizzando C2DM da un server che è stato autenticato con OAuth2?

Nella console dell'API di Google ho creato un progetto e quindi ho creato una chiave per un account di servizio.

Questo è il codice che sto usando per autenticare il server:

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

Quando eseguo questo, il metodo viene chiamato onTokenResponse e ottengo una access_token con token_type "portatore" con scadenza 3600 secondi. Fin qui tutto bene.

Questo è il codice che sto utilizzando per inviare il messaggio al dispositivo, che mi dà sempre uno stato 401 (non autorizzato). Qualche idea?

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

Grazie!

risposta

2

Poiché C2DM è in uno stato beta al momento, l'unico modo per farlo funzionare con OAuth2.0 è creare un ID del client dell'applicazione Web, anziché un account di servizio (nella console delle API di Google).

Ho seguito i passaggi in http://michsan.web.id/content/how-code-android-c2dm-oauth-2 e ha funzionato perfettamente

Problemi correlati