我在这个东西上坐了近一个星期,却找不到任何能真正说明如何将GoogleSignIn连接到Google API的文档...

我试图通过使用GoogleSignIn框架向Google验证用户身份,然后读取特定的日历。 iOS上的类似方法“开箱即用”,现在我正尝试为Android做同样的事情。

我使用以下方法验证用户身份:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestScopes(new Scope("https://www.googleapis.com/auth/calendar.readonly"))
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();
signInClient = GoogleSignIn.getClient(getContext(), gso);
signIn.setSize(SignInButton.SIZE_STANDARD);
signIn.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    Intent signInIntent = signInClient.getSignInIntent();
    startActivityForResult(signInIntent, RC_SIGN_IN);
  }
});
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(getContext());
if (account == null) {
  setSignInVisible(true);
} else {
  setSignInVisible(false);
  if (account.getIdToken() != null) {
    AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    mAuth.signInWithCredential(credential);
  }
}


然后,尝试使用以下方法访问Calendar API:

Calendar HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleSignInAccount gsia = GoogleSignIn.getLastSignedInAccount(getContext());
GoogleCredential gc = new GoogleCredential().setAccessToken(gsia.getIdToken());
mService = new com.google.api.services.calendar.Calendar.Builder(
                    transport, jsonFactory, gc)
                    .setApplicationName("MyApp")
                    .build();
Events events = mService.events().list(CalendarActivity._dataStore.getConfigString(CalendarActivity.instance.getString(R.string.config_google_calendar_key)))
                    .setTimeMin(dtFourDaysBack)
                    .setTimeMax(dtTwoMonthFuture)
                    .setOrderBy("startTime")
                    .setSingleEvents(true)
                    .execute();


但是,执行会导致401-未经授权的错误...
我做错什么了吗?
重要的是要提到我确实从帐户对象获取用户信息(我看到电子邮件,得到令牌等)。

最佳答案

我刚刚解决了这个问题,希望这对所有遭受无法解释的401-未经授权错误的人有所帮助。

问题是凭证的生成。
它的创建方式为:

private static final String[] SCOPES = { CalendarScopes.CALENDAR_READONLY };
final GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(getContext());
GoogleAccountCredential mCredential = GoogleAccountCredential.usingOAuth2(
                                       mainActivity.instance, Arrays.asList(SCOPES))
                                      .setSelectedAccountName(account.getAccount().name)
                                      .setBackOff(new ExponentialBackOff());


注意凭据的用法。不是GoogleCredentials。我无法在任何地方找到的东西是需要通过实验达到setSelectedAccountName的要求(可惜的是,我花了大约一个星期的时间来尝试那个...)。

实施它时,请确保将其清理干净(仅当account对象不是null时才使用它,依此类推。

祝大家好运...

07-24 09:34