android - 带有 GoogleSignIn 的 Google API - 错误 401 - 未经授权

标签 android google-api

我在这件事上坐了将近一个星期,找不到任何实际解释如何将 GoogleSignIn 连接到 Google API 的文档...

我正在尝试通过 Google(通过使用 GoogleSignIn 框架)对用户进行身份验证,然后阅读特定的日历。 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);
  }
}

然后,尝试使用以下方法访问日历 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- 未经授权的错误... 我做错了什么吗? 重要的是要提到我确实从帐户对象中获取了用户信息(我看到了电子邮件,我得到了一个 token 等)

最佳答案

我刚刚解决了这个问题,我希望这能帮助所有遭受无法解释的 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,这是我通过实验得到的(太糟糕了,我花了大约一周的时间来尝试那个......)。

当你实现它时,确保它是干净的(只有当它不是null时才使用account对象,等等)

祝大家好运...

关于android - 带有 GoogleSignIn 的 Google API - 错误 401 - 未经授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49891923/

相关文章:

google-apps-script - 在 Google 表格模板的容器绑定(bind)脚本中维护启用的 API

php - 提高 Gmail API 速度的方法 (PHP)

Golang - Gmail API 400 BadRequest 失败前提条件

android - Activity 启动时显示软键盘

javascript - google.setOnLoadCallback(initialize) 函数到底是什么意思?

javascript - Google 登录使用 Hello.js 返回用户名 'Undefined"

Android 3.x EditText 光标颜色

android - 如何在 Eclipse Buildship 插件中运行 'gradle init' 任务?

android - android 的主页按钮到底在做什么?

java - 安卓.content.res.Resources$NotFoundException : File from xml type layout resource ID #0x1020014