Java 挂起GetAuthToken()的AccountManager

Java 挂起GetAuthToken()的AccountManager,java,android,multithreading,android-asynctask,oauth-2.0,Java,Android,Multithreading,Android Asynctask,Oauth 2.0,因此,我使用Android中的AccountManager来存储OAuth2凭据。然后,这些凭证将在getAuthToken方法中使用,就像任何其他帐户管理器一样。这是我的getAuthToken方法: @Override public Bundle getAuthToken(AccountAuthenticatorResponse response, final Account account, String authTokenType, Bundle options) throws Netw

因此,我使用Android中的
AccountManager
来存储OAuth2凭据。然后,这些凭证将在
getAuthToken
方法中使用,就像任何其他帐户管理器一样。这是我的
getAuthToken
方法:

@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, final Account account, String authTokenType, Bundle options) throws NetworkErrorException {
    Log.d(TAG, "onGetAuthToken");
    final AccountManager am = AccountManager.get(context);

    String storeToken = am.peekAuthToken(account, authTokenType);

    final String password = am.getPassword(account);
    if (TextUtils.isEmpty(storeToken) && password != null) {
        storeToken = new OAuth2Client(account.name, password, "test", "test", Constants.getServerUrlBase() + "token.php").getAccessToken().getAccessToken();
    } else {
        if (password != null) {
            final Bundle result = new Bundle();
            String authToken = null;

            // Network stuff
            JSONObject JSONResult;
            DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
            HttpPost httppost = new HttpPost(Constants.SERVER_URL_BASE + "verify.php");
            List<NameValuePair> pairs = new ArrayList<>();
            pairs.add(new BasicNameValuePair("access_token", storeToken));
            try {
                httppost.setEntity(new UrlEncodedFormEntity(pairs));
            } catch (UnsupportedEncodingException e) {
                Log.e(TAG, "onFailed Posting\n" + e);
            }
            InputStream inputStream = null;

            try {
                HttpResponse httpResponse = httpClient.execute(httppost);
                HttpEntity entity = httpResponse.getEntity();

                inputStream = entity.getContent();
                // json is UTF-8 by default
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                StringBuilder sb = new StringBuilder();

                String line;
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
                Log.d(TAG + "." + this.getClass().getEnclosingMethod(), "onReceivedData " + sb.toString());
                JSONResult = new JSONObject(sb.toString());


                if (JSONResult.getBoolean("success"))
                    authToken = storeToken;
            } catch (JSONException | IOException e) {
                Log.e(TAG, "onCrashed\n", e);
            } finally {
                if (inputStream != null) try {
                    inputStream.close();
                } catch (IOException e) {
                    Log.e(TAG, "Failed on inputStream!\n", e);
                }
            }
            if (authToken == null) {
                authToken = new OAuth2Client(account.name, password, "corentec_logistics_application", "corentec123", Constants.getServerUrlBase() + "token.php").getAccessToken().getAccessToken();
                am.invalidateAuthToken(Constants.ACCOUNT_TYPE, storeToken);
                am.setUserData(account, AccountManager.KEY_AUTHTOKEN, authToken);
            }

            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
            result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
            result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
            Log.d(TAG, "onPostExecute with String: " + authToken);
            return result;
        }
    }

    final Intent intent = new Intent(context, AuthenticatorActivity.class);
    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
    intent.putExtra(AuthenticatorActivity.ARG_ACCOUNT_TYPE, account.type);
    intent.putExtra(AuthenticatorActivity.ARG_AUTH_TYPE, authTokenType);
    final Bundle bundle = new Bundle();
    bundle.putParcelable(AccountManager.KEY_INTENT, intent);
    return bundle;
}
而且

private class GetToken extends AsyncTask<Void, Void, String> {
    String token = null;

    @Override
    protected String doInBackground(Void... params) {
        Log.d(TAG, "onDoInBackgroundExecute");
        try {

            token = accountManager.getAuthToken(getCurrentAccount(), Constants.TOKEN_TYPE, null, null, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
            Log.d(TAG, "Finished getting token: " + token);
        } catch (OperationCanceledException | IOException | AuthenticatorException e) {
            Log.e(TAG, "onCrashed getting token\n", e);
        }
        return token;
    }
}
application
作为应用程序类的实例

但是,这会挂起活动。Logcat和线程快照表示这是由于以下原因:
token=accountManager.getAuthToken(getCurrentAccount(),Constants.token\u TYPE,null,null,null,null).getResult().getString(accountManager.KEY\u AUTHTOKEN)


异步任务的内部
GetToken
。我不明白为什么这件事会悬而未决。有人能帮忙吗?

我也遇到了同样的问题,你解决了吗@Luca Santarella这是因为在getAuthToken()中调用setUserData()。还没发现,怎么解决呢。。由于文档的原因,您应该在创建帐户后设置用户数据。
private class GetToken extends AsyncTask<Void, Void, String> {
    String token = null;

    @Override
    protected String doInBackground(Void... params) {
        Log.d(TAG, "onDoInBackgroundExecute");
        try {

            token = accountManager.getAuthToken(getCurrentAccount(), Constants.TOKEN_TYPE, null, null, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
            Log.d(TAG, "Finished getting token: " + token);
        } catch (OperationCanceledException | IOException | AuthenticatorException e) {
            Log.e(TAG, "onCrashed getting token\n", e);
        }
        return token;
    }
}
application.setCurrentAccount(new Account(intent.getStringExtra(AccountManager.KEY_ACCOUNT_NAME), Constants.ACCOUNT_TYPE));
String token = application.getAuthToken();