Android11 PIN码解锁分析

在上一篇文章里我们分析了手势绘制解锁的整个流程,这次我们来分析一下PIN码解锁时所相关的内容

布局

在我们分析流程之前,我们先来看到KeyguardPINView这个类,他是用于显示解锁的 PIN 键盘,也就是绘制这个界面。在这个类里面有几个ViewGroup,每一个都代表了一排按键
让我们来看下这张图请添加图片描述
从最上面输入密码的按键123开始总共有四行,所以我们在这里就有四个ViewGroup

KeyguardPINView

构造

首先我们看他的构造方法,在这里面定义了显示动画以及消失动画的初始化,并且初始化了监听器和一些基本参数

onFinishInflate

在这个方法里面,每个view都会进行初始化,通过findViewById找到自己对应的那个view。然后在类的成员变量中,有一个view的二维数组mViews,这里就是将1234567890以及确定退格打入至布局中。(还有一行紧急呼救)这里有一个重点,我们可以看到底部导航栏的这个回退按键,它也是在这个页面进行初始化的而不是我们平常使用的那一个底部导航栏,以及他的点击事件也是在这里进行实现。(但是修改了之后还是可以进行相同的处理,这里没有搞明白)

这个类大概就这两个方法需要注意,接着我们进行主要的部分

KeyguardPinBasedInputView

与之前那一个类一样,我们还有一个类是跟PIN解锁相关的,那就是KeyguardPinBasedInputView,在KeyguardPINView中,我们只看到了每一行的布局,而在KeyguardPinBasedInputView类中,代码加载了每一个按键的单独布局

 @Override
    protected void onFinishInflate() {
        mPasswordEntry = findViewById(getPasswordTextViewId());
        mPasswordEntry.setOnKeyListener(this);

        // Set selected property on so the view can send accessibility events.
        mPasswordEntry.setSelected(true);

        mPasswordEntry.setUserActivityListener(new PasswordTextView.UserActivityListener() {
            @Override
            public void onUserActivity() {
                onUserInput();
            }
        });

        mOkButton = findViewById(R.id.key_enter);
        if (mOkButton != null) {
            mOkButton.setOnTouchListener(this);
            mOkButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(TAG, "mOkButton onClick");
                    if (mPasswordEntry.isEnabled()) {
                        Log.d(TAG, "mOkButton onClick verifyPasswordAndUnlock");
                        verifyPasswordAndUnlock();
                    }
                }
            });
            mOkButton.setOnHoverListener(new LiftToActivateListener(getContext()));
        }

        mDeleteButton = findViewById(R.id.delete_button);
        mDeleteButton.setVisibility(View.VISIBLE);
        mDeleteButton.setOnTouchListener(this);
        mDeleteButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // check for time-based lockouts
                if (mPasswordEntry.isEnabled()) {
                    mPasswordEntry.deleteLastChar();
                }
            }
        });
        mDeleteButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                // check for time-based lockouts
                if (mPasswordEntry.isEnabled()) {
                    resetPasswordText(true /* animate */, true /* announce */);
                }
                doHapticKeyClick();
                return true;
            }
        });

        mButton0 = findViewById(R.id.key0);
        mButton1 = findViewById(R.id.key1);
        mButton2 = findViewById(R.id.key2);
        mButton3 = findViewById(R.id.key3);
        mButton4 = findViewById(R.id.key4);
        mButton5 = findViewById(R.id.key5);
        mButton6 = findViewById(R.id.key6);
        mButton7 = findViewById(R.id.key7);
        mButton8 = findViewById(R.id.key8);
        mButton9 = findViewById(R.id.key9);

        mPasswordEntry.requestFocus();
        super.onFinishInflate();
    }

接下来我们看一看确认按键的事件
首先第一步,他先找到了输入的密码,然后设置监听器,设置选中。
接下来在给OKButton设置监听事件
那么我们可以看到最终触发的方法是verifyPasswordAndUnlock,这才是最重要的组成部分和实现,我们来看一看

protected void verifyPasswordAndUnlock() {
        Log.d(TAG, "verifyPasswordAndUnlock mDismissing=" + mDismissing);
        //首先验证是否正在解锁,如果是则直接返回
        if (mDismissing) return; // already verified but haven't been dismissed; don't do it again.
		//这里表示获取输入的密码凭证,接着就不再让输入密码了直至验证完成
        final LockscreenCredential password = getEnteredCredential();
        setPasswordEntryInputEnabled(false);
        if (mPendingLockCheck != null) {
            mPendingLockCheck.cancel(false);
        }

        final int userId = KeyguardUpdateMonitor.getCurrentUser();
        if (password.size() <= MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT) {
        	//在这里验证密码之前先确认是否大于预设的最小密码长度,这是为了防止误触导致手机锁定
        	//默认长度为4
        	//设置可以继续输入密码,进行检查直接返回false,密码清空接下来返回
            // to avoid accidental lockout, only count attempts that are long enough to be a
            // real password. This may require some tweaking.
            setPasswordEntryInputEnabled(true);
            onPasswordChecked(userId, false /* matched */, 0, false /* not valid - too short */);
            password.zeroize();
            return;
        }

        if (LatencyTracker.isEnabled(mContext)) {
            LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL);
            LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL_UNLOCKED);
        }

        mKeyguardUpdateMonitor.setCredentialAttempted();
        mPendingLockCheck = LockPatternChecker.checkCredential(
                mLockPatternUtils,
                password,
                userId,
                new LockPatternChecker.OnCheckCallback() {
					//检查之前
                    @Override
                    public void onEarlyMatched() {
                        if (LatencyTracker.isEnabled(mContext)) {
                            LatencyTracker.getInstance(mContext).onActionEnd(
                                    ACTION_CHECK_CREDENTIAL);
                        }
                        onPasswordChecked(userId, true /* matched */, 0 /* timeoutMs */,
                                true /* isValidPassword */);
                        password.zeroize();
                    }
					//进行检查
                    @Override
                    public void onChecked(boolean matched, int timeoutMs) {
                        Log.d(TAG, "verifyPasswordAndUnlock onChecked");
                        if (LatencyTracker.isEnabled(mContext)) {
                            LatencyTracker.getInstance(mContext).onActionEnd(
                                    ACTION_CHECK_CREDENTIAL_UNLOCKED);
                        }
                        setPasswordEntryInputEnabled(true);
                        mPendingLockCheck = null;
                        if (!matched) {
                            onPasswordChecked(userId, false /* matched */, timeoutMs,
                                    true /* isValidPassword */);
                        }
                        password.zeroize();
                    }
					//如果检查前的回调取消了检测,则调用这个方法。但是与此同时仍然要记下延迟
                    @Override
                    public void onCancelled() {
                        Log.d(TAG, "verifyPasswordAndUnlock onCancelled");
                        // We already got dismissed with the early matched callback, so we cancelled
                        // the check. However, we still need to note down the latency.
                        if (LatencyTracker.isEnabled(mContext)) {
                            LatencyTracker.getInstance(mContext).onActionEnd(
                                    ACTION_CHECK_CREDENTIAL_UNLOCKED);
                        }
                        password.zeroize();
                    }
                });
    }

与上方的OKButton一样接下来DeleteButton也有着同样的设置。并且我们来关注一下它里面的 deleteLastChar方法

public void deleteLastChar() {
        int length = mText.length();
        CharSequence textbefore = getTransformedText();
        if (length > 0) {
            mText = mText.substring(0, length - 1);
            CharState charState = mTextChars.get(length - 1);
            charState.startRemoveAnimation(0, 0);
            sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
        }
        userActivity();
    }

这里的流程其实就是
1.确认密码长度是否大于0,如果大于0则已经输入了密码就接着往下走。
2.将获取到的密码Text字符串分解成一个个的字符,接着将最后一个移除
3.发送事件重新在Text中设置密码

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
win10系统的BitLocker是一种整硬盘加密技术,用于保护计算机上的数据安全。如果在重装系统后无法解锁BitLocker,可能是由于以下几个原因: 1. 未备份恢复密钥:在使用BitLocker加密硬盘时,会生成一个恢复密钥,用于解锁加密数据。如果您没有备份恢复密钥,那么即使重新安装系统,也无法解锁BitLocker。因此,您需要确保在重装系统前备份了恢复密钥。 2. 更换硬件设备:如果您在重装系统后更换了硬件设备,例如更换了主板或者更换了硬盘,那么原来的BitLocker密钥将无法解锁加密数据。因此,您需要使用之前备份好的恢复密钥重新解锁BitLocker。 3. 操作错误:在尝试解锁BitLocker时,可能会因为操作错误导致无法解锁。您需要仔细按照BitLocker的解锁步骤进行操作,确保输入正确的密或恢复密钥。 如果您遇到了无法解锁BitLocker的问题,可以尝试以下解决方法: 1. 使用恢复密钥:如果您备份了BitLocker的恢复密钥,可以使用该密钥进行解锁。在系统重启后,按照提示选择“输入恢复密钥”选项,并输入正确的恢复密钥进行解锁。 2. 与微软支持联系:如果您无法通过恢复密钥解锁BitLocker,可以联系微软的技术支持团队获取进一步的帮助。他们可能需要您提供一些详细信息,以便帮助您解决问题。 最后,为避免类似的情况再次发生,建议您在使用BitLocker加密硬盘之前备份好恢复密钥,并牢记相关的密。这样,即使需要重装系统,您也能顺利解锁BitLocker,保护您的数据安全。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值