android8.0 Fingerprint 指纹输错5次后亮屏显示错误信息

当有指纹解锁时,会执行AuthenticationClient.java-->onAuthenticated()一直在监听解锁行为

@Override
    public boolean onAuthenticated(int fingerId, int groupId) {
        boolean result = false;
        boolean authenticated = fingerId != 0;

        IFingerprintServiceReceiver receiver = getReceiver();
        if (receiver != null) {
            try {
                MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_AUTH,
                        authenticated);
                if (!authenticated) {
                    receiver.onAuthenticationFailed(getHalDeviceId());
                } else {
                    if (DEBUG) {
                        Slog.v(TAG, "onAuthenticated(owner=" + getOwnerString()
                                + ", id=" + fingerId + ", gp=" + groupId + ")");
                    }
                    Fingerprint fp = !getIsRestricted()
                            ? new Fingerprint("" /* TODO */, groupId, fingerId, getHalDeviceId())
                            : null;
                    receiver.onAuthenticationSucceeded(getHalDeviceId(), fp, getTargetUserId());//解锁成功
                }
            } catch (RemoteException e) {
                Slog.w(TAG, "Failed to notify Authenticated:", e);
                result = true; // client failed
            }
        } else {
            result = true; // client not listening
        }
        if (!authenticated) {
            if (receiver != null) {
                vibrateError();
            }
            // allow system-defined limit of number of attempts before giving up
            int lockoutMode =  handleFailedAttempt();
            if (lockoutMode != LOCKOUT_NONE) {
                try {
                    Slog.w(TAG, "Forcing lockout (fp driver code should do this!), mode(" +
                            lockoutMode + ")");
                    stop(false);
                    int errorCode = lockoutMode == LOCKOUT_TIMED ?
                            FingerprintManager.FINGERPRINT_ERROR_LOCKOUT :
                            FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
                    receiver.onError(getHalDeviceId(), FingerprintManager.FINGERPRINT_ERROR_FORCING_LOCKOUT, 0 /* vendorCode */);//Add By mincao@tcl.com 2018/1/20 Defect:5880186  //当解锁失败会执行
                    receiver.onError(getHalDeviceId(), errorCode, 0 /* vendorCode */);
                } catch (RemoteException e) {
                    Slog.w(TAG, "Failed to notify lockout:", e);
                }
            }
            result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode
        } else {
            if (receiver != null) {
                vibrateSuccess();
            }
            result |= true; // we have a valid fingerprint, done
            resetFailedAttempts();
        }
        return result;
    }

先看看int lockoutMode =  handleFailedAttempt();他是在FingerprintService.java中实现,因为它监听了该方法

private void startAuthentication(IBinder token, long opId, int callingUserId, int groupId,
                IFingerprintServiceReceiver receiver, int flags, boolean restricted,
                String opPackageName) {
        updateActiveGroup(groupId, opPackageName);

        if (DEBUG) Slog.v(TAG, "startAuthentication(" + opPackageName + ")");

        AuthenticationClient client = new AuthenticationClient(getContext(), mHalDeviceId, token,
                receiver, mCurrentUserId, groupId, opId, restricted, opPackageName) {
            @Override
            public int handleFailedAttempt() {
                mFailedAttempts++;
                mTimedLockoutCleared = false;
                final int lockoutMode = getLockoutMode();
                if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
                    mPerformanceStats.permanentLockout++;
                } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
                    mPerformanceStats.lockout++;
                }

                // Failing multiple times will continue to push out the lockout time
                if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
                    scheduleLockoutReset();
                    return lockoutMode;
                }
                return AuthenticationClient.LOCKOUT_NONE;
            }

            @Override
            public void resetFailedAttempts() {
                FingerprintService.this.resetFailedAttempts(true /* clearAttemptCounter */);
            }

            @Override
            public void notifyUserActivity() {
                FingerprintService.this.userActivity();
            }

            @Override
            public IBiometricsFingerprint getFingerprintDaemon() {
                return FingerprintService.this.getFingerprintDaemon();
            }
        };

        int lockoutMode = getLockoutMode();
        if (lockoutMode != AuthenticationClient.LOCKOUT_NONE) {
            Slog.v(TAG, "In lockout mode(" + lockoutMode +
                    ") ; disallowing authentication");
            int errorCode = lockoutMode == AuthenticationClient.LOCKOUT_TIMED ?
                    FingerprintManager.FINGERPRINT_ERROR_LOCKOUT :
                    FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
            if (!client.onError(errorCode, 0 /* vendorCode */)) {
                Slog.w(TAG, "Cannot send permanent lockout message to client");
            }
            return;
        }
        startClient(client, true /* initiatedByClient */);
    }

看到这个方法可以明白,他是记录指纹识别错误的次数及一些行为,当mFailedAttempts为5的倍数时,会返回AuthenticationClient.LOCKOUT_TIMED

 private int getLockoutMode() {
        if (mFailedAttempts >= MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT) {
            return AuthenticationClient.LOCKOUT_PERMANENT;
        } else if (mFailedAttempts > 0 && mTimedLockoutCleared == false &&
                (mFailedAttempts % MAX_FAILED_ATTEMPTS_LOCKOUT_TIMED == 0)) {
            return AuthenticationClient.LOCKOUT_TIMED;

        }
        return AuthenticationClient.LOCKOUT_NONE;
    }

回到AuthenticationClient.java-->onAuthenticated(),可以看到receiver.onError()方法,传入了一些状态码,而receiver是在FingerprintManager.java指纹监听的时候有实现

private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {

        @Override // binder call
        public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
            mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
        }

        @Override // binder call
        public void onAcquired(long deviceId, int acquireInfo, int vendorCode) {
            mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, vendorCode, deviceId).sendToTarget();
        }

        @Override // binder call
        public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {
            mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, fp).sendToTarget();
        }

        @Override // binder call
        public void onAuthenticationFailed(long deviceId) {
            mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();
        }

        @Override // binder call
        public void onError(long deviceId, int error, int vendorCode) {
            mHandler.obtainMessage(MSG_ERROR, error, vendorCode, deviceId).sendToTarget();//向上层发送消失反馈
        }

        @Override // binder call
        public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
            mHandler.obtainMessage(MSG_REMOVED, remaining, 0,
                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
        }

        @Override // binder call
        public void onEnumerated(long deviceId, int fingerId, int groupId, int remaining) {
            // TODO: propagate remaining
            mHandler.obtainMessage(MSG_ENUMERATED, fingerId, groupId, deviceId).sendToTarget();
        }
    };

利用Handler接收了MSG_ERROR执行了sendErrorResult,具体的switch就不贴出来了

private void sendErrorResult(long deviceId, int errMsgId, int vendorCode) {
            // emulate HAL 2.1 behavior and send real errMsgId
            final int clientErrMsgId = errMsgId == FINGERPRINT_ERROR_VENDOR
                    ? (vendorCode + FINGERPRINT_ERROR_VENDOR_BASE) : errMsgId;
            if (mEnrollmentCallback != null) {
                mEnrollmentCallback.onEnrollmentError(clientErrMsgId,
                        getErrorString(errMsgId, vendorCode));
            } else if (mAuthenticationCallback != null) {
                mAuthenticationCallback.onAuthenticationError(clientErrMsgId,
                        getErrorString(errMsgId, vendorCode));

            } else if (mRemovalCallback != null) {
                mRemovalCallback.onRemovalError(mRemovalFingerprint, clientErrMsgId,
                        getErrorString(errMsgId, vendorCode));
            } else if (mEnumerateCallback != null) {
                mEnumerateCallback.onEnumerateError(clientErrMsgId,
                        getErrorString(errMsgId, vendorCode));
            }
        }

mAuthenticationCallback其实是FingerprintManager.java中的一个回调接口,在上层KeyguardUpdateMonitor.java中有实现

因为之前指纹解锁时一直在监听:mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);就等待mAuthenticationCallback返回结果。

private FingerprintManager.AuthenticationCallback mAuthenticationCallback
            = new AuthenticationCallback() {

        @Override
        public void onAuthenticationFailed() {
            handleFingerprintAuthFailed();
        };

        @Override
        public void onAuthenticationSucceeded(AuthenticationResult result) {
            Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
            handleFingerprintAuthenticated(result.getUserId());
            Trace.endSection();
        }

        @Override
        public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
            handleFingerprintHelp(helpMsgId, helpString.toString());
        }

        @Override
        public void onAuthenticationError(int errMsgId, CharSequence errString) {
            handleFingerprintError(errMsgId, errString.toString());//更新错误信息
        }

        @Override
        public void onAuthenticationAcquired(int acquireInfo) {
            handleFingerprintAcquired(acquireInfo);
        }
    };

看到这个方法可以明白,它是根据不同的状态码处理不同的消息,当状态码为7时,也就是FingerprintManager.FINGERPRINT_ERROR_FORCING_LOCKOUT=7,此时已经输错了5次,因为当输错了5次,指定了状态码为7,用7来处理后续的操作,会通过亮屏显示指纹识别错误信息。

private void handleFingerprintError(int msgId, String errString) {
        Log.d(TAG, "Fingerprint handleFingerprintError:  msgId = "+msgId);
        if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
                && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
            setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
            startListeningForFingerprint();
        }
        //Add by mincao@tcl.com for defect[5880186] 20180120, fingerprint unlock the device failed 5 times without any prompts, begin
        if (msgId == FingerprintManager.FINGERPRINT_ERROR_FORCING_LOCKOUT){
            Log.d(TAG, "Fingerprint unlock the device failed 5 times, wakeup screen and show prompt.");
            setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
            mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
            mWakeLock = mPM.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "Wakeup Sreen");
            mWakeLock.acquire();
            mWakeLock.release();
            mWakeLock = null;
            mPM = null;
        }
        //Add by mincao@tcl.com for defect[5880186] 20180120, fingerprint unlock the device failed 5 times without any prompts, end

        else {
            setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
        }

        if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
            if (mHardwareUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
                mHardwareUnavailableRetryCount++;
                mHandler.removeCallbacks(mRetryFingerprintAuthentication);
                mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
            }
        }

        if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
            mLockPatternUtils.requireStrongAuth(
                    LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
                    getCurrentUser());
        }

        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onFingerprintError(msgId, errString);//会更新界面错误信息,在FingerprintUnlockController.java中有实现
            }
        }

    }

此时,指纹识别错误5次,亮屏且提示错误信息已经解析完毕。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的代码示例,用于将指纹验证结果上传到串口幕进行显示: ```c++ #include <SoftwareSerial.h> // 引入串口幕库 #include <Adafruit_Fingerprint.h> // 引入指纹模块库 SoftwareSerial mySerial(2, 3); // 创建一个软串口实例,用于和串口幕通信 Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); // 创建一个指纹模块实例 void setup() { Serial.begin(9600); // 初始化串口通信 mySerial.begin(9600); // 初始化软串口通信 finger.begin(57600); // 初始化指纹模块 } void loop() { if (finger.getImage()) { // 获取指纹图像 int id = finger.fingerFastSearch(); // 在指纹库中搜索指纹 if (id == FINGERPRINT_OK) { // 如果搜索成功 Serial.println("指纹验证成功!"); // 在串口中输出验证结果 mySerial.print("指纹验证成功!"); // 将验证结果通过串口发送到幕 } else { Serial.println("指纹验证失败!"); // 在串口中输出验证结果 mySerial.print("指纹验证失败!"); // 将验证结果通过串口发送到幕 } } } ``` 以上代码中,我们使用了 `SoftwareSerial` 库和 `Adafruit_Fingerprint` 库来分别与串口幕和指纹模块进行通信和操作。在 `loop()` 函数中,我们首先调用 `finger.getImage()` 方法来获取指纹图像,然后调用 `finger.fingerFastSearch()` 方法在指纹库中搜索指纹。如果搜索成功,我们在串口中输出验证结果,并通过 `mySerial.print()` 方法将结果上传到串口幕进行显示。 需要注意的是,以上代码中的具体串口和引脚号可能因具体硬件而有所不同,需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值