Android访问令牌上的Google日历API

Android访问令牌上的Google日历API,android,google-calendar-api,google-oauth,Android,Google Calendar Api,Google Oauth,我想查询并将事件添加到已登录应用程序的用户的主日历中(使用他/她/其“谷歌帐户”) 我已经走了这么远: class CalendarClient { private static final String APPLICATION_NAME = "TrackTransfer"; private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); private final

我想查询并将事件添加到已登录应用程序的用户的主日历中(使用他/她/其“谷歌帐户”)

我已经走了这么远:

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.getIdToken()仍为
Null
。 我还尝试将令牌设置为在GoogleDeveloper控制台中为我的应用程序获取的客户端ID,这也不起作用

自然地,当令牌为
Null
时,我会得到一个异常,表明超出了未登录api调用的条件

在调用
writeToCalendar()
之前访问Fitness API对该帐户没有问题(因此已登录)

我查看了各种资源,但均未证明有帮助。GoogleAPI文档是关于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);
登录

我还发现,在api向您提供访问令牌之前,您可能需要使用oauth:

然后我会检查它是否是您需要启用计费帐户的api之一。可能是。这并不意味着你需要付费……这取决于谷歌让你“启用”计费的api。不确定此api是否是其中之一


现有登录很可能不具备所需的oAuth2


之前请求这些应该提供能够访问API的作用域。

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

code: 401
message: wrong credential
为了获得令牌,可以使用以下两种方法之一:AuthUtils.getToken、GoogleAuthorizationCodeTokenRequest()。但在此之前,您必须请求权限(google登录+scoppes),以免出现错误:“未授予权限”。()

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(推荐方法):


我不得不问,你启用了api吗?很好,但是是的;密钥是否仅限于设备类型?如果这不是默认设置,则为NOB但这将如何帮助使令牌非空?我更新了答案。但是可以肯定的是,一些map api,也许这一个在付费帐户建立之前(即使是免费的)不会让你访问。这是谷歌的事情。像更新的问题中那样请求范围正确吗?或者,在使用谷歌日历API时,您是否必须采取不同的做法?
 @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
  /**
   * @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)