Android 从不从getAuthToken请求获取AccountManager.KEY\u意图

Android 从不从getAuthToken请求获取AccountManager.KEY\u意图,android,Android,在JellyBean设备上 我下面请求一个oauth2令牌,例如 AccountManager am = AccountManager.get(getActivity()); am.invalidateAuthToken(MY_AUTH_TOKEN_TYPE, null); am.getAuthToken(aGoogleAccount, MY_AUTH_TOKEN_TYPE, null, this, new OnTokenAcquired(), new Handler(new OnEr

在JellyBean设备上

我下面请求一个oauth2令牌,例如

AccountManager am = AccountManager.get(getActivity());
am.invalidateAuthToken(MY_AUTH_TOKEN_TYPE, null);
am.getAuthToken(aGoogleAccount, MY_AUTH_TOKEN_TYPE, null, this, 
    new OnTokenAcquired(), new Handler(new OnError()));
然后根据后面的代码示例进行检查:

private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
@Override
    public void run(AccountManagerFuture<Bundle> result) {
        Bundle bundle = result.getResult();
        ...
        Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT);
        if (launch != null) {
            startActivityForResult(launch, 0);
            return;
        }
    }
}
实现AccountManagerCallback的私有类{ @凌驾 公共作废运行(AccountManagerFuture结果){ Bundle Bundle=result.getResult(); ... Intent启动=(Intent)bundle.get(AccountManager.KEY\u Intent); 如果(启动!=null){ startActivityForResult(发布,0); 返回; } } } 我从来没有钥匙。我理解如下:

验证器返回意图的原因可能很多。这可能是用户首次登录此帐户。可能用户的帐户已过期,他们需要再次登录,或者他们存储的凭据不正确。可能该帐户需要双因素身份验证,或者需要启动摄像头进行视网膜扫描。原因到底是什么并不重要。如果你想要一个有效的代币,你就必须激发获得它的意图

但是,
getAuthToken
总是在代码点击
run
方法之前出现权限屏幕或登录屏幕,此时令牌有效。我试过:

  • 启用两步身份验证。在
    运行之前请求帐户登录
    ,因此始终在
    运行
    中使用令牌
  • 更改服务器上的密码。在运行
    run
    之前再次请求帐户登录,因此始终在
    run
    中使用令牌
  • 我没有能力尝试视网膜扫描,所以有点不知所措

    编辑1我遇到的问题是,在某种情况下,我可能会得到一个
    密钥意图
    ,因此我宁愿现在就测试这个代码路径,而不是当它在字段中时

    提前谢谢


    Peter。

    我想您需要调用
    getResult()
    ,如下所示:

    Intent launch = (Intent)result.getResult().get(AccountManager.KEY_INTENT);
    

    有机会在一个项目上做类似的事情。这与您的代码不完全相同,我仍然认为回调文档有太多的“可能”,无法确定它应该如何工作,但是如果您对
    notifyAuthFailure
    使用passing
    false
    ,如果您更改密码或启用2FA,您将获得重新登录屏幕的意图。这是用于ClientLogin的,但对于OAuth 2也应该是类似的(尽管未经测试)。比如:

    // using Calendar ClientLogin for simplicity
    Bundle authResult = am.getAuthToken(account, "cl", false, null, null).getResult();
    if (authResult.containsKey(AccountManager.KEY_INTENT)) {
      Intent authIntent = authResult.getParcelable(AccountManager.KEY_INTENT);
      // start activity or show notification
    }
    

    您使用的是getAuthToken版本,它使用一个活动来调用访问授权提示。该版本的getAuthToken不会返回意图,因为提供的活动用于启动相应的意图。如果要手动启动intent,请使用API级别14中不推荐使用的getAuthToken版本。有关更多信息,请参见以下内容:

    到底是什么问题?顺便说一句,你可能应该为此使用谷歌Play服务,它有更好的用户体验。更新了为什么的问题。我还没有看过Google Play服务,也没有看过我是否可以使用它来获得一个令牌,用于访问Google Cloud Print服务。在描述中有很多“可能”,所以现在完全有可能有办法强制OAuth使用它。Google Play服务支持OAuth 2令牌,因此应该适用于使用这些令牌的任何东西。不过,我还没有在打印服务中使用它。谢谢。同意如果它返回OAuth2令牌,那么访问打印服务就可以了。是的,他们的描述中有太多的“可能”,而且考虑到我测试了双因素身份验证,这与API的实际行为有些不一致。你是如何创建/检索
    aGoogleAccount
    ?感谢你的发现,我从developer.android网页复制了代码。我的实际代码确实首先调用了
    getResult()。我已经相应地更新了问题。谢谢。我会试试这个。我发现这个方法在API 14中被弃用了,但如果它能工作,至少可以让我测试我的代码路径。通过将回调设置为null,它也可以与未弃用的方法一起工作。Android上的整个弃用过程有点可笑——如果你想让你的应用程序在API 14以下的任何东西上运行,你必须使用旧的方法(至少在那些平台上)。我还没有看源代码,但两者基本上应该做相同的事情,更新的版本有更多的选项。