Android9锁屏界面时间,Android9.0在锁屏界面Keyguard输错5次密码后倒计时30秒时重启手机不显示倒计时...

本文详细介绍了如何在Android系统中实现锁屏密码输入错误后的倒计时功能。通过分析KeyguardPatternView.java源码,重点讲述了在错误五次后启动倒计时的逻辑,包括设置休眠时间、读取和修改系统设置以及在reset()方法中触发倒计时的启动和结束。同时,提到了在不同方法中尝试触发倒计时的尝试与解决过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近解了一个bug,觉得很有意思,拿出来和大家分享一下。

锁屏密码输错五次后出现倒计时,重启设备不显示倒计时。

首先,以图案解锁为例,图案解锁的初始化和逻辑比对都在KeyguardPatternView.java中

倒计时方法用的是该类中的handleAttemptLockout(long elapsedRealtimeDeadline)方法,传入一个获取的系统休眠时间,该时间是设备启动至现在的时间,再加上你所设置的休眠时间。

long mDeadline = mLockPatternUtils.setLockoutAttemptDeadline(

KeyguardUpdateMonitor.getCurrentUser(), 30000);//传入的handleAttemptLockout的

//elapsedRealtimeDeadline就是这样设置的,30000为休眠的30秒

休眠方法知道了,我的整体思路是我在SettingsProvider里存了一个值默认0,然后在倒计时的时候将这个值置为1,倒计时结束再置为0,在KeyguardPatternView.java的每次启动方法中去读取这个值,如果是0就什么都不做,如果是1就开始倒计时。

OK,万事具备,只欠东风,就是一个KeyguardPatternView.java的每次启动都会运行的方法,刚开始我尝试在KeyguardPatternView的构造方法中去做这些事,结果一直在报 mLockPatternView空指针,大家可以观察handleAttemptLockout方法

private void handleAttemptLockout(long elapsedRealtimeDeadline) {

mLockPatternView.clearPattern();//需要清除当前图像

mLockPatternView.setEnabled(false);//设置不可点击

final long elapsedRealtime = SystemClock.elapsedRealtime();

final long secondsInFuture = (long) Math.ceil(

(elapsedRealtimeDeadline - elapsedRealtime) / 1000.0);

if (mCountdownTimer != null) {

mCountdownTimer.cancel();

}

mCountdownTimer = new CountDownTimer(secondsInFuture * 1000, 1000) {

handleAttemptLockout方法需要清除当前图像,并且设置不可点击,所以我们需要在mLockPatternView创建好后去执行这些方法,后来我又尝试在KeyguardPatternView.java的onFinishInflate()方法,但是发现它并不是每次的执行,所以也不行,最后我终于找到每次都会执行的方法就是KeyguardPatternView.java的 reset()方法,该方法每次加载PatternView都会执行

具体代码实现如下:

@Override

public void reset() {

// reset lock pattern

mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(

KeyguardUpdateMonitor.getCurrentUser()));

mLockPatternView.enableInput();

mLockPatternView.setEnabled(true);

mLockPatternView.clearPattern();

//add for count time at 2019-5-14 start 这里开始

Log.v(TAG, "reset() COUNT_DOWNTIME_UNLOCK ="+Settings.System.getInt(mContext.getContentResolver(),Settings.System.COUNT_DOWNTIME_UNLOCK,0)+"mLockPatternView = "+mLockPatternView);

if (Settings.System.getInt(mContext.getContentResolver(),Settings.System.COUNT_DOWNTIME_UNLOCK,0) == 1 && mLockPatternView != null){//这里去读取存入值

long mDeadline = mLockPatternUtils.setLockoutAttemptDeadline(

KeyguardUpdateMonitor.getCurrentUser(), 30000);这里去设置休眠时间

Log.v(TAG, "reset(inside) handleAttemptLockout(mDeadline)"+mDeadline);

}

//add for count time at 2019-5-14 end这里结束

// if the user is currently locked out, enforce it.

long deadline = mLockPatternUtils.getLockoutAttemptDeadline(

KeyguardUpdateMonitor.getCurrentUser());

if (deadline != 0) {

handleAttemptLockout(deadline);//这里执行休眠方法

} else {

displayDefaultSecurityMessage();

}

}

接着需要修改倒计时handleAttemptLockout(deadline)方法,在倒计时的时候设为1,停止的时候设置为0

private void handleAttemptLockout(long elapsedRealtimeDeadline) {

mLockPatternView.clearPattern();

mLockPatternView.setEnabled(false);

final long elapsedRealtime = SystemClock.elapsedRealtime();

final long secondsInFuture = (long) Math.ceil(

(elapsedRealtimeDeadline - elapsedRealtime) / 1000.0);

if (mCountdownTimer != null) {

mCountdownTimer.cancel();

}

mCountdownTimer = new CountDownTimer(secondsInFuture * 1000, 1000) {

@Override

public void onTick(long millisUntilFinished) {//倒计时执行的地方

final int secondsRemaining = (int) Math.round(millisUntilFinished / 1000.0);

mSecurityMessageDisplay.setMessage(mContext.getResources().getQuantityString(

R.plurals.kg_too_many_failed_attempts_countdown,

secondsRemaining, secondsRemaining));

//add for count time unlock start

Log.v(TAG, "handleAttemptLockout secondsRemaining = "+secondsRemaining);

if(secondsRemaining == 30){

Settings.System.putInt(mContext.getContentResolver(),Settings.System.COUNT_DOWNTIME_UNLOCK,1);

//在这里置为1

}

}

@Override

public void onFinish() {//倒计时结束的地方

mLockPatternView.setEnabled(true);

displayDefaultSecurityMessage();

Settings.System.putInt(mContext.getContentResolver(),Settings.System.COUNT_DOWNTIME_UNLOCK,0);

//在这里置为0

//add for count time unlock at 2019-end

}

}.start();

}

这样就结束了,因为password和pin码都继承自KeyguardAbsKeyInputView.java,所以我们只需要在KeyguardAbsKeyInputView.java做同样的修改就OK了

### 如何设置和管理 Android 设备的 PIN 码 #### 设置 PIN 码 为了增强设备的安全性,可以按照以下方法在 Android 设备上配置 PIN: 进入 **设置** 序列中的安全选项,具体路径可能因同制造商而有所变化,通常位于 `设置` -> `安全` 或者 `设置` -> `幕和安全性` 中找到 “设定PIN码” 的入口[^1]。 在此过程中,系统可能会要求先验证当前存在的任何其他形式的身份验证手段(比如图案或现有密码),随后引导创建一个新的四位数以上的个人识别号码作为新的解凭证。完成设置后,每唤醒手机都需要入这个预先定义好的PIN才能访问主幕。 #### 修改已有的 PIN 码 当希望更改现有的 PIN ,同样前往之前提到过的安全设置菜单内寻找更新或者改变已有PIN的选择。这里需要注意的是,在执行此操作前往往也需要确认旧的PIN以证明身份合法性[^4]。 对于忘记了自己所设PIN的情况,部分版本提供了额外的帮助机制;例如连续五误尝试点击解按钮之后能够触发找回途径或是重置流程[^2]。 #### 删除 PIN 码 若再需要使用PIN保护,则可在相同位置选择移除它。过在此之前务必考虑清楚这样做可能导致的数据风险以及隐私暴露可能性。另外值得注意的一点是在某些特定条件下即使取消了常规意义上的措施也可能存在特殊情况下的二认证需求,像双SIM卡各自的独立PIN验证过程就会因为整体关闭了图形化方式而受到影响[^3]。 ```bash # 使用 ADB 命令查看存储 PIN 码的位置 (需具备 root 权限) adb shell ls -al /data/misc/keystore/user_0/ ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值