2012-03-02 24 views
6

He estado luchando con esto por un par de días. Intento hacer llamadas a Google Calendar usando la autenticación a través del AccountManager de Android. Puedo recuperar un token de autenticación utilizando el método habitual:Autenticando con Google API usando AccountManager

AccountManager manager = AccountManager.get(this); 
String authToken = manager.getAuthToken(account, AUTH_TOKEN_TYPE, true, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN); 

Y entonces, con esa manera, se crea una instancia de Calendar así:

HttpTransport transport = AndroidHttp.newCompatibleTransport(); 
JacksonFactory jsonFactory = new JacksonFactory(); 
GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessToken); 
Calendar calendar = Calendar.builder(transport, jsonFactory).setApplicationName("MyApp/1.0").setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() { 
    @Override 
    public void initialize(JsonHttpRequest request) { 
     CalendarRequest calendarRequest = (CalendarRequest) request; 
     calendarRequest.setKey(API_KEY); 
    } 
}).setHttpRequestInitializer(accessProtectedResource).build(); 

Sin embargo, cuando la API con esto, reciba el error 401 Unauthorized que se ve a continuación. Tenga en cuenta que he incluido el código para invalidar tokens de autenticación vencidos, por lo que no creo que ese sea el problema aquí.

com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized 
{ 
    "code" : 401, 
    "errors" : [ { 
     "domain" : "global", 
     "location" : "Authorization", 
     "locationType" : "header", 
     "message" : "Invalid Credentials", 
     "reason" : "authError" 
    } ], 
    "message" : "Invalid Credentials" 
} 

¿Alguna idea de lo que podría estar haciendo mal?

Respuesta

11

Sí, esto es posible. Una vez que tenga un control sobre la cuenta de Google (tal como lo describió), solo necesita solicitar un token de autenticación del AccountManager para el servicio GData.

Si el dispositivo Android ya tiene un token de autenticación (para el servicio GData particular al que está intentando acceder), se le devolverá. De lo contrario, AccountManager solicitará uno y se lo devolverá. De cualquier forma, no necesita preocuparse por esto ya que AccountManager lo maneja.

En el siguiente ejemplo, estoy usando la API de Google Spreadsheets:

ArrayList<Account> googleAccounts = new ArrayList<Account>(); 

// Get all accounts 
Account[] accounts = accountManager.getAccounts(); 
    for(Account account : accounts) { 
    // Filter out the Google accounts 
    if(account.type.compareToIgnoreCase("com.google")) { 
     googleAccounts.add(account); 
    } 
    } 
AccountManager accountManager = AccountManager.get(activity); 

// Just for the example, I am using the first google account returned. 
Account account = googleAccounts.get(0); 

// "wise" = Google Spreadheets 
AccountManagerFuture<Bundle> amf = accountManager.getAuthToken(account, "wise", null, activity, null, null); 

try { 
    Bundle authTokenBundle = amf.getResult(); 
    String authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN); 

    // do something with the token 
    InputStream response = sgc.getFeedAsStream(feedUrl, authToken, null, "2.1"); 

} 

Y

Por favor, echar un vistazo a la sample code en la API de datos de Google. Lo importante después de la autenticación es llamar a GoogleHeaders.setGoogleLogin (String).

Espero que esto ayude.

+0

Bien, actualmente no estoy llamando a 'setGoogleLogin()', pero estoy viendo el código de ejemplo que llama '((GoogleHeaders) transport.defaultHeaders) .setGoogleLogin (authToken)', pero eso ni siquiera compilar para mi Estoy usando google-http-client-1.6.0-beta. 'HttpTransport' ya no parece tener el campo' defaultHeaders'. –

0

Me metí en un problema similar yo mismo. He descubierto que tengo que configurar el xoauth_requestor_id en la lista de claves desconocidas (Referencia http://www.yenlo.nl/2011/google-calendar-api-v3-and-2lo/)

Esto funcionó para mí:

com.google.api.services.calendar.Calendar.CalendarList.List list = calendar.calendarList().list(); 
//Set the requestor id 
list.getUnknownKeys().put("xoauth_requestor_id", "[email protected]"); 

Después de esto las llamadas a la API fuimos a través.

Ojalá hubiera una explicación de por qué es necesario el ID del solicitante. ¿Alguien puede explicar?

+0

Intenté eso, pero sigo recibiendo el error '401 no autorizado' por desgracia. –

Cuestiones relacionadas