如果在SyncAdapter.onPerformSync
中固有获取身份验证令牌导致用户需要输入密码,如何成功登录后重新运行或继续同步?< / p>
虽然这似乎是一个相当标准的功能,但我一直无法找到它。 AccountManager.getAuthToken docs似乎暗示使用an OnAccountsUpdatedListener,但我已经尝试过,它永远不会被调用。此外,如果我理解正确的文档,那么将会调用任何更改任何帐户,这似乎有点......间接。
以下是我的代码的相关部分。我密切关注official guide和优秀的blog post by Udinic
在Authenticator.getAuthToken
中// There is neither an access nor a refresh token. User has to log in
if (!tokens.hasAccess() && !tokens.hasRefresh()) {
Intent intent = new Intent(context, LoginActivity.class);
intent.putExtra(LoginActivity.ARG_ACCOUNT, account);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); // As per AbstractAccountAuthenticator doc
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
}
...
return bundle;
在LoginActivity.finishLogin
// Store access token if one was provided. Note that this should always be the case anyway,
// otherwise the login would have been unsuccessful
if (tokens.hasAccess()) {
manager.setAuthToken(account, Authenticator.TOKEN_TYPE_ACCESS, tokens.access);
}
// Store refresh token if one was provided.
if (tokens.hasRefresh()) {
manager.setAuthToken(account, Authenticator.TOKEN_TYPE_REFRESH, tokens.refresh);
}
final Intent intent = new Intent();
if (tokens.hasAccess()) {
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type);
intent.putExtra(AccountManager.KEY_AUTHTOKEN, tokens.access);
}
setAccountAuthenticatorResult(intent.getExtras());
setResult(Activity.RESULT_OK, intent);
finish();
而且,即使它有点微不足道: 在SyncAdapter.onPerformSync中:
String token = null;
try {
token = AccountManager.get(getContext()).blockingGetAuthToken(account, Authenticator.TOKEN_TYPE_ACCESS, true);
if (token == null) {
syncResult.stats.numAuthExceptions++;
return;
}
} catch (OperationCanceledException x) {
return;
} catch (AuthenticatorException x) {
syncResult.stats.numAuthExceptions++;
return;
} catch (IOException x) {
syncResult.stats.numIoExceptions++;
return;
}
答案 0 :(得分:1)
经过一番讨论,我相信你需要的是:
ContentResolver.requestSync(account, Contract.AUTHORITY, new Bundle());
您的客户经理非常合理地导致blockingGetAuthToken立即返回null,此时需要用户交互才能完成同步。您只需要安排,当用户完成操作(验证自己)时,您请求新的同步。上面的代码就可以了。