我们有个方法,是判断系统的账号有没有登录。

public static boolean isAccountLogin(Context context) {String df = "com.z**;AccountManager accountManager = AccountManager.get(context);try {Account[] accounts = accountManager.getAccountsByType(df);if (accounts != null && accounts.length > 0) {Account account = accounts[0];SDKLogUtils.d("PackageUtils", account.toString());if (account != null) {return true;}} else {SDKLogUtils.d("PackageUtils", "com.ztemt account is null");}} catch (Exception var5) {var5.printStackTrace();}return false;}

这个在8.0以前的手机,完全没问题。但是8.0就有问题。而且改一下target 版本到8.0才有问题。

赶紧查一下。果然8.0变更了。https://developer.android.com/about/versions/oreo/android-8.0-changes.html

Apps targeting Android 8.0 这个是target 提到8.0以后才需要注意的
These behavior changes apply exclusively to apps that are targeting Android 8.0 (API level 26) or higher. Apps that compile against Android 8.0, or set targetSdkVersion to Android 8.0 or higher must modify their apps to support these behaviors properly, where applicable to the app.
Account access and discoverability
In Android 8.0 (API level 26), apps can no longer get access to user accounts unless the authenticator owns the accounts or the user grants that access. The GET_ACCOUNTS permission is no longer sufficient. To be granted access to an account, apps should either use AccountManager.newChooseAccountIntent() or an authenticator-specific method. After getting access to accounts, an app can can call AccountManager.getAccounts() to access them.
Android 8.0 deprecates LOGIN_ACCOUNTS_CHANGED_ACTION. Apps should instead use addOnAccountsUpdatedListener() to get updates about accounts during runtime.

For information about new APIs and methods added for account access and discoverability, see Account Access and Discoverability in the New APIs section of this document.

OK,下载下来8.0的代码,看下

    public Account[] getAccountsByType(String type) {return getAccountsByTypeAsUser(type, Process.myUserHandle());}
    /** @hide Same as {@link #getAccountsByType(String)} but for a specific user. */@NonNullpublic Account[] getAccountsByTypeAsUser(String type, UserHandle userHandle) {try {return mService.getAccountsAsUser(type, userHandle.getIdentifier(),mContext.getOpPackageName());} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
    private final IAccountManager mService;

这个Service 是个啥?
我也不知道,用SourceInsight 全局搜一下getAccountsAsUser 这个方法的实现吧。好吧,没收到。
看了别人的,说是:AccountManagerService,可能是sdk 源码不全

OK,继续
最终会调用到这里:

/*** Method which handles default values for Account visibility.** @param account The account to check visibility.* @param packageName Package name to check visibility* @param accounts UserAccount that currently hosts the account and application** @return Visibility value, the method never returns AccountManager.VISIBILITY_UNDEFINED**/private Integer resolveAccountVisibility(Account account, @NonNull String packageName,UserAccounts accounts) {Preconditions.checkNotNull(packageName, "packageName cannot be null");int uid = -1;try {long identityToken = clearCallingIdentity();try {uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);} finally {restoreCallingIdentity(identityToken);}} catch (NameNotFoundException e) {Log.d(TAG, "Package not found " + e.getMessage());return AccountManager.VISIBILITY_NOT_VISIBLE;}// System visibility can not be restricted.if (UserHandle.isSameApp(uid, Process.SYSTEM_UID)) {return AccountManager.VISIBILITY_VISIBLE;}int signatureCheckResult =checkPackageSignature(account.type, uid, accounts.userId);// Authenticator can not restrict visibility to itself.if (signatureCheckResult == SIGNATURE_CHECK_UID_MATCH) {return AccountManager.VISIBILITY_VISIBLE; // Authenticator can always see the account}// Return stored value if it was set.int visibility = getAccountVisibilityFromCache(account, packageName, accounts);if (AccountManager.VISIBILITY_UNDEFINED != visibility) {return visibility;}boolean isPrivileged = isPermittedForPackage(packageName, uid, accounts.userId,Manifest.permission.GET_ACCOUNTS_PRIVILEGED);// Device/Profile owner gets visibility by default.if (isProfileOwner(uid)) {return AccountManager.VISIBILITY_VISIBLE;}boolean preO = isPreOApplication(packageName);if ((signatureCheckResult != SIGNATURE_CHECK_MISMATCH)|| (preO && checkGetAccountsPermission(packageName, uid, accounts.userId))|| (checkReadContactsPermission(packageName, uid, accounts.userId)&& accountTypeManagesContacts(account.type, accounts.userId))|| isPrivileged) {// Use legacy for preO apps with GET_ACCOUNTS permission or pre/postO with signature// match.visibility = getAccountVisibilityFromCache(account,AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE, accounts);if (AccountManager.VISIBILITY_UNDEFINED == visibility) {visibility = AccountManager.VISIBILITY_USER_MANAGED_VISIBLE;}} else {visibility = getAccountVisibilityFromCache(account,AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, accounts);if (AccountManager.VISIBILITY_UNDEFINED == visibility) {visibility = AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE;}}return visibility;}

只有这里返回对你可见,那么你才能访问账户。
1.signatureCheckResult != SIGNATURE_CHECK_MISMATCH 同签名
2.preO && checkGetAccountsPermission(packageName, uid, accounts.userId)
target 大于android O 并且有GetAccounts 权限
3.checkReadContactsPermission(packageName, uid, accounts.userId)
&& accountTypeManagesContacts(account.type, accounts.userId)
当前的包名有 ReadContacts 权限,并且 授予账号的包,有Manifest.permission.WRITE_CONTACTS的权限
4. 享有特权的, 即 有GET_ACCOUNTS_PRIVILEGED权限

总结:
1.源码大概了解意思就行,不必每个东西都弄懂。
2.一遍看不懂,或者没有看到关键,多看几遍。
3.使用SourceInSight
4.要时时关注最新的动态,不要改了东西,自己不知道。遇到问题了,去百度。看别人的博客。才知道怎么解决。

参考:
https://blog.csdn.net/gdutxiaoxu/article/details/80099717

android 8.0 Account行为变更 账号系统相关推荐

  1. Android 8.0学习(25)---系统的应用图标适配

    Android 8.0系统的应用图标适配 现在已经进入了2018年,Android 8.0系统也逐渐开始普及起来了.三星今年推出的最新旗舰机Galaxy S9已经搭载了Android 8.0系统,紧接 ...

  2. Android 4.0 事件输入(Event Input)系统

    1. TouchScreen功能在Android4.0下不工作 原来在Android2.3.5下能正常工作的TouchScreen功能,移植到Android 4.0就不能正常工作了.凭直觉,Andro ...

  3. android 12.0 第三方输入法app设置系统默认输入法

    1.概述 在12.0的产品开发中,有功能需要要求设置默认输入法,替换掉系统的输入法,所以这就需要了解设置输入法的相关功能需求,然后根据输入法包名来设置默认输入法 2.第三方输入法app设置系统默认输入 ...

  4. Android 10.0 framework设备联网后系统时间没有自动同步更新的修改

    1.概述 在定制化10.0的产品开发中,在产品联网后系统都会自动同步时间,但在一些产品中,会出现即使联网了也不会同步时间的情况,开始以为是设备的网络问题,咨询同事和百度发现谷歌服务器会出现在大陆时间同 ...

  5. android 10.0 第三方输入法app设置系统默认输入法

    目录 1.概述 2.第三方输入法app设置系统默认输入法的核心类

  6. Android 6.0 7.0 8.0特性变更

    Android 6.0 变更 本文内容 运行时权限 低电耗模式和应用待机模式 取消支持 Apache HTTP 客户端 BoringSSL 硬件标识符访问权 通知 音频管理器变更 文本选择 浏览器书签 ...

  7. Android 2.0 --- 2.3 API变更概要:

    Android 2.0 API变更概要: 1.Bluetooth · 开启关闭蓝牙 · 设备和服务发现 · 使用 RFCOMM连接一个可插拔的设备收发数据 · 公布RFCOMM 服务和监听接收 RFC ...

  8. android 8.0 行为变更--day03

    Android 8.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更.本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更. 其中大部分变更会影响所有应用,而不论应用针对的 ...

  9. Android 7.0 行为变更 通过FileProvider在应用间共享文件吧

    本文转自张鸿洋的博客 http://blog.csdn.net/lmj623565791/article/details/72859156 一.概述 之前项目的新特性适配工作都是同事在做,一直没有怎么 ...

最新文章

  1. app如何打开了request url_手机日历app内如何打开节日提醒功能?支持提前提醒节日的云便签...
  2. Java三大主流框架概述
  3. 无导师学习_如何找到一位导师并加快学习速度:新手指南。
  4. 华为存储S58000T-硬盘更换
  5. JavaScript ES2015
  6. MIT自然语言处理第五讲:最大熵和对数线性模型
  7. 授于某个用户有写作业和调度作业的权限
  8. Java微服务:蛋糕是骗人的,但您不能忽略它
  9. 《Python Cookbook 3rd》笔记(5.5):文件不存在才能写入
  10. probe request帧结构_WLAN 无线网络 09 - 管理帧
  11. 在 F5 LTM 上配置数据包过滤
  12. UI设计素材字体|三明治3D文字效果– 3个角度
  13. 【VB】StrConv函数.
  14. .html() 与.text() 获取值、取值 区别
  15. WebStorm中常用的快捷键及使用技巧
  16. 计算机安装重装出现错误,一键重装失败怎么办?电脑重装系统失败的原因和解决方法...
  17. [落选]狗熊会人才计划第6期选拔作业
  18. 微信api接口调用-发朋友圈
  19. LeetCode——复数乘法 C++
  20. Codeforces-85D Sum of Medians

热门文章

  1. android如何查看分区信息,android如何查看分区信息
  2. java随机生成不重复的数组_Java生成不重复的随机数组的方法
  3. CUDA学习-计算实际线程ID
  4. 暑假爆零欢乐赛SRM08题解
  5. 关闭/开启 ubuntu 自动更新提示
  6. IOS性能调优系列:使用Time Profiler发现性能瓶颈
  7. [算法][递归] 棋盘覆盖
  8. Java时间操作工具类
  9. php中文乱码问题解决方案
  10. dojo helloworld