AccountManager: invalidateAuthToken does not inval

2020-04-10 02:54发布

I'm trying to get a brand new token from a Google account stored in a Android device but all that I got is the same old token that I've been caching in the last days. It seems that it's cached somewhere in the phone, and even the Internet request is not being sent (I made the test in the app without Internet connection and the same token is returned).

I used the invalidateAuthToken method before getting a new one with getResult from AccountManagerFuture. Take a look please:

public String updateToken(Activity activity) throws Exception {             
    AccountManager am = AccountManager.get(activity);
    Account[] accounts = am.getAccountsByType("com.google");

    if (accounts == null || 
        accounts.length == 0 || 
        "".equals(accounts[0].name.trim())) 
    {
        throw new Exception("Não há contas Google configuradas no smartphone.");
    } 
    else if (!"crsilva@gmail.com".equals(accounts[0].name.trim()) && 
             !"cristiano.bezerra@sulamerica.com.br".equals(accounts[0].name.trim()) &&
             !"tholiver@gmail.com".equals(accounts[0].name.trim())) 
    {
        Log.w("Util.updateToken","conta obtida: " + accounts[0].name);
        throw new Exception("Conta Google não autorizada.");
    }
    Log.w("Util.updateToken","conta obtida: " + accounts[0].name);
    am.invalidateAuthToken("com.google", null);
    Log.w("Util.updateToken","Passou do invalidateAuthToken");
    AccountManagerFuture<Bundle> future = 
        am.getAuthToken(accounts[0], "ah", null, activity, null, null);
    Log.w("Util.updateToken","Passou do getAuthToken");
    Bundle bundle = future.getResult();
    Log.w("Util.updateToken","Passou do getResult");
    future = null;
    am = null;
    accounts = null;
    String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
    Log.w("Util.updateToken","Token: " + authToken);
    return authToken;
}

A thread called this method from a Util class by singleton instance. The manifest has all the permissions necessary. Does somebody have idea why the token is not refreshed?

2条回答
够拽才男人
2楼-- · 2020-04-10 03:12

To invalidate the auth token you need to pass the token you want to invalidate as the second argument to invalidateAuthToken. Please see section "4.4.3 Invalidate the auth token" of this blog post. The video on that page is also helpful.

The documentation for invalidateAuthToken mention that the second argument may be null, but this only mean that it's allowed to call this method with null, not that every cached token is invalidated if null is passed.

If you do something like this instead your code should work:

// Get token
AccountManagerFuture<Bundle> future = am.getAuthToken(accounts[0], "ah", null, activity, null, null);
Bundle bundle = future.getResult();
String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);

// invalidate the token since it may have expired.
am.invalidateAuthToken("com.google", authToken);

// Get token again
future = am.getAuthToken(accounts[0], "ah", null, activity, null, null);
bundle = future.getResult();
authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
查看更多
爷、活的狠高调
3楼-- · 2020-04-10 03:22

It is simpler to simply "peek" the currently cached token, check if it is still valid, and create a new one if required.

String authToken = accountManager.peekAuthToken(account, Constants.AUTHTOKEN_TYPE);
// validate the token, invalidate and generate a new one if required
accountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, authToken);
accountManager.blockingGetAuthToken(account,
                Constants.AUTHTOKEN_TYPE, NOTIFY_AUTH_FAILURE);
查看更多
登录 后发表回答