您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關使用React Native實現指紋登錄的方法,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
具體內容如下所示:
最近在做react-native的APP,項目登錄使用了普通賬號密碼登錄、短信登錄、手勢登陸、指紋登錄和人臉識別登錄五種方式,所以準備做一個登錄方式的合集。本篇是指紋登錄篇,通過手機調用指紋傳感器來獲取用戶指紋并做校驗,校驗成功則自動登錄。
首先展示我們最后達成的成果,畢竟無圖無真相,下方是真機錄屏gif:
分析下gif所展示的功能點:
1,通過點擊操作選項來彈出指紋識別界面,點擊取消/上方空白處取消指紋識別
2,切換到其他登錄方式時,仍然可以調用"更多操作方式"來喚起指紋識別
經過功能點分析,我們可以看出,現在需要一個指紋識別的組件,通過操作彈出項來喚起/切換指紋識別的組件。操作項組件我們可以選擇antd-mobile-rn的ActionSheet組件,指紋識別組件使用react-native-fingerprint-scanner,在github上有642個star,想必是值得信任的,附上組件地址https://github.com/hieuvp/react-native-fingerprint-scanner。(多句嘴,模擬器是沒有指紋識別的功能的,請使用真機調試)。
接下來按照文檔一通操作,下載,跑demo,不出所料有問題出現了。
官方demo使用的是react16之前的class寫法,并且對于喚起/隱藏指紋識別的地方寫的有些模糊,所以我們需要仔細梳理并用新的函數式組件寫法來重寫一次。
指紋識別的過程應該如下:
1,判斷設備是否支持指紋識別
2,判斷android API是否低于23,因為android 6.0之后官方才支持了指紋識別的api接口,所以如果android API<23我們需要對低版本手機做適配
3,從指紋組件react-native-fingerprint-scanner引入FingerprintScanner,調用FingerprintScanner.authenticate
方法來喚起指紋組件
4,點擊取消/上方空白處隱藏指紋組件
5,指紋識別成功寫對應的事件,如登錄事件
按照指紋識別的流程,我們在FingerPrint/index.tsx下寫指紋組件,關鍵代碼都寫了注釋:
import React, {Component, useState, useCallback} from 'react'; import { Alert, Image, Text, TouchableOpacity, View, ViewPropTypes, Platform, StyleSheet, } from 'react-native'; import FingerprintScanner from 'react-native-fingerprint-scanner'; import ShakingText from './ShakingText.component'; import {connector, ModelState} from '@/models/connect'; import {useFocusEffect} from "@react-navigation/native"; interface Props extends ModelState{ fingerPrint, setFingerPrint, } const FingerPrintPopup: React.FC<Props> = React.memo(props => { let {fingerPrint, setFingerPrint,dispatch} = props; const description = null; const [LegacyInfo, setLegacyInfo] = useState({ errorMessageLegacy: undefined, biometricLegacy: undefined }) useFocusEffect( React.useCallback(() => { console.log("進入指紋組件"); //判斷設備是否支持指紋識別 detectFingerprintAvailable(); //判斷Android API是不是<23,高于此版本使用標準指紋解鎖api;低于此版本使用兼容適配版本 if (requiresLegacyAuthentication()) { authLegacy(); } else { authCurrent(); } return () => { console.log("離開指紋組件"); //組件卸載,停止指紋監聽指紋掃描器并釋放內部緩存 FingerprintScanner.release(); } }, []) ) //判斷安卓版本 function requiresLegacyAuthentication() { return Platform.Version < 23; } //控制指紋組件消失 const handleFingerprintDismissed = () => { setFingerPrint({ ...fingerPrint, popupShowed: false }); }; //檢測手機是否支持指紋識別 const detectFingerprintAvailable = () => { FingerprintScanner .isSensorAvailable() .catch(error => { Alert.alert("您的設備不支持指紋識別,請選擇其他方式登錄") setFingerPrint({ ...fingerPrint, errorMessage: error.message, biometric: error.biometric, popupShowed: false, }) }); } //android API>23時,調用authCurrent const authCurrent = () => { FingerprintScanner .authenticate({title: '指紋登錄', cancelButton: '取消'}) .then(() => { //離開頁面時將popupShowed置為false handleFingerprintDismissed(); //指紋驗證成功后的事件,比如登錄 successVerify(); }) .catch(() => { //點擊取消或上方空白區隱藏組件后,將popupShowed置為false //這里是控制指紋組件切換顯示/隱藏的關鍵! handleFingerprintDismissed(); }) } //指紋驗證成功后的事件,比如登錄 const successVerify = () => { dispatch({ type: 'user/login', payload: { username: "張三", password: '123456', } }); } //android API<23時調用指紋組件的兼容寫法 const authLegacy = () => { FingerprintScanner .authenticate({onAttempt: handleAuthenticationAttemptedLegacy}) .then(() => { //指紋驗證成功 handleFingerprintDismissed(); Alert.alert('指紋身份驗證', '身份驗證成功'); successVerify(); }) .catch((error) => { //指紋驗證失敗 setLegacyInfo({errorMessageLegacy: error.message, biometricLegacy: error.biometric}); description.shake(); handleFingerprintDismissed(); }); } //當用戶嘗試掃描指紋但失敗時的回調函數 const handleAuthenticationAttemptedLegacy = (error) => { setLegacyInfo({ ...LegacyInfo, errorMessageLegacy: error.message }); description.shake(); }; //手動寫一個指紋驗證的組件 const renderLegacy = ( <View style={styles.container}> <View style={styles.contentContainer}> <Image style={styles.logo} source={require('../../../assets/login/finger_print.png')} /> <Text style={styles.heading}> 生物識別{'\n'}身份驗證 </Text> <ShakingText ref={(instance) => { description = instance; }} style={styles.description(!!LegacyInfo.errorMessageLegacy)}> {LegacyInfo.errorMessageLegacy || `Scan your ${LegacyInfo.biometricLegacy} on the\ndevice scanner to continue`} </ShakingText> <TouchableOpacity style={styles.buttonContainer} onPress={handleFingerprintDismissed} > <Text style={styles.buttonText}> 返回 </Text> </TouchableOpacity> </View> </View> ); return () => { //android API>23時,不需要渲染;否則渲染renderLegacy的組件 if (requiresLegacyAuthentication()) { return renderLegacy } return null; } }) export default connector(FingerPrintPopup); const styles = StyleSheet.create({ container: { position: 'absolute', top: 0, bottom: 0, left: 0, right: 0, backgroundColor: 'rgba(0, 164, 222, 0.9)', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', }, contentContainer: { flexDirection: 'column', justifyContent: 'center', alignItems: 'center', backgroundColor: '#ffffff', }, logo: { marginVertical: 45, }, heading: { textAlign: 'center', color: '#00a4de', fontSize: 21, }, description: (error) => { return { textAlign: 'center', color: error ? '#ea3d13' : '#a5a5a5', height: 65, fontSize: 18, marginVertical: 10, marginHorizontal: 20, } }, buttonContainer: { padding: 20, }, buttonText: { color: '#8fbc5a', fontSize: 15, fontWeight: 'bold', }, });
可以看出來,android API在23以上版本是不需要渲染指紋識別組件的,23以下版本需要自己手動寫一個渲染的組件,引用了一個ShakingText組件,這個組件官網有給,我們直接復制過來就可以,在ShakingText.component.js寫:
import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { Animated, Text, } from 'react-native'; class ShakingText extends Component { componentWillMount() { this.shakedValue = new Animated.Value(0); } get animatedStyle() { return { transform: [ { translateY: this.shakedValue.interpolate({ inputRange: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], outputRange: [0, 10, -15, 12, -9, 18, -7, 10, -11, 5, 0], }), }, { translateX: this.shakedValue.interpolate({ inputRange: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], outputRange: [0, 2, -3, 4, -4, 3, -3, 4, -5, 2, 0], }), }, ], }; } shake = () => { this.shakedValue.setValue(0); Animated.spring(this.shakedValue, { toValue: 1, friction: 3, tension: 10, }).start(() => this.shakedValue.setValue(0)); }; render() { return ( <Animated.Text {...this.props} style={[this.animatedStyle, this.props.style]} /> ); } } ShakingText.propTypes = { children: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.node), PropTypes.node ]), style:Text.propTypes.style, }; export default ShakingText;
寫好了指紋組件,接下來我們需要使用ActionSheet組件來切換和控制指紋組件的顯示隱藏。控制指紋組件的顯示隱藏我們使用popupShowed這個變量來控制,將它放在state中。我們在LoginSheet/index.tsx
下寫:
import React,{useState} from 'react'; import {View, Text, StyleSheet} from 'react-native'; import {px2rem} from "@/utils/px2rem"; import {ActionSheet} from "@ant-design/react-native"; import {navigateReplace} from "@/utils/navigation"; import FingerprintPopup from "@/pages/Account/FingerPrint"; import {connector,ModelState} from '@/models/connect'; interface Props { } const LoginSheet: React.FC<Props> = React.memo(props => { const {dispatch} = props; const [fingerPrint,setFingerPrint] = useState({ errorMessage: undefined, biometric: undefined, popupShowed: false, }) //點擊指紋登錄選項時,將popupShowed置為true const handleFingerprintShowed = () => { setFingerPrint({ ...fingerPrint, popupShowed: true }); } const showActionSheet = () =>{ const BUTTONS = [ '賬號 / 短信登錄', '手勢登錄', '指紋登錄', '人臉識別登錄', '取消', ]; ActionSheet.showActionSheetWithOptions( { options: BUTTONS, cancelButtonIndex: 4, }, buttonIndex => { const clickOption = BUTTONS[buttonIndex]; console.log('clicked: ',clickOption); switch (clickOption){ case '賬號 / 短信登錄': navigateReplace("Login"); return; case '手勢登錄': navigateReplace("GestureUnlock"); return; case '指紋登錄': //顯示指紋登錄 handleFingerprintShowed(); return; case '人臉識別登錄': navigateReplace("Login"); return; } } ); } return ( <View style={styles.container}> <View style={styles.more}> <Text style={styles.moreText} onPress={showActionSheet}>更多登錄方式</Text> </View> {fingerPrint.popupShowed ? ( <FingerprintPopup fingerPrint={fingerPrint} setFingerPrint={setFingerPrint} /> ) : null} </View> ); }) export default connector(LoginSheet); const styles = StyleSheet.create({ container:{ }, more:{ width:'100%', alignItems:'center', height:px2rem(50), marginBottom:px2rem(30), }, moreText:{ // color:'#a1a1a1' } });
這樣就完成了react-native 的指紋登錄功能,總結一下,關鍵點在于:
切換指紋組件顯示隱藏在于控制popupShowed的true/false狀態來切換FingerprintPopup組件的展示與否每次喚醒組件都要通過顯示FingerprintPopup組件,在初始化期間進行判斷可用、版本然后調用組件展示每次隱藏組件都要通過隱藏FingerprintPopup組件,在組件卸載階段釋放指紋組件監聽器FingerprintScanner.release();
操作指紋組件時不管是指紋識別成功還是點擊取消,都一定要將popupShowed置為false;指紋識別失敗不做操作。
關于使用React Native實現指紋登錄的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。