7

Tôi đang làm việc trên ứng dụng Android Honeycomb (v3.0) có yêu cầu liên lạc với API Lịch Google. Tôi muốn cho phép ứng dụng của tôi truy cập vào dữ liệu Lịch của tài khoản Google cụ thể để đọc và tạo sự kiện.API Lịch Google OAuth2 trên Android Honeycomb

Thật không may, tôi gặp sự cố với ủy quyền sử dụng OAuth2. Dưới đây là những gì tôi có cho đến thời điểm này:

1) Tài khoản Google có lịch mà tôi muốn truy cập được đăng ký trong thiết bị Android mà tôi đang làm việc.

2) Tôi đã bật API lịch trong Bảng điều khiển API Google trên tài khoản.

3) Tôi có thể truy cập vào tài khoản này bằng cách sử dụng đoạn mã sau:

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) Bây giờ tôi muốn để có được một authToken để sử dụng khi giao tiếp với lịch. Tôi đã theo dõi số tutorial này nhưng đã chuyển đổi mọi thứ để hoạt động với Lịch Google thay vì Google Task. Tôi đã truy xuất thành công số authToken từ số AccountManager bằng tài khoản tôi muốn sử dụng bằng cách sử dụng getAuthToken với AUTH_TOKEN_TYPE == "oauth2:https://www.googleapis.com/auth/calendar".

5) Đây là nơi các sự cố bắt đầu. Tôi bây giờ vào thời điểm này:

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) Dưới đây là những ngoại lệ được trả về bởi dòng cuối cùng:

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) Theo này Google API Video (chờ một phút hoặc lâu hơn để có được nội dung áp dụng), lý do cho ngoại lệ này có thể là do tôi không bật quyền truy cập API trong Bảng điều khiển API Google cho tài khoản. Tuy nhiên, nếu bạn nhìn vào 2), bạn có thể thấy rằng tôi đã làm như vậy.

8) Đối với tôi, có vẻ như vấn đề là tôi không thể đặt Khóa truy cập API đơn giản một cách chính xác, vì phương pháp Calendar.setKey không được chấp nhận. Trong hướng dẫn Google Task mà tôi đã liên kết trước đó, khóa được đặt bằng cách sử dụng Tasks.accessKey = "key". Tôi không chắc chắn làm thế nào để có được điều này làm việc với API lịch, mặc dù. Tôi đã thử nhiều tài khoản Google, tất cả đều xuất hiện với ngoại lệ từ 5).

9) Tôi muốn chỉ ra rằng phương pháp truyền thống sử dụng OAuth2 đã hoạt động đối với tôi. Dưới đây là đoạn code tôi sử dụng cho rằng:

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) Cuối cùng, câu hỏi của tôi: Tôi muốn sử dụng tài khoản từ lý Tài khoản trên thiết bị riêng của mình để lấy một OAuth2 thẻ làm việc để sử dụng với Google Calendar API. Phương pháp thứ hai không hữu ích cho tôi, bởi vì người dùng sẽ phải tự truy cập trình duyệt web của họ và nhận mã ủy quyền, không thân thiện với người dùng. Ai có ý tưởng gì không? Xin lỗi vì bài viết dài và cảm ơn!

+0

chào, tôi đang đối mặt với một vấn đề tương tự, tôi sử dụng mã này đoạn để có được một lịch ứng dụng đang chạy, nhưng sau đó tôi nhận được một 403 , truy cập lỗi bị cấm, đồng uld u xin vui lòng hỗ trợ, những gì tôi nên làm trong Android? mặc dù tôi không sử dụng số 8 làm tùy chọn. xin vui lòng hlp. –

+0

Bạn đang sử dụng tùy chọn nào? Bạn đã kiểm tra câu trả lời của @ eltrl chưa? – BVB

Trả lời

4

Hãy thử thêm một JsonHttpRequestInitializer đến xây dựng và thiết lập chìa khóa của bạn có:

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(); 
+0

Cảm ơn bạn, nhưng tôi nhận được lỗi sau trong Eclipse: 'Phương thức setJsonHttpRequestInitializer (JsonHttpRequestInitializer) trong kiểu Calendar.Builder không áp dụng cho các đối số (new JsonHttpRequestInitializer() {})' – BVB

+0

Ôi, tôi đã sửa lỗi (vấn đề nhập khẩu) và nó đã hoạt động! Cảm ơn bạn rất nhiều! – BVB

+1

Không vấn đề gì, những thứ này không phải là rất nhỏ để chẩn đoán trạng thái hiện tại (beta) của tài liệu. – eltrl

1

Để trả lời không 10: Tôi đã về cơ bản đã phải làm những gì bạn phải làm làm việc với TaskSample và sau đó sử dụng Android GData Lịch mẫu có sẵn ở đây: http://code.google.com/p/google-api-java-client/source/browse/calendar-android-sample/src/main/java/com/google/api/client/sample/calendar/android/CalendarSample.java?repo=samples để có được những authToken từ lý Tài khoản chính:

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(); 
} 
Các vấn đề liên quan