//获取帐号列表/或对应帐号类型的某个帐号
AccountManager#getAccounts()/getAccountsByType(String accountType)
如果你的工程运行在Android 8.0(SDK version 26)的机器上,满足下面任意一个条件,你都仍然可以获取到系统帐号
1. Target API level below O and have deprecated GET_ACCOUNTS permission.
2. Have GET_ACCOUNTS_PRIVILEGED permission.
3. Have the same signature as authenticator.
4. Have READ_CONTACTS permission and account type may be associated with contacts data - (verified by WRITE_CONTACTS permission check for the authenticator).
targetSdkVersion<26,判断逻辑和8.0之前的判断逻辑是一样的,会检查***Manifest.permission.GET_ACCOUNTS***的权限(Android6.0及以上是运行时权限,需动态申请)
有权限***Manifest.permission.GET_ACCOUNTS_PRIVILEGED***,只有priv/app目录下的app声明之后才会授予此权限 (不管targetSdkVersion<26,还是>=26,有此权限,都有getAccountsXXX的权限 )
和注册此帐号类型的authenticator app签名一致(同第二种情况,与targetSdkVersion无关,只要签名一致,即可在8.0的机器上有权限调用getAccountsXXX)
caller app有权限***Manifest.permission.READ_CONTACTS***,该accountType的authenticator app要有***Manifest.permission.WRITE_CONTACTS***(这两个都是dangerous permission,需要动态申请)
根据Requesting Permissions才发现,read contacts,write contacts和get account这三个权限是属于同一个权限组的
如果上面四个条件你都不满足,AccountManager还提供里另外两个接口:通过authenticator app给你的app设置帐号可见性,你就可以获取到帐号了
/**
* 返回用户选择授予获取帐号的弹窗Intent
*/
static public Intent newChooseAccountIntent(Account selectedAccount,
ArrayList allowableAccounts,
String[] allowableAccountTypes,
String descriptionOverrideText,
String addAccountAuthTokenType,
String[] addAccountRequiredFeatures,
Bundle addAccountOptions)
/**
* 将某个帐号对特定包名可见性(允许/拒绝)
* 只有和account的authenticator app签名一致才能调用此接口
*/
public boolean setAccountVisibility(Account account, String packageName, @AccountVisibility int visibility)
/**
* 此外,android8.0还追加下面接口,与setAccountVisibility接口相同
* 在登录成功,向AccountManager数据库中添加帐号时添加对特定包名的可见性
* 名义上,只有authenticator app才可以调用此接口
*/
public boolean addAccountExplicitly(Account account, String password, Bundle extras, Map visibility)
上述接口要么是用户来选择授权同意,要么是authenticator app给予授权,具体来说Android 8.0更加加强了用户的隐私数据安全性
newChooseAccountIntent显示给用户的弹窗样式如下:
其实一般情况下,单个app开发不会遇到这个问题,同公司相同签名的系列app,帐号互通sso登录也不会遇到此问题。。。
开发过程中之所以会遇到此情况,是因为公司产品比较多,属于不同部门各自独立研发,但又无属于公司级别的签名,只能每个部门自己管理自己的签名,其中帐号虽属于基础部门,但也是独立签名,真心建议初始开发时可以把app签名问题作为评估考量之列