锁屏相关的文件在android对应package:com.android.internal.policy.impl。

phoneWindowManager.java可以派发各种物理key,如Power,Home,Vol+和Vol-等等。那么,这个类是由谁启动的?

在package下Policy.java中

public PhoneWindowManager makeNewWindowManager() {

return new PhoneWindowManager();

}

这个方法实现创建这个类。而在PolicyManager.java下调用这个方法实现对PhoneWindowManager的创建。

但是,PhoneWindowManager.java中有一个init()方法,这个是这个类的初始化方法,它调用PowerManager、windowManager、KeyguardViewMediator等等实现对PhoneWindowManager。这个Init()是在WindowManagerService.java下 的PolicyThread类下得Run方法中调用mPolicy.init(mContext, mService, mPM)。

PhoneWindowManager.java这个类是非常重要的,这里注册了一个Orientation变化的监听类:

MyOrientationListener extends WindowOrientationListener,但是,它不能够自动进行更新,它的更新主要是依据接收广播进行的,此处大概就是JNI根据驱动获取相关Sensor消息然后发送消息。这里仅仅粗略说明在这个文件中有屏幕旋转的处理方法。

下面是锁屏的处理流程:

在PhoneWindowManager.java中:

public void systemReady() {

// tell the keyguard

mKeyguardMediator.onSystemReady();

android.os.SystemProperties.set("dev.bootcomplete", "1");

synchronized (mLock) {

updateOrientationListenerLp();

mSystemReady = true;

mHandler.post(new Runnable() {

public void run() {

updateSettings();

}

});

}

}

这个方法在开机时启动调用,然后mKeyguardMediator.onSystemReady()

在KeyGuardViewMeditor.java是一个非常重要的类,它用来响应电源键的处理(黑亮屏),查询解锁屏等等。

public void onSystemReady() {

synchronized (this) {

if (DEBUG) Log.d(TAG, "onSystemReady");

mSystemReady = true; //系统准备好了

doKeyguard(); //判断是否设定了锁

}

}

private void doKeyguard()主要功能:Enable the keyguard if the settings are appropriate.意思就是如果在Setting里面设置了密码就激活keyguard。

1.如果设置了屏幕锁,黑屏后,在onScreenTurnedOff中doKeyguard()调用一次;

2.如果有SIM卡,且设置了PIN或PUK锁,那么调用doKeyguard();

3.TIMEROUT时调用doKeyguard();

4.接收到消息;DELAYED_KEYGUARD_ACTION或者TelephonyManager.ACTION_PHONE_STATE_CHANGED可能会调用

doKeyguard().

doKeyguard()方法最后调用了showLocked();

private void showLocked() {

if (DEBUG) Log.d(TAG, "showLocked");

// ensure we stay awake until we are finished displaying the keyguard

mShowKeyguardWakeLock.acquire();

Message msg = mHandler.obtainMessage(SHOW);

mHandler.sendMessage(msg);

}

实际上就是发送消息显示SHOW

当Handler接收到SHOW这个Message时,进行相关处理:

进入KeyguardViewManager.java:

在public synchronized void show()方法中:

if (mKeyguardView == null) {

if (DEBUG) Log.d(TAG, "keyguard view is null, creating it...");

mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);

mKeyguardView.setId(R.id.lock_screen);

……

}

mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this)这个就是KeyguardViewBase创建一个KeyguardViewBase的对象,也就是管理Lock、Unlock画面的类实例。

在Setting里面设置各种锁屏之后,在按power键重新开启时会产生lock或者unlock界面,需要输入密码或者绘出Pattern等操作后才能进入界面。这个锁定和解锁界面是由LockPatternKeyguardView这个类实现的。下面便是这个class的构造函数。

public LockPatternKeyguardView(

Context context,

KeyguardUpdateMonitor updateMonitor,

LockPatternUtils lockPatternUtils,

KeyguardWindowController controller)

重要实现:

mConfiguration = context.getResources().getConfiguration();

这个函数是用来获取系统的一些配置,在此用来决定是横屏还是竖屏。

mMode = getInitialMode();

这个则是获取系统的mode了。

mMode是这样的类型:

enum Mode {

LockScreen,

UnlockScreen

}

可以初步判断是lock还是unlock状态的flag枚举。获取这个状态是非常重要的,它决定初始化时究竟是显示unlock 界面还是lock界面。

private Mode getInitialMode() {

boolean isPukRequired = false;

for (int i = 0; i < TelephonyManager.getPhoneCount(); i++) {

isPukRequired = isPukRequired || isSimPukLocked(i);

if (isPukRequired) break;

}

//这里是判断sim是否加入PUK锁或者sim卡不存在

if (stuckOnLockScreenBecauseSimMissing() || isPukRequired) {

return Mode.LockScreen;

} else {

// Show LockScreen first for any screen other than Pattern unlock.

final boolean usingLockPattern =

mLockPatternUtils.getKeyguardStoredPasswordQuality()== DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;

if (isSecure() && usingLockPattern) {

return Mode.UnlockScreen;

} else {

return Mode.LockScreen;

}

}

}

对于isSecure这个函数,定义如下:

private boolean isSecure() {

UnlockMode unlockMode = getUnlockMode();

boolean secure = false;

switch (unlockMode) {

case Pattern:

secure = mLockPatternUtils.isLockPatternEnabled();

break;

case SimPin:

for (int i = 0; i < TelephonyManager.getPhoneCount(); i++) {

// Check if subscription is PIN/PUK locked.

// isPinLocked returns true if the state is PIN_REQUIRED/PUK_REQUIRED.

secure = secure || getSimState(i).isPinLocked();

if (secure) break;

}

break;

case Account:

secure = true;

break;

case Password:

secure = mLockPatternUtils.isLockPasswordEnabled();

break;

default:

throw new IllegalStateException("unknown unlock mode " + unlockMode);

}

return secure;

很显然是判断,是否设置了解锁屏方式。是则返回true,否则false。

而usingLockPattern是判断是否是用pattern模式的。具体判断后面研究。

在获取相关初始状态后,就是一些回调函数的实现:

mKeyguardScreenCallback = new KeyguardScreenCallback(),这个是十分容易解决的。

在之后是:

// create both the lock and unlock screen so they are quickly available

// when the screen turns on

mLockScreen = createLockScreen();

addView(mLockScreen);

final UnlockMode unlockMode = getUnlockMode();

if (DEBUG) Log.d(TAG,

"LockPatternKeyguardView ctor: about to createUnlockScreenFor; mEnableFallback="

+ mEnableFallback);

mUnlockScreen = createUnlockScreenFor(unlockMode);

mUnlockScreenMode = unlockMode;

maybeEnableFallback(context);

addView(mUnlockScreen);

updateScreen(mMode);

由注释可知:其实就是创建lock和unlock界面,这样切换时就可以直接显示而不必先创建在切换,造成时间的缓冲。那么究竟显示lock还是unlock界面就是最后那个调用。具体函数:

private void updateScreen(final Mode mode) {

if (DEBUG_CONFIGURATION) Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode

+ " last mode=" + mMode, new RuntimeException());

mMode = mode;

// Re-create the unlock screen if necessary. This is primarily required to properly handle

// SIM state changes. This typically happens when this method is called by reset()

if ((mode == Mode.UnlockScreen && mCurrentUnlockMode != getUnlockMode()) ||

(getUnlockMode() == UnlockMode.SimPin)) {

recreateUnlockScreen();

}

final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;

final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;

// do this before changing visibility so focus isn't requested before the input

// flag is set

mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());

if (DEBUG_CONFIGURATION) {

Log.v(TAG, "Gone=" + goneScreen);

Log.v(TAG, "Visible=" + visibleScreen);

}

if (mScreenOn) {

if (goneScreen.getVisibility() == View.VISIBLE) {

((KeyguardScreen) goneScreen).onPause();

}

if (visibleScreen.getVisibility() != View.VISIBLE) {

((KeyguardScreen) visibleScreen).onResume();

}

}

goneScreen.setVisibility(View.GONE);

visibleScreen.setVisibility(View.VISIBLE);

requestLayout();

if (!visibleScreen.requestFocus()) {

throw new IllegalStateException("keyguard screen must be able to take "

+ "focus when shown " + visibleScreen.getClass().getCanonicalName());

}

}

这里mMode = mode;之后

final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;

final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;

很显然,这是根据mode决定显示lock还是unlock的。

关于在Unlock界面输入错误密码的提示流程:

当用户输入密码时,若不正确,此时就会报告错误:

在PasswordUnlockScreen.java中有一个函数verifyPasswordAndUnlock,如下:

private void verifyPasswordAndUnlock() {

String entry = mPasswordEntry.getText().toString();

if (mLockPatternUtils.checkPassword(entry)) {

mCallback.keyguardDone(true);

mCallback.reportSuccessfulUnlockAttempt();

} else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) {

mCallback.reportFailedUnlockAttempt();

//在这里,也就是输入次数是5的整数倍时,弹出报错对话框:

if (0 == (mUpdateMonitor.getFailedAttempts()

% LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {

long deadline = mLockPatternUtils.setLockoutAttemptDeadline();

handleAttemptLockout(deadline);

}

}

mPasswordEntry.setText("");

}

那么这个错误如何显示的?

上面代码有一处: mCallback.reportFailedUnlockAttempt()

reportFailedUnlockAttempt()函数是在LockPatternKeyguardView.java中,

public void reportFailedUnlockAttempt() {

mUpdateMonitor.reportFailedAttempt();

final int failedAttempts = mUpdateMonitor.getFailedAttempts();

final boolean usingLockPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()

== DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;

if (usingLockPattern && mEnableFallback && failedAttempts ==

(LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET

- LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {

showAlmostAtAccountLoginDialog();

} else if (usingLockPattern && mEnableFallback

&& failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {

mLockPatternUtils.setPermanentlyLocked(true);

updateScreen(mMode);

} else if ((failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)

== 0) {

showTimeoutDialog();

}

mLockPatternUtils.reportFailedPasswordAttempt();

}

showAlmostAtAccountLoginDialog和showTimeoutDialog()决定显示什么样的Message:

private void showTimeoutDialog() {

//Get time to lock screen

int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;

//Announce a message

String message = "";

//Get unlock mode

UnlockMode unlockMode = getUnlockMode();

if (unlockMode  == UnlockMode.password) {

message = mContext.getString(

R.string.lockscreen_too_many_failed_attempts_dialog_message,

mUpdateMonitor.getFailedAttempts(),

timeoutInSeconds);

}

else {

message = mContext.getString(

R.string.lockscreen_too_many_failed_attempts_dialog_message,

mUpdateMonitor.getFailedAttempts(),

timeoutInSeconds);

}

final AlertDialog dialog = new AlertDialog.Builder(mContext)

.setTitle(null)

.setMessage(message)

.setNeutralButton(R.string.ok, null)

.create();

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);

if (!mContext.getResources().getBoolean(

com.android.internal.R.bool.config_sf_slowBlur)) {

dialog.getWindow().setFlags(

WindowManager.LayoutParams.FLAG_BLUR_BEHIND,

WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

}

dialog.show();

}

android 锁屏界面处理相关推荐

  1. android锁屏界面快捷键,Funtouch新特性 锁屏快捷键可以自定义

    凤凰数码讯 5月1日 vivo的Funtouch OS系统日前曝出新特性,用户可以自定义锁屏快捷键,大大提升了锁屏界面的易用性. 中关村在线消息,由于设计风格华丽.UI特色鲜明,vivo基于Andro ...

  2. android 锁屏显示音乐播放器,Android锁屏界面控制音乐播放

    目前,在锁屏界面控制音乐播放有两种常用方式. 第一种方式:原生Android系统及自带音乐播放器. 锁屏界面端: 原生Android中,锁屏界面相关的UI由KeyguardHostView提供,Key ...

  3. android 锁屏界面弹出qq,Android锁屏状态下弹出activity,如新版qq的锁屏消息提示

    Android锁屏状态下弹出activity,如新版qq的锁屏消息提示 发布时间:2020-06-26 21:27:13 来源:51CTO 阅读:1643 作者:lp5345 在接收消息广播的onRe ...

  4. Android 锁屏界面自定义

    1.创建个Activity <activity android:excludeFromRecents="true"android:exported="false&q ...

  5. android 锁屏 home,android 锁屏界面禁用长按home 和menu(recent apps)

    android 5.1 系统中 public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int polic ...

  6. Android锁屏界面监听按键,Android 监听锁屏/开屏事件

    1. 两种方案 (1) 监听BroadcastReceiver (2)获取PowerManager事件 2.  BroadcastReceiver 2.1. 事件 总共有3个事件: Intent.AC ...

  7. android 锁屏界面 sim卡,注意!手机的这个密码比锁屏密码更重要,赶紧设置!攻略→...

    视频加载中,请稍候... 自动播放 近日,一名网友分享了自己的亲身经历,因为手机被盗,不法分子通过手机上的App,窃取他的个人信息,进而申请网贷,造成财产损失.该文章通过互联网大量转发,引发网民对手机 ...

  8. android锁屏显示应用程序,今日应用:微软又给 Android 做了一款锁屏应用

    微软又做了一款 Android 锁屏应用,质量还不错.如果你已经设置了锁屏,Picturesque可能让你再解锁一次你真的需要在锁屏就处理这么多任务吗? 微软又来给 Android 提供应用了,他们昨 ...

  9. android 原生分享界面_手机资讯:省时省力!直接在锁屏界面打开应用App

    如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多知识的,这些知识很多小伙伴一般都是不知道的,就好比最近就有很多小伙伴们想要知道省时省力!直接在锁屏界面打开应用App,那么既然现 ...

最新文章

  1. 计算机设备板块超跌,半导体全线拉升,沪指强势突破3600点,午后A股会再次冲高回落吗...
  2. Hadoop vs Spark性能对比
  3. 《梦断代码》阅读笔记01
  4. lstm中look_back的大小选择_基于机器学习检测僵尸网络中的域名生成算法
  5. 关于10g RAC监听设置,tnsnames.ora设置,VIP及客户端配置问题
  6. android调用oncreate,Android - 每次启动时都会调用onCreate
  7. mysql数据库实战_主题:MySQL数据库操作实战
  8. pytorch测试用例(查看tensor维度)
  9. Linux常见目录含义及功能
  10. C++ 限定名称查找
  11. 我为什么要放弃RESTful,选择拥抱GraphQL?
  12. Managing Configuration Data Programmatically in ASP.NET 2.0
  13. 用微信名片制作软件打造专属的电子名片
  14. 【犯二记录】链表结点换位引发的思维僵化,太可怕,智商 == 0
  15. 通过任意数量点拟合曲线
  16. zblog php 调用缩略图,zblog调用文章缩略图的方法
  17. 关于 移动硬盘数据丢失问题 的解决方法
  18. 计算机用鼠标画图,在电脑上用鼠标画画用那个软件好
  19. Network Battery for mac(实时网速显示和电池健康) 教程
  20. SQL语言_3 模糊查询和聚合函数

热门文章

  1. java,输入一个数字n,以等边三角形输出1到n。
  2. win7优化大师_Win7设置某个用户自动登录的方法
  3. 7.1. 布朗运动-定义和构造(Durrett)答案
  4. 孔子怀疑徒弟(zt)
  5. JavaEE - 面向对象-构造方法、封装、类加载过程
  6. vue(4) - 收藏集 - 掘金
  7. 苹果相关链接和联系方式
  8. 不一样的精巧:高级机械原理——全动画图解
  9. 【Node.js实战】一文带你开发博客项目(使用假数据处理)
  10. 【招聘·杭州】长亭科技-golang 研发工程师