Android访问令牌上的Google Calendar API

时间:2019-04-12 18:41:38

标签: android google-calendar-api google-oauth

我想查询事件并将事件添加到已经登录到该应用程序(使用其Google帐户)的用户的主日历中。

我走了这么远:

class CalendarClient {
    private static final String APPLICATION_NAME = "TrackTransfer";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    private final String token;

    CalendarClient (String token){
        this.token = token;
    }

    private Credential getCredentials() {
        return new GoogleCredential().setAccessToken(token);
    }

    void print() throws IOException {
        // Build a new authorized API client service.
        final NetHttpTransport HTTP_TRANSPORT = new com.google.api.client.http.javanet.NetHttpTransport();
        Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials())
                .setApplicationName(APPLICATION_NAME)
                .build();

        // List the next 10 events from the primary calendar.
        DateTime now = new DateTime(System.currentTimeMillis());
        Events events = service.events().list("primary")
                .setMaxResults(10)
                .setTimeMin(now)
                .setOrderBy("startTime")
                .setSingleEvents(true)
                .execute();
        List<Event> items = events.getItems();
        if (items.isEmpty()) {
            System.out.println("No upcoming events found.");
        } else {
            System.out.println("Upcoming events");
            for (Event event : items) {
                DateTime start = event.getStart().getDateTime();
                if (start == null) {
                    start = event.getStart().getDate();
                }
                System.out.printf("%s (%s)\n", event.getSummary(), start);
            }
        }
    }

}

我从这样的活动中这样称呼它:用户已经登录,并且登录帐户由account表示。

private void writeToCalendar()  {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Log.d("CAL", "token: " + account.getIdToken());
                CalendarClient c = new CalendarClient(account.getIdToken());
                c.print();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

}

但是,即使用户已登录,account.getIdToken()仍为Null。 我还尝试将令牌设置为在Google开发人员控制台中为我的应用程序获取的客户端ID,这也不起作用。

自然地,当令牌为Null时,我得到一个异常,指出超出了未签名的api调用的条件。

在调用writeToCalendar()之前访问该健身API对该帐户来说不是问题(因此已登录)。

我查看了各种资源,但都证明没有用。 Google API文档是有关Java的,并使用了从开发者控制台获得的凭据。但是,由于我想使用OAuth进行身份验证,因此这不是正确的选择(我想是吗?)。 然后我发现一个人可以使用GoogleCredential().setAccessToken(token),但我不知道使用了什么令牌。

如何获取正确的令牌?

更新

当请求登录帐户的范围时,可以使用Fitness api进行直接操作:

FitnessOptions fitnessOptions = FitnessOptions.builder()
                .addDataType(DataType.TYPE_DISTANCE_DELTA, FitnessOptions.ACCESS_READ)
                .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
                .build();
GoogleSignInAccount gsa = GoogleSignIn.getAccountForExtension(this, fitnessOptions);

具有如下所示的回调:

account = completedTask.getResult(ApiException.class);

但是,当请求日历api的作用域时,以下正确吗?

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .requestScopes(new Scope("https://www.googleapis.com/auth/calendar"))
                .build();
GoogleSignInClient tempClient = GoogleSignIn.getClient(this, gso);

3 个答案:

答案 0 :(得分:1)

登录

sign in

我也发现了这一点,在api给您访问令牌之前,您可能需要使用oauth:

auth

然后,我将检查您是否需要为其启用帐单帐户的api之一。有可能。这并不意味着您需要付费...取决于Google使您“启用”帐单的api。不确定此api是否是其中之一。

info

答案 1 :(得分:0)

很有可能,现有登录名不具有必需的oAuth2 scopes

事先请求这些内容应该提供能够访问API的范围。

答案 2 :(得分:0)

要使用日历api,您需要accessToken。在您的示例中,您使用的是idToken而不是它。 即使您获得idToken和reqest事件,您也会收到错误消息。

code: 401
message: wrong credential

为了获得令牌,您可以使用以下两种方法之一:AuthUtils.getToken,GoogleAuthorizationCodeTokenRequest()。但是在这些之前,您必须请求权限(Google登录+ scoppes),以免出现错误:“未授予权限”。 (https://developers.google.com/calendar/auth

AuthUtils.getToken:

 @Deprecated
 public static String getToken(Context context, String email, String var2) throws IOException, UserRecoverableAuthException, GoogleAuthException

 public static String getToken(Context var0, Account var1, String var2) throws IOException, UserRecoverableAuthException, GoogleAuthException

GoogleAuthorizationCodeTokenRequest(推荐方法https://developers.google.com/identity/sign-in/android/migration-guide):

  /**
   * @param transport HTTP transport
   * @param jsonFactory JSON factory
   * @param clientId client identifier issued to the client during the registration process
   * @param clientSecret client secret
   * @param code authorization code generated by the authorization server
   * @param redirectUri redirect URL parameter matching the redirect URL parameter in the
   *        authorization request (see {@link #setRedirectUri(String)}
   */
  public GoogleAuthorizationCodeTokenRequest(HttpTransport transport, JsonFactory jsonFactory,
      String clientId, String clientSecret, String code, String redirectUri)