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

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. */
@NonNull
public 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 4.0 事件输入(Event Input)系统

    参考:http://blog.csdn.net/myarrow/article/details/7091061 1. TouchScreen功能在Android4.0下不工作 原来在Android2. ...

  2. android 8.0变更

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

  3. Android 6.0权限全面详细分析和解决方案

    原文: http://www.2cto.com/kf/201512/455888.html http://blog.csdn.net/yangqingqo/article/details/483711 ...

  4. Android 6.0 Permission权限与安全机制

    Marshmallow版本权限修改 android的权限系统一直是首要的安全概念,因为这些权限只在安装的时候被询问一次.一旦安装了,app可以在用户毫不知晓的情况下访问权限内的所有东西,而且一般用户安 ...

  5. Android 9.0更新

    北京时间2018年8月7日上午,Google 发布了 Android 9.0 操作系统.并宣布系统版本 Android P 被正式命名为代号"Pie". Android 9.0 利 ...

  6. Android 7.0 新增功能和api

    Android 7.0 Nougat 为用户和开发者引入多种新功能.本文重点介绍面向开发者的新功能. 请务必查阅 Android 7.0 行为变更以了解平台变更可能影响您的应用的领域. 要详细了解 A ...

  7. Android 6.0权限

    在android 6.0 Marshmallow版本之后,系统不会在软件安装的时候就赋予该app所有其申请的权限,对于一些危险级别的权限,app需要在运行时一个一个询问用户授予权限. 只有那些targ ...

  8. android studio2.0出现的gradle问题,instant Run即时运行不了.

    android studio 2.0出现的gradle问题: instant Run即时运行不了.经历了几乎9个preView版本的AS2.0,终于迎来了正式版,然而晴天我的霹雳,好不容易装好的2.0 ...

  9. Nexus5 电信3G保留数据和Root升级Android 6.0

    前提: A 备份手机重要数据,安全第一 B 进入twrp recovery 备份EFS,建议最好拷贝到电脑上(如果没有twrp,则需要先刷twrp,具体指令请看下面步骤第10条) C 因为Androi ...

随机推荐

  1. MySQL数据库------常用函数

    一.数学函数 数学函数主要用于处理数字,包括整型.浮点数等. [1]ABS(x)        返回x的绝对值 例子:SELECT ABS(-1) -- 返回1 [2]CEIL(x),CEILING( ...

  2. jquery基础介绍-转

    学习目的:理解 Ajax 及其工作原理,构建网站的一种有效方法. Ajax 是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写. 下面是 Ajax 应用程 ...

  3. Enum介绍

    public enum Color { RED, YELLOW, BLUE; } 说明: 使用的是enum关键字而不是class 多个枚举变量之间用 逗号 隔开 枚举变量名大写,多个单词之间用 _ 隔 ...

  4. byte转换字符串(string)+字符串转换byte

    C# 中字符串string和字节数组byte[]的转换 //string转byte[]: byte[] byteArray = System.Text.Encoding.Default.GetByte ...

  5. 【题解】洛谷P4281 [AHOI2008] 紧急集合(求三个点LCA)

    洛谷P4281:https://www.luogu.org/problemnew/show/P4281 思路 答案所在的点必定是三个人所在点之间路径上的一点 本蒟蒻一开始的想法是:先求出2个点之间的L ...

  6. 嵌入式 Linux 学习 之路

    1. 嵌入式 Linux  (首先百度了一下) 结果没有 看到 有信息的内容.2017年2月17日10:06:51 (嵌入式Linux 英文名:embedded Linux 简称 eLinux,Git ...

  7. SecureCRT连接主机时(串口/网络),无法从键盘输入

    Session Option-Connection-Serial-Flow Control,里面的选项全部取消掉,再重启CRT就ok了...

  8. Java中,如何跳出当前的多重嵌套循环

    在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环.(Java中支持带标签的break和continue语句)

  9. JQuery给一个元素绑定两次点击事件(第二次点击事件)

    由于项目的要求,需要给复选框设置样式,初始样式:,第一次点击的时候显示,第二次点击时候需要改变该样式:. 设计思路: 当点击次数为奇数时显示带有颜色的图片 当点击次数为偶数时显示没有颜色的图片 下边是 ...

  10. 基于kafka rest实现资源访问服务化(实战)

    问题引出 新产品的体系架构包含多个模块,模块集特点是数量多.模块间交互复杂.那么统一接口是一个很好的解决方案,为了实现统一接口打算采用微服务的核心思想,设计了采用restful service的数据交 ...