react native项目中硬件相关的第三方库和工具

147 阅读4分钟

逐步更新中...

手持机

红外扫码(需要/不需要输入框)√今天研究明白了🫡

需要输入框:有输入框就行,代码其实都不用写了。

不需要输入框:就是广播模式,需要对接代码,监听结果。

读取红外扫码就两种:

  • 第一种难一点的要通过pda设备的串口通信,自己研究比较复杂,厂家也没文档说怎么弄,我自己也没学习资料。
  • 第二种就是厂商提供的封装好的sdk,基本就是通过广播,厂商有给代码,自己封装一下,监听一下,写个RN的桥接文件,传给JS层,再封装一下就是写hook方便function函数组件使用。

兄弟们等我有空发文章~

手持机摄像头扫码

这个我现在是用react-native-camera封装的

蓝牙打印机:

目前公司采购的是ZR328 PlusLink OS打印机 官方写了一个教程怎么使用react native 封装:www.youtube.com/watch?v=DSN…

文字版:developer.zebra.com/blog/develo…

第三方库也有,但是没有上传npm,目前是私用的,代码可以参考 github.com/scantarbian…

高频刷卡(nfc刷卡)

react-native-nfc-manager 这个用了好久,维护更新也快。测试通过可用✅

截屏2025-08-13 21.48.39.png

超高频刷卡

原来的项目里面有,等我整理一下文档。

工位机:

USB连接打印机:

目前公司采购的是得实的DL-316系列

USB扫码枪扫码(需要/不需要输入框,原理是模拟键盘输入,监听+拼接结果)

github.com/china-engli… 测试通过可用✅

github.com/kevinejohn/… 需要搭配自己写键盘输入的映射,测试通过可用 ✅

import { useState, useEffect, useRef, useCallback } from 'react';
import KeyEvent from 'react-native-keyevent';

/**
 * 扫码键盘事件自定义Hook - 简化版
 * 参考Java版ScanKeyEventHelper的核心逻辑
 *
 * @param {function} onScanComplete 扫码完成回调函数
 * @returns {string} 最新的扫码结果
 */
const useScanKeyEvent = onScanComplete => {
  const MESSAGE_DELAY = 500; // 延迟500ms,判断扫码是否完成(与Java版本一致)

  // 状态管理
  const [lastScanResult, setLastScanResult] = useState('');

  // Refs 管理
  const scanBufferRef = useRef('');
  const timeoutRef = useRef(null);
  const shiftPressedRef = useRef(false);

  // 键码转字符映射(与Java版本保持一致)
  const getInputChar = useCallback((keyCode, isShift) => {
    // 字母 A-Z (keyCode 29-54 对应 Android KeyEvent.KEYCODE_A-Z)
    if (keyCode >= 29 && keyCode <= 54) {
      const char = String.fromCharCode(65 + (keyCode - 29)); // A-Z
      return isShift ? char : char.toLowerCase();
    }

    // 数字 0-9 (keyCode 7-16 对应 Android KeyEvent.KEYCODE_0-9)
    if (keyCode >= 7 && keyCode <= 16) {
      if (isShift) {
        // Shift + 数字键的特殊字符(与Java版本一致)
        const shiftNumbers = [')', '!', '@', '#', '$', '%', '^', '&', '*', '('];
        return shiftNumbers[keyCode - 7];
      } else {
        return String.fromCharCode(48 + (keyCode - 7)); // 0-9
      }
    }

    // 特殊字符处理(与Java版本保持一致)
    const specialKeys = {
      55: isShift ? '<' : ',', // KEYCODE_COMMA
      56: isShift ? '>' : '.', // KEYCODE_PERIOD
      76: isShift ? '?' : '/', // KEYCODE_SLASH
      74: isShift ? ':' : ';', // KEYCODE_SEMICOLON
      71: isShift ? '{' : '[', // KEYCODE_LEFT_BRACKET
      72: isShift ? '}' : ']', // KEYCODE_RIGHT_BRACKET
      73: isShift ? '|' : '\\', // KEYCODE_BACKSLASH
      68: isShift ? '~' : '`', // KEYCODE_GRAVE
      69: isShift ? '_' : '-', // KEYCODE_MINUS
      70: isShift ? '+' : '=', // KEYCODE_EQUALS
      62: ' ', // KEYCODE_SPACE
    };

    return specialKeys[keyCode] || '';
  }, []);

  // 扫码完成处理(参考Java版本的performScanSuccess)
  const performScanSuccess = useCallback(() => {
    const barcode = scanBufferRef.current;
    if (barcode && onScanComplete) {
      onScanComplete(barcode);
      setLastScanResult(barcode);
    }
    // 清空缓冲区
    scanBufferRef.current = '';
  }, [onScanComplete]);

  // 清理定时器
  const clearScanTimeout = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }
  }, []);

  // 键盘事件处理(参考Java版本的analysisKeyEvent)
  const handleKeyEvent = useCallback(
    keyEvent => {
      const keyCode = keyEvent.keyCode;

      // 检查Shift键状态(参考Java版本的checkLetterStatus)
      if (keyCode === 59 || keyCode === 60) {
        // KEYCODE_SHIFT_LEFT || KEYCODE_SHIFT_RIGHT
        shiftPressedRef.current = true;
        return;
      }

      // Enter键 - 立即完成扫码(与Java版本一致)
      if (keyCode === 66 || keyCode === 28) {
        // KEYCODE_ENTER
        clearScanTimeout();
        performScanSuccess();
        return;
      }

      // 获取字符
      const char = getInputChar(keyCode, shiftPressedRef.current);

      if (char) {
        // 累积字符到缓冲区
        scanBufferRef.current += char;

        // 清除之前的定时器,设置新的延时(与Java版本逻辑一致)
        clearScanTimeout();
        timeoutRef.current = setTimeout(() => {
          performScanSuccess();
        }, MESSAGE_DELAY);
      }

      // 重置Shift状态
      if (shiftPressedRef.current && keyCode !== 59 && keyCode !== 60) {
        shiftPressedRef.current = false;
      }
    },
    [getInputChar, performScanSuccess, clearScanTimeout],
  );

  // 启动监听
  useEffect(() => {
    KeyEvent.onKeyDownListener(handleKeyEvent);

    return () => {
      clearScanTimeout();
      KeyEvent.removeKeyDownListener();
    };
  }, [handleKeyEvent, clearScanTimeout]);

  return lastScanResult;
};

export default useScanKeyEvent;

hook方式useScanKeyEvent

  const lastScanResult = useScanKeyEvent(scannedData => {
    console.log('Hook扫码完成回调:', scannedData);
    //TODO - 扫码成功后的操作
  });

刷卡(也是串口通讯)

github.com/bastengao/r… 测试通过可用✅

人脸识别

方案一:虹软sdk,提取人脸特征到服务端,客户端请求接口保存到本地,获取frame帧和本地人脸特征对比。需要封装好给RN端口(还没封装好)

方案二:github.com/FaceAISDK/F… 作者的RN版本github.com/zkteco-home… (未验证方案)

红外发射器

react-native-infrared-interface

react-native-infrared-interface 是一个用于在Android设备上使用红外(IR)发射器的React Native接口库。 1

这个库的主要功能:

  1. 检测设备是否有红外发射器 - hasIrEmitter() 方法

  2. 查询支持的载波频率 - getCarrierFrequencies() 方法

  3. 发射红外信号 - transmit(carrierFrequency, pattern) 方法

它是一个 发射器(transmitter) 库,只能用来 发送 红外信号,这个库主要用于控制红外设备(如电视、空调等),而不是读取红外数据。

参考文章:

Android NFC开发详解 总结和NFC读卡实例解析

Android 串口通信开发总结和实例解析

Android USB通信开发总结和热敏打印机开发实例解析