Google Calendar API OAuth2 Problemas en Android Honeycomb

Estoy trabajando en una aplicación Android Honeycomb (v3.0) que tiene un requisito de comunicación con Google Calendar API. Me gustaría permitir que mi aplicación accediera a datos de calendario de una cuenta de Google en particular para leer y crear eventos.

Desafortunadamente, encontré un problema con la autorización usando OAuth2. Esto es lo que tengo hasta ahora:

1) La cuenta de Google cuyo calendario quisiera acceder está registrada en el dispositivo con el que estoy trabajando.

2) habilité la API de calendario dentro de la consola de API de Google en la cuenta.

3) Puedo acceder a esta cuenta usando el siguiente código:

AccountManager accountManager = AccountManager.get(this.getBaseContext()); Account[] accounts = accountManager.getAccountsByType("com.google"); Account acc = accounts[0]; // The device only has one account on it 

4) Ahora quisiera obtener un AuthToken para usarlo cuando se comunica con el calendario. Seguí este tutorial , pero lo convertí a todo para trabajar con Google Calendar en lugar de con Google Tasks. Con éxito recupero un authToken del AccountManager con la cuenta que me gustaría utilizar usando getAuthToken con AUTH_TOKEN_TYPE == "oauth2:https://www.googleapis.com/auth/calendar" .

5) Aquí es donde comienzan los problemas. Ahora estoy en este punto:

 AccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(tokens[0]); // this is the correct token HttpTransport transport = AndroidHttp.newCompatibleTransport(); Calendar service = Calendar.builder(transport, new JacksonFactory()) .setApplicationName("My Application's Name") .setHttpRequestInitializer(accessProtectedResource) .build(); service.setKey("myCalendarSimpleAPIAccessKey"); // This is deprecated??? Events events = service.events().list("primary").execute(); // Causes an exception! 

6) Aquí está la excepción devuelta por la última línea:

 com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden { "code" : 403, "errors" : [ { "domain" : "usageLimits", "message" : "Daily Limit Exceeded. Please sign up", "reason" : "dailyLimitExceededUnreg", "extendedHelp" : "https://code.google.com/apis/console" } ], "message" : "Daily Limit Exceeded. Please sign up" } 

7) Según este video de la API de Google (espere un minuto más o menos para llegar al contenido aplicable), una razón para esta excepción puede ser el hecho de que no habilité el acceso a la API dentro de la Consola de API de Google para la cuenta. Sin embargo, si miras 2), puedes ver que lo hice.

8) Para mí, parece que el problema es que no pude establecer la clave de acceso Simple API correctamente, porque el método Calendar.setKey está obsoleto. Dentro del tutorial de Google Tasks que he vinculado anteriormente, la clave se establece mediante Tasks.accessKey = "key" . No estoy seguro de cómo conseguir esto trabajando con la API de calendario, sin embargo. He intentado varias cuentas de Google, que todo vino para arriba con la excepción de 5).

9) Quisiera señalar que el método tradicional de usar OAuth2 funcionó para mí. Aquí está el código que usé para eso:

 HttpTransport TRANSPORT = new NetHttpTransport(); JsonFactory JSON_FACTORY = new JacksonFactory(); String SCOPE = "https://www.googleapis.com/auth/calendar"; String CALLBACK_URL = "urn:ietf:wg:oauth:2.0:oob"; String CLIENT_ID = "myClientID"; String CLIENT_SECRET = "myClientSecret"; String authorizeUrl = new GoogleAuthorizationRequestUrl(CLIENT_ID, CALLBACK_URL, SCOPE).build(); String authorizationCode = "???"; // At this point, I have to manually go to the authorizeUrl and grab the authorization code from there to paste it in here while in debug mode GoogleAuthorizationCodeGrant authRequest = new GoogleAuthorizationCodeGrant(TRANSPORT, JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, authorizationCode, CALLBACK_URL); authRequest.useBasicAuthorization = false; AccessTokenResponse authResponse = authRequest.execute(); String accessToken = authResponse.accessToken; // gets the correct token GoogleAccessProtectedResource access = new GoogleAccessProtectedResource(accessToken, TRANSPORT, JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, authResponse.refreshToken); HttpRequestFactory rf = TRANSPORT.createRequestFactory(access); AccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessToken); HttpTransport transport = AndroidHttp.newCompatibleTransport(); Calendar service = Calendar.builder(transport, new JacksonFactory()) .setApplicationName("My Application's Name") .setHttpRequestInitializer(accessProtectedResource) .build(); Events events = service.events().list("primary").execute(); // this works! 

10) Finalmente, mi pregunta: Me gustaría usar la cuenta de AccountManager en el propio dispositivo para recuperar un token OAuth2 de trabajo para usar con la API de Google Calendar. El segundo método no es útil para mí, porque el usuario tendrá que ir manualmente a su navegador web y obtener el código de autorización, que no es fácil de usar. ¿Alguien tiene alguna idea? Disculpas por el largo post, y gracias!

Intente agregar un JsonHttpRequestInitializer al constructor y establezca su clave allí:

 Calendar service = Calendar.builder(transport, new JacksonFactory()) .setApplicationName("My Application's Name") .setHttpRequestInitializer(accessProtectedResource) .setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() { public void initialize(JsonHttpRequest request) { CalendarRequest calRequest = (CalendarRequest) request; calRequest.setKey("myCalendarSimpleAPIAccessKey"); } }).build(); 

Para responder no 10: básicamente he tenido que hacer lo que tenías que hacer para trabajar con TaskSample y luego usar la muestra de calendario de Android GData disponible aquí: http://code.google.com/p/google-api-java- Cliente / fuente / browse / calendario-android-sample / src / main / java / com / google / api / cliente / muestra / calendario / android / CalendarSample.java? Repo = muestras para obtener el AuthToken del propio AccountManager:

 accountManager = new GoogleAccountManager(this); settings = this.getSharedPreferences(PREF, 0); gotAccount(); private void gotAccount() { Account account = accountManager.getAccountByName(accountName); if (account != null) { if (settings.getString(PREF_AUTH_TOKEN, null) == null) { accountManager.manager.getAuthToken(account, AUTH_TOKEN_TYPE, true, new AccountManagerCallback<Bundle>() { @Override public void run(AccountManagerFuture<Bundle> future) { try { Bundle bundle = future.getResult(); if (bundle .containsKey(AccountManager.KEY_INTENT)) { Intent intent = bundle .getParcelable(AccountManager.KEY_INTENT); int flags = intent.getFlags(); flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK; intent.setFlags(flags); startActivityForResult(intent, REQUEST_AUTHENTICATE); } else if (bundle .containsKey(AccountManager.KEY_AUTHTOKEN)) { setAuthToken(bundle .getString(AccountManager.KEY_AUTHTOKEN)); // executeRefreshCalendars(); } } catch (Exception e) { handleException(e); } } }, null); } else { // executeRefreshCalendars(); } return; } chooseAccount(); } private void chooseAccount() { accountManager.manager.getAuthTokenByFeatures( GoogleAccountManager.ACCOUNT_TYPE, AUTH_TOKEN_TYPE, null, ExportClockOption.this, null, null, new AccountManagerCallback<Bundle>() { @Override public void run(AccountManagerFuture<Bundle> future) { Bundle bundle; try { bundle = future.getResult(); setAccountName(bundle .getString(AccountManager.KEY_ACCOUNT_NAME)); setAuthToken(bundle .getString(AccountManager.KEY_AUTHTOKEN)); // executeRefreshCalendars(); } catch (OperationCanceledException e) { // user canceled } catch (AuthenticatorException e) { handleException(e); } catch (IOException e) { handleException(e); } } }, null); } void setAuthToken(String authToken) { SharedPreferences.Editor editor = settings.edit(); editor.putString(PREF_AUTH_TOKEN, authToken); editor.commit(); createCalendarService(authToken); try { Events events = service.events().list("primary").execute(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void createCalendarService(String authToken) { accessProtectedResource = new GoogleAccessProtectedResource(authToken); Log.i(TAG, "accessProtectedResource.getAccessToken() = " + accessProtectedResource.getAccessToken()); JacksonFactory jsonFactory = new JacksonFactory(); service = com.google.api.services.calendar.Calendar .builder(transport, jsonFactory) .setApplicationName("Time Journal") .setJsonHttpRequestInitializer( new JsonHttpRequestInitializer() { @Override public void initialize(JsonHttpRequest request) { CalendarRequest calendarRequest = (CalendarRequest) request; calendarRequest .setKey("<YOUR SIMPLE API KEY>"); } }).setHttpRequestInitializer(accessProtectedResource) .build(); } 
  • Los eventos AllDay de Android comienzan o terminan en el día incorrecto
  • No se pueden insertar varios eventos en Google Calendar.
  • API de Google: ¿Diferencia entre la clave del navegador y la clave de Android?
  • Error de autorización de Google Calendar API
  • Android google calendar api no funciona cuando en la versión
  • Tratando de establecer un huso horario para un evento
  • Android Formato de fecha con zona horaria
  • Java.lang.NoClassDefFoundError en el estudio android
  • Editar / eliminar eventos de Google Calendar y obtener el ID de evento
  • Google OAuth2 - token de acceso y token de actualización -> invalid_grant / Code ya se redimió
  • ¿Cómo puedo llegar a la información de calendario de los usuarios en el servidor?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.