Android 8.0 - AccountManager之行为变更

Android 8.0 - AccountManager之权限变更

      • 获取系统帐号的接口:
      • 获取系统帐号的权限
        • 条件 1:
        • 条件 2:
        • 条件 3:
        • 条件 4:
        • 其他解决方案
      • 写在最后:

获取系统帐号的接口:

//获取帐号列表/或对应帐号类型的某个帐号
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).

条件 1:

targetSdkVersion<26,判断逻辑和8.0之前的判断逻辑是一样的,会检查***Manifest.permission.GET_ACCOUNTS***的权限(Android6.0及以上是运行时权限,需动态申请)

条件 2:

有权限***Manifest.permission.GET_ACCOUNTS_PRIVILEGED***,只有priv/app目录下的app声明之后才会授予此权限 (不管targetSdkVersion<26,还是>=26,有此权限,都有getAccountsXXX的权限 )

条件 3:

和注册此帐号类型的authenticator app签名一致(同第二种情况,与targetSdkVersion无关,只要签名一致,即可在8.0的机器上有权限调用getAccountsXXX)

条件 4:

caller app有权限***Manifest.permission.READ_CONTACTS***,该accountType的authenticator app要有***Manifest.permission.WRITE_CONTACTS***(这两个都是dangerous permission,需要动态申请)
根据Requesting Permissions才发现,read contacts,write contacts和get account这三个权限是属于同一个权限组的
Android 8.0 - AccountManager之行为变更_第1张图片

其他解决方案

如果上面四个条件你都不满足,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显示给用户的弹窗样式如下:
Android 8.0 - AccountManager之行为变更_第2张图片

写在最后:

其实一般情况下,单个app开发不会遇到这个问题,同公司相同签名的系列app,帐号互通sso登录也不会遇到此问题。。。
开发过程中之所以会遇到此情况,是因为公司产品比较多,属于不同部门各自独立研发,但又无属于公司级别的签名,只能每个部门自己管理自己的签名,其中帐号虽属于基础部门,但也是独立签名,真心建议初始开发时可以把app签名问题作为评估考量之列

你可能感兴趣的:(android)