使用GoogleSignIn的Google API - 错误401 - 未经授权

时间:2018-04-18 05:36:54

标签: 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);
  }
}

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

2 个答案:

答案 0 :(得分:2)

我刚刚解决了这个问题,我希望这将有助于所有遭受无法解释的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等时使用console.log()对象。

祝大家好运......

答案 1 :(得分:0)

可能是您试图在没有任何同步过程的情况下调用您的日历代码。请尝试以下集成Google日历的代码。 处理Google Calendar API调用的异步任务。将API调用放在自己的任务中可确保UI保持响应。

private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
        private com.google.api.services.calendar.Calendar mService = null;
        private Exception mLastError = null;

        MakeRequestTask(GoogleAccountCredential credential) {
            HttpTransport transport = AndroidHttp.newCompatibleTransport();
            JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
            mService = new com.google.api.services.calendar.Calendar.Builder(
                    transport, jsonFactory, credential)
                    .setApplicationName("Google Calendar API Android Quickstart")
                    .build();
        }

        @Override
        protected List<String> doInBackground(Void... params) {
            try {
                return getDataFromApi();
            } catch (Exception e) {
                mLastError = e;
                cancel(true);
                return null;
            }
        }

        private List<String> getDataFromApi() throws IOException {
            // List the next 10 events from the primary calendar.
            DateTime now = new DateTime(System.currentTimeMillis());
            List<String> eventStrings = new ArrayList<String>();
            Events events = mService.events().list("primary")
                    .setMaxResults(10)
                    .setTimeMin(now)
                    .setOrderBy("startTime")
                    .setSingleEvents(true)
                    .execute();
            List<Event> items = events.getItems();

            for (Event event : items) {
                DateTime start = event.getStart().getDateTime();
                if (start == null) {
                    // All-day events don't have start times, so just use
                    // the start date.
                    start = event.getStart().getDate();
                }
                eventStrings.add(
                        String.format("%s (%s)", event.getSummary(), start));
            }
            return eventStrings;
        }


        @Override
        protected void onPreExecute() {
            mOutputText.setText("");
            mProgress.show();
        }

        @Override
        protected void onPostExecute(List<String> output) {
            mProgress.hide();
            if (output == null || output.size() == 0) {
                //"No results returned
            } else {
                //Data retrieved using the Google Calendar API
            }
        }
}

有关详细信息,请查看google documentation description

相关问题