转载自http://blog.csdn.net/u013656135/article/details/43274161

Andriod谷歌账号解锁功能,通常情况下不会显示,如果用户忘记密码,输错几次后会显示一个Button。如下图中FORGOT PATTERN,这是我修改以后让这个Button一直显示。触摸这个Button以后就出现一个登入画面,其中包括需要用户添些的username(gmail)和用户所添账户的密(password)。

当然要想通过账户(account)来解锁,必须先在设置中添加账户(add account)。目前Android有几种保密锁屏:Pattern、Password、PIN。

在去写代码之前,或者是看Android是怎么实现这个功能之前,心里想一下,这个功能要怎么去实现,想必都会有这样的思路(除去界面不说):

下面就图案解锁来分析一下实现过程,当然初次接触锁屏有必要看下锁屏界面的布局,如果熟悉Keyguard,自然就知道图案解锁的View 在KeyguardPatternView.java中。要看图案解锁 此时锁屏的布局,当然用hierarchyviewer.bat 来查看布局比较方便,左右对比很容易看出控件锁在的View,如图:

从上图中找到com.android.keyguard.KeyguardPatternView,然后直接找到KeyguardPatternView.java文件开始分析。

1、通过Button控件 显示login 界面:

[html] view plain copy

  1. mForgotPatternButton = (Button) findViewById(R.id.forgot_password_button);
  2. // note: some configurations don't have an emergency call area
  3. if (mForgotPatternButton != null) {
  4. mForgotPatternButton.setText(R.string.kg_forgot_pattern_button_text);
  5. mForgotPatternButton.setOnClickListener(new OnClickListener() {
  6. public void onClick(View v) {
  7. mCallback.showBackupSecurity();
  8. }
  9. });
  10. }

通过Button的Click 显示Login界面,Android通过调用KeyguardSecurityCallback接口中的showBackupSecurity()函数来实现,而真正实现showBackupSecurity()函数的地方是在

KeyguardHostView.java :

[html] view plain copy

  1. private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
  2. ...
  3. @Override
  4. public void showBackupSecurity() {
  5. KeyguardHostView.this.showBackupSecurityScreen();
  6. }
  7. ...

[html] view plain copy

  1. /**
  2. * Shows the backup security screen for the current security mode. This could be used for
  3. * password recovery screens but is currently only used for pattern unlock to show the
  4. * account unlock screen and biometric unlock to show the user's normal unlock.
  5. */
  6. private void showBackupSecurityScreen() {
  7. if (DEBUG) Log.d(TAG, "showBackupSecurity()");
  8. SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection)
  9. showSecurityScreen(backup);
  10. }

最终调用的是函数showSecurityScreen(backup)而backup是SecurityMode,通过getBackupSecurityMode()赋值,来获得当前是那种安全锁屏模式。

[html] view plain copy

  1. SecurityMode getBackupSecurityMode(SecurityMode mode) {
  2. switch(mode) {
  3. case Biometric:
  4. return getSecurityMode();
  5. case Pattern:
  6. return SecurityMode.Account;
  7. }
  8. return mode; // no backup, return current security mode
  9. }

showBackupSecurityScreen()函数的说明,只为Pattern 和 Biometric 两种模式所用,看函数getBackupSecurityMode() 就知道为什么了。在showSecurityScreen()中,会通过SecurityMode去获取对应的view。

KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);

KeyguardSecurityView newView = getSecurityView(securityMode);

getSecurityView()通过SecurityMode 获取到对应的布局ID,然后对view进行加工 return 各种

SecurityMode 所需要的View.

[html] view plain copy

  1. private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
  2. ...
  3. final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
  4. ...
  5. }
  6. private int getSecurityViewIdForMode(SecurityMode securityMode) {
  7. switch (securityMode) {
  8. case None: return R.id.keyguard_selector_view;
  9. case Pattern: return R.id.keyguard_pattern_view;
  10. case PIN: return R.id.keyguard_pin_view;
  11. case Password: return R.id.keyguard_password_view;
  12. case Biometric: return R.id.keyguard_face_unlock_view;
  13. case Account: return R.id.keyguard_account_view;
  14. case SimPin: return R.id.keyguard_sim_pin_view;
  15. case Sim2Puk: return R.id.keyguard_sim_puk_view;
  16. }
  17. return 0;

而keyguard_account_view就是Login登入界面所需要的,在这里也可以肯定只有当SecurityMode = Account时才会显示Login界面,而getBackupSecurityMode函数中,只有Pattern模式才会返回Account ,所以Password 和 PIN 模式即使有FORGOT PASSWORD 也不会显示Login界面。所以要增加这两种模式显示login就要把getBackupSecurityMode()改成:

[html] view plain copy

  1. SecurityMode getBackupSecurityMode(SecurityMode mode) {
  2. switch(mode) {
  3. case Biometric:
  4. return getSecurityMode();
  5. case Pattern:
  6. case Password:
  7. case PIN:
  8. return SecurityMode.Account;
  9. }
  10. return mode; // no backup, return current security mode
  11. }

到这里Login界面分析完了,然后就是重点---解锁。

2、账号解锁:Login界面的东西,都在KeyguardAccountView.java中。

从“确定”或者“ok”Button 入手:

-> mOk = (Button) findViewById(R.id.ok);

-> mOk.setOnClickListener(this);

public void onClick(View v) {

mCallback.userActivity(0);

if (v == mOk) {

asyncCheckPassword();

}

}

触摸确认button,执行asyncCheckPassword(),异步检查账户,按照上面简单的逻辑视图,

先要获取Account,所以在asyncCheckPassword()可以看到:

Account account = findIntendedAccount(login);

[html] view plain copy

  1. private Account findIntendedAccount(String username) {
  2. Account[] accounts = AccountManager.get(mContext).getAccountsByTypeAsUser("com.google",
  3. new UserHandle(mLockPatternUtils.getCurrentUser()));
  4. // Try to figure out which account they meant if they
  5. // typed only the username (and not the domain), or got
  6. // the case wrong.
  7. Account bestAccount = null;
  8. int bestScore = 0;
  9. for (Account a: accounts) {
  10. int score = 0;
  11. if (username.equals(a.name)) {
  12. score = 4;
  13. } else if (username.equalsIgnoreCase(a.name)) {
  14. score = 3;
  15. } else if (username.indexOf('@') < 0) {
  16. int i = a.name.indexOf('@');
  17. if (i >= 0) {
  18. String aUsername = a.name.substring(0, i);
  19. if (username.equals(aUsername)) {
  20. score = 2;
  21. } else if (username.equalsIgnoreCase(aUsername)) {
  22. score = 1;
  23. }
  24. }
  25. }
  26. if (score > bestScore) {
  27. bestAccount = a;
  28. bestScore = score;
  29. } else if (score == bestScore) {
  30. bestAccount = null;
  31. }
  32. }
  33. return bestAccount;
  34. }

首先通过AccountManager 获得系统中的账号,然后遍历系统的账户,查找匹配用户输入的账户,然后将查找到的账户赋给bestaccount,如果bestaccount = null 就告知用户Fail,基本符合上面简单的逻辑图中对Account的判断。

通过asyncCheckPassword()函数了解到,不管account是否为null,都会调用postOnCheckPasswordResult()

[html] view plain copy

  1. private void postOnCheckPasswordResult(final boolean success) {
  2. // ensure this runs on UI thread
  3. mLogin.post(new Runnable() {
  4. public void run() {
  5. if (success) {
  6. // clear out forgotten password
  7. mLockPatternUtils.setPermanentlyLocked(false);
  8. mLockPatternUtils.setLockPatternEnabled(false);
  9. mLockPatternUtils.saveLockPattern(null);
  10. // launch the 'choose lock pattern' activity so
  11. // the user can pick a new one if they want to
  12. Intent intent = new Intent();
  13. intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
  14. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  15. mContext.startActivityAsUser(intent,
  16. new UserHandle(mLockPatternUtils.getCurrentUser()));
  17. mCallback.reportSuccessfulUnlockAttempt();
  18. // dismiss keyguard
  19. mCallback.dismiss(true);
  20. } else {
  21. mSecurityMessageDisplay.setMessage(R.string.kg_login_invalid_input, true);
  22. mPassword.setText("");
  23. mCallback.reportFailedUnlockAttempt();
  24. }
  25. }
  26. });
  27. }

在postOnCheckPasswordResult()函数中,如果传进来的值是false,即account=null.函数走else,通过显示一个message告诉用户目前情况。如果传进来的值是true,即account=!null.就要执行解锁功能,并跳转到指定界面。

mLockPatternUtils.setPermanentlyLocked(false);

mLockPatternUtils.setLockPatternEnabled(false);

mLockPatternUtils.saveLockPattern(null);

这就是解锁,但只有图案解锁,把图案密码设置为null。这也就导致password 和 PIN 不能解锁。所以为了这两种方式也能解锁,需要在这里增加:

mLockPatternUtils.saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);

或者直接改成mLockPatternUtils.clearLock(success);

如果不确定password 和 PIN 两种模式是不是这样解锁的,可以跟一下在设置里面输入密码确认时设置里面是如何执行解锁的。

Intent intent = new Intent();

intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

mContext.startActivityAsUser(intent,

new UserHandle(mLockPatternUtils.getCurrentUser()));

跳转选择锁屏的界面。当然也不一定非要跳转的到这个界面,这里这么做的主要意思是为了在解锁以后方便用户再次选择选择锁屏方式。当然不选也没关系,直接返回桌面,系统会默认将锁屏设置为滑动锁屏。

至此,Android账户解锁大致流程就是如此。

PS:忘了一个地方,Pattern 界面FORGOT 的Button 如果要一直都显示,可看KeyguardPatternView.java中的函数updateFooter()。这里是控制Button是否显示的地方。

Android的本意是:如果用户忘记密码,可以尝试几次,如果在规定的次数内仍不能解锁,就会显示FORGOT button,允许用户通过账户解锁。

Andriod谷歌账号解锁功能相关推荐

  1. 谷歌浏览器登录不了账号_谷歌浏览器使用分享(可谷歌账号登录)之谷歌账号登录...

    由于谷歌退出中国市场以及中国网络安全法规的限制,中国大陆用户无法访问谷歌服务器,也不能使用其提供的应用,所以我们需要下载一个插件(集装箱),借此来登录谷歌账号. 1.直接网页搜索"集装箱&q ...

  2. 最新注册谷歌账号遇到此号码无法验证的解决办法_看我如何成功注册gmail

    许多朋友注册谷歌账号的时候遇上手机号无法验证的问题,那到底怎么才能注册谷歌Gmail邮箱呢?其实自己的手机号是可以成功注册验证谷歌的,不用想着用外国手机号申请,也不要用虚拟运营商的手机号,都是无法通过 ...

  3. java实现用户登录异常统计、锁定及解锁功能

    写在前面 现在很多互联网项目.app等都会有登录异常提醒.登录异常次数限制,基本都是5次异常后就会锁定一定时间的账户,让该账户无法进行登录操作.需要注册用户使用安全验证手段(如动态验证码等),解除锁定 ...

  4. Android11.0 增加人脸解锁功能

    一.Settings 模块修改 从 Q 版本开始 aosp 代码就已经默认支持 Biometric 生物识别相关功能,Settings 中不显示入口菜单是因为判断了 硬件是否支持.可以先看下安全页面中 ...

  5. 如何利用谷歌邮箱别名功能获取无限 Gmail 邮箱

    公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你玩转 Linux ! 我们注册有些国外的服务时,是不能用国内邮箱注册的,这时一个 Gmail 邮箱就显得很有必要.而有时候我们会需要注册 ...

  6. 极客日报:吉利回应收购魅族手机传闻;​苹果要求App必须内置账号删除功能;英特尔斥资千亿美元打造全球最大芯片基地

    一分钟速览新闻点! 吉利回应收购魅族手机传闻 泰国AreuOK队赢得华为科技挑战赛金奖 华为2022年第一位天才少年诞生 微信支付推出虎年限量红包封面,"虎豆妞"送祝福 有赞回应裁 ...

  7. 谷歌账号登录twitter_Google会购买Twitter吗?

    谷歌账号登录twitter The latest rumor to circulate the Internet is that Google is in the final stages of ne ...

  8. 谷歌广告账号注册很难?请收下这篇谷歌账号注册指南

    做跨境电商这一行业的,相信都会去了解谷歌广告账户.Google广告是Google的广告平台,一般在用户使用引擎搜索的时候推送.为什么大家都要去开通Google广告账户呢?因为Google广告能够快速提 ...

  9. 现在申请Android Auto认证,没有谷歌账号可以吗?

    现在申请Android Auto认证,没有谷歌账号可以吗? 一定需要谷歌账号.如果是第一次申请,前装项目可以叫车厂配合申请账号. Android Auto是Google推出的专为汽车所设计之Andro ...

最新文章

  1. [iOS]MVVM-框架介绍
  2. mysql5.7.25源码安装_源码编译安装 mysql5.7.25
  3. 你说我做丨为你定制「大局观版」职场设计课
  4. Java怎么在if输出中进行运算_磕代码:c/c++/java:输入三个整数,输出运算结果;if条件句的使...
  5. 网络知识:电脑无线网连接不上问题汇总!
  6. MATLAB基础教程(5)——斐波那契数列
  7. JavaScript循环及练习
  8. [WP8] ListBox的Item宽度自动填满
  9. 关联规则完整源代码_接口测试:A06_HttpRunner关联_02_提取 SessionID:固定名称方式...
  10. php打印机 纸张大小,打印设置信息中的纸张类型,如何取自定义纸张!
  11. python游戏程序代码大全_python小游戏代码,python小游戏代码大全打枪
  12. 电气专业学校排名全国计算机专业学校排名,电气工程及其自动化专业学校排名...
  13. rubyonrails test 小记
  14. 阳历时间转换为农历时间
  15. BlowFish算法Java实现
  16. [SSL_CHX][2021-8-18]角谷猜想
  17. 香港服务器怎么加速?
  18. 手机尾号(%d的深度使用)
  19. 单片机定时器计数原理
  20. Linux | CentOS系统时钟校正

热门文章

  1. 蓝鲸智云部署过程中问题汇总
  2. 百度算法大全:更新至2121年
  3. PostgreSQL登录及修改密码
  4. 实验六 Biopython-1
  5. 图像的高频信息和低频信息的含义
  6. 图像低频、高频信息的理解
  7. 英读廊——尬跑一英里
  8. 数学建模Word排版——样式
  9. 车辆识别号(VIN)验证
  10. linux kfifo的使用