好的,我有一点工作,但后来想在app启动时添加静默登录(可选)。我现在发疯了,并且遇到了错误
com.google.api.client.googleapis.json.GoogleJsonResponseException:401 Unauthorized { “代码”:401, “错误”:[ { “域名”:“全球”, “location”:“授权”, “locationType”:“标题”, “message”:“需要登录”, “理由”:“必需” } ] “message”:“需要登录” }
这发生在线上(我应该使用“我”吗?)
Message messageResult = mGmailService.users().messages().send("me", message).execute();
每当我尝试发送(在上面的情况下)或阅读电子邮件(未显示)。最终,我想要对应用程序做的只是阅读用户的电子邮件并代表他们发送。该应用已注册,具有密钥,权限等。
我正在设置数据(当我尝试工作时你可以看到我的各种评论):
mGso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestScopes(new Scope(Scopes.PROFILE))
.requestScopes(new Scope(GmailScopes.GMAIL_READONLY))
.requestScopes(new Scope(GmailScopes.GMAIL_SEND))
.requestScopes(new Scope(GmailScopes.GMAIL_COMPOSE))
.requestScopes(new Scope(GmailScopes.GMAIL_LABELS))
.requestScopes(Plus.SCOPE_PLUS_LOGIN)
.requestScopes(new Scope(Scopes.EMAIL))
.requestScopes(new Scope(Scopes.PLUS_ME))
.build();
// set up Google client
// mGoogleApiClient = new GoogleApiClient.Builder(this)
// .addConnectionCallbacks(this)
// .addOnConnectionFailedListener(this)
// .addApi(Plus.API)
// .addApi(Auth.GOOGLE_SIGN_IN_API, mGso)
// .build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
// .enableAutoManage(this, this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addApi(Auth.GOOGLE_SIGN_IN_API, mGso)
.build();
//mGoogleApiClient.connect(GoogleApiClient.SIGN_IN_MODE_REQUIRED); // try to connect right away
mGmailService = new com.google.api.services.gmail.Gmail.Builder(
AndroidHttp.newCompatibleTransport(), GsonFactory.getDefaultInstance(), null)
.setApplicationName("com.company.appname")
.build();
静默登录在嵌入式片段的onStart()方法中完成:
// try to silently sign in ...
OptionalPendingResult<GoogleSignInResult> pendingResult =
Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (pendingResult.isDone()) {
// There's an immediate result available.
mSignInAcct = pendingResult.get().getSignInAccount();
mEmailAcct = mSignInAcct.getEmail();
} else {
// There's no immediate result ready, wait for the async callback.
pendingResult.setResultCallback(new ResultCallback<GoogleSignInResult>() {
@Override
public void onResult(@NonNull GoogleSignInResult result) {
mSignInAcct = result.getSignInAccount();
mEmailAcct = mSignInAcct.getEmail();
} // if fails, forget it and force a real login later.
});
}
mGoogleApiClient.connect(GoogleApiClient.SIGN_IN_MODE_OPTIONAL);
boolean b = mGoogleApiClient.isConnected();
有时会使用有效的用户帐户进行连接,有时则不会。我确实看到...来自...的isConnected()调用是假的,虽然isConnected()稍后在后面的调用中返回true。
登录按钮代码:
gmail_signin_button = (com.google.android.gms.common.SignInButton) rootView.findViewById(R.id.gmail_sign_in_button);
gmail_signin_button.setScopes(mGso.getScopeArray());
gmail_signin_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// User clicked the sign-in button, so begin the sign-in process and automatically
// attempt to resolve any errors that occur.
mShouldResolve = true;
// connect if unconnected...
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
tv_email_status.setText("G+ connecting");
// Show a message to the user that we are signing in.
Log.d(Constants.TAG, "Google API connecting ...");
}
else {
// sign in anew ...
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, Constants.RC_SIGN_IN);
}
}
});
onActivityResult代码(部分):
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// G+
if (requestCode == Constants.RC_SIGN_IN) {
// If the error resolution was not successful we should not resolve further.
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (!result.isSuccess()) {
mShouldResolve = false;
Log.d(Constants.TAG, "Error: code: " + resultCode);
tv_email_status.setText("Error: code: " + resultCode);
} else {
mSignInAcct = result.getSignInAccount();
mEmailAcct = mSignInAcct.getEmail();
Log.d(Constants.TAG, "Gmail signin OK - " + mEmailAcct);
tv_email_status.setText("Email: " + mEmailAcct);
}
mIsResolving = false;
if(!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect(GoogleApiClient.SIGN_IN_MODE_OPTIONAL);
}
} else if (requestCode == Constants.REQUEST_ACCOUNT_PICKER) {
if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
mEmailAcct = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (mEmailAcct != null) {
//mCredential.setSelectedAccountName(accountName);
SharedPreferences settings = mActivity.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(Constants.PREF_ACCOUNT_NAME, mEmailAcct);
editor.commit();
Log.d(Constants.TAG, "Gmail: account: " + mEmailAcct);
tv_email_status.setText("Gmail: account: " + mEmailAcct);
}
} else if (resultCode == RESULT_CANCELED) {
tv_email_status.setText("Account unspecified.");
}
}
//else if (requestCode == Constants.REQUEST_AUTHORIZATION) {
//if (mCredential != null && resultCode != RESULT_OK) {
// startActivityForResult(mCredential.newChooseAccountIntent(), Constants.REQUEST_ACCOUNT_PICKER);
//}
//}
好的,我会得到一个好的onActivityResult并获得有效的SignInAcct和EmailAcct值。 似乎我们已经登录正常,但是gMail服务总是因为401错误而失败,如上所述。
要进行静音登录,我必须添加GOOGLE_SIGN_IN_API,然后似乎需要GoogleApiClient与SIGN_IN_MODE_OPTIONAL连接,这对我来说没有意义。
我也看到我的AccountPicker现在也没有做任何事情。但这是另一个故事/问题,正如我所说,我认为这一切都有效,直到我尝试添加该静音功能。
哇,好吧,我可能比这更难,有人能引导我朝着正确的方向前进吗?正如我所说,我想做的就是:
答案 0 :(得分:0)
void setGmailAccess(GoogleSignInResult result) {
mSignInAcct = result.getSignInAccount();
mEmailAcct = mSignInAcct.getEmail();
final Thread task = new Thread()
{
@Override
public void run()
{
try {
// run in background thread
String token = GoogleAuthUtil.getToken(MainActivity.this, Plus.AccountApi.getAccountName(mGoogleApiClient), "oauth2:profile email");
GoogleCredential credential = new GoogleCredential().setAccessToken(token);
mGmailService = new com.google.api.services.gmail.Gmail.Builder(
AndroidHttp.newCompatibleTransport(), GsonFactory.getDefaultInstance(), credential)
.setApplicationName("com.company.appname")
.build();
}
catch (Exception e) {
// ignore errors
String error = e.getMessage();
}
}
};
task.start();
}
设置GmailService对象。它是从onConnected调用的,我在结果成功块中有这样的代码:
try {
// try to silently sign in ...
OptionalPendingResult<GoogleSignInResult> pendingResult =
Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
if (pendingResult.isDone()) {
// There's an immediate result available.
setGmailAccess(pendingResult.get());
} else {
// There's no immediate result ready, wait for the async callback.
pendingResult.setResultCallback(new ResultCallback<GoogleSignInResult>() {
@Override
public void onResult(@NonNull GoogleSignInResult result) {
setGmailAccess(result);
} // if fails, forget it and force a real login later.
});
}
} catch(Exception e) {
String me = e.getLocalizedMessage();
}
在开始新登录的活动结果中。似乎工作。