You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo托管React Native应用连接Brother P-TOUCH蓝牙打印机求助

问题:Expo托管工作流连接Brother P-TOUCH蓝牙打印机失败

我用Expo托管工作流开发React Native应用,集成expo-print和Brother P-TOUCH蓝牙便携打印机时遇到问题:打印按钮能触发,但找不到已连接的蓝牙打印机(设备蓝牙列表里能看到它)。

不确定问题出在打印机必须用专属APP才能工作,还是需要执行npx expo prebuild来兼容托管工作流不支持的打印类库,或者两者都有。

想知道有没有人成功用Expo托管工作流连接过Brother P-TOUCH便携打印机,求实现步骤和避坑指南。另外也欢迎推荐其他便携打印机,目前试了多种方案都失败,只能临时把内容存到相册后用Brother官方APP打印。

附上我的代码:

import { View, Text, TouchableOpacity } from "react-native";
import { StyleSheet } from "react-native";
import * as Print from "expo-print";
import * as MediaLibrary from "expo-media-library";
import QRCode from "react-native-qrcode-svg";
import { useRef, useState, useEffect, useId } from "react";
import { captureRef } from "react-native-view-shot";

function QRscreen({ route }) {
  const { currentDate, currentTime, longitude, latitude, qrText } =
    route.params;
  const qrId = useId();

  const qrCodeData = JSON.stringify({
    Id: qrId,
    Date: currentDate,
    Time: currentTime,
    Longitude: longitude,
    Latitude: latitude,
    UserText: qrText,
  });

  const svg = useRef(null);
  const imgRef = useRef();

  const [dataUrl, setDataUrl] = useState(null);

  const handlePrint = async () => {
    const html = `<img src="data:image/jpeg;base64,${dataUrl}"/>`;
    await Print.printAsync({ html });
  };

  const handleSaveImg = async () => {
    const { status } = await MediaLibrary.requestPermissionsAsync();
    if (status === "granted" && dataUrl) {
      const qrImg = await captureRef(imgRef, {
        format: "jpg",
        quality: 0.8,
      });
      const asset = await MediaLibrary.createAssetAsync(qrImg);
      await MediaLibrary.createAlbumAsync("MyQRCodeAlbum", asset, false);
    } else {
      console.log("Invalid dataUrl format or missing image data.");
    }
  };

  useEffect(() => {
    const getDataUrl = () => {
      svg.current.toDataURL(setDataUrl);
    };
    if (svg.current != null) {
      getDataUrl();
    }
  }, [svg]);

  return (
    <View style={styles.container}>
      <View>
        <Text style={styles.header}>Qr Code</Text>
        <View ref={imgRef} collapsable={false}>
          <Text style={styles.idHeadline}>
            id: {qrId.substring(2, qrId.length - 1)}
          </Text>
          <QRCode
            value={qrCodeData}
            size={200}
            getRef={(c) => (svg.current = c)}
          />
        </View>
        <TouchableOpacity
          style={styles.printButton}
          onPress={handlePrint}
          activeOpacity={0.6}
        >
          <Text>Print</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.saveImageButton}
          onPress={handleSaveImg}
          activeOpacity={0.6}
        >
          <Text>Save as Image</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
  },
  header: {
    alignSelf: "center",
    fontSize: 25,
    fontWeight: "bold",
    marginBottom: 16,
  },
  printButton: {
    alignItems: "center",
    backgroundColor: "#DEB887",
    padding: 10,
    borderRadius: 8,
    marginTop: 25,
  },
  saveImageButton: {
    alignItems: "center",
    backgroundColor: "#DEB887",
    padding: 10,
    borderRadius: 8,
    marginTop: 10,
  },
  idHeadline: {
    color: "white",
    fontWeight: "bold",
    fontSize: 15,
  },
});

export default QRscreen;

打印界面


解决方案与实现步骤

1. 核心问题分析

  • expo-print依赖系统原生打印框架,本身不支持直接连接蓝牙热敏打印机(如Brother P-TOUCH这类),这类设备大多需要厂商专属协议或SDK支持,系统框架无法识别。
  • Expo托管工作流无法直接引入原生蓝牙打印SDK,必须转为预构建(prebuild)工作流才能添加原生依赖。

2. 具体实现步骤

步骤1:转为预构建工作流

  • 执行命令生成iOS/Android原生项目文件:
    npx expo prebuild
    
  • 在app.json中配置完整蓝牙权限:
    {
      "expo": {
        "ios": {
          "infoPlist": {
            "NSBluetoothAlwaysUsageDescription": "需要蓝牙权限连接打印机"
          }
        },
        "android": {
          "permissions": [
            "BLUETOOTH",
            "BLUETOOTH_ADMIN",
            "ACCESS_FINE_LOCATION",
            "BLUETOOTH_CONNECT"
          ]
        }
      }
    }
    

步骤2:集成Brother官方打印SDK

  • iOS:在ios/Podfile中添加依赖,执行pod install:
    pod 'BrotherPrintSDK'
    
  • Android:在android/build.gradle中添加Brother Maven仓库,app/build.gradle添加SDK依赖:
    dependencies {
      implementation 'com.brother.ptouch.sdk:print-sdk:3.14.0'
    }
    

步骤3:实现打印机连接与打印逻辑

  • 可自行编写React Native原生桥接模块调用Brother SDK的蓝牙扫描、打印方法,或使用第三方封装库(如react-native-brother-print,注意验证版本兼容性)。
  • 核心逻辑示例(Android侧):
    PrinterManager printerManager = new PrinterManager();
    PrinterInfo printerInfo = new PrinterInfo();
    printerInfo.setPrinterModel(PrinterInfo.Model.PT_P300BT);
    printerInfo.setConnectionType(PrinterInfo.ConnectionType.BLUETOOTH);
    printerManager.setPrinterInfo(printerInfo);
    
    // 扫描蓝牙打印机
    List<PrinterInfo> printers = printerManager.getPrinterList();
    // 选中打印机后发送打印任务(如QR码图片)
    printerManager.printImage(bitmap);
    

步骤4:替换原有打印逻辑

不再依赖expo-print的系统打印,直接通过Brother SDK生成打印内容并发送到目标打印机。

3. 避坑指南

  • 确认打印机型号支持SDK连接:Brother P-TOUCH系列仅部分型号(如PT-P300BT、PT-P710BT)支持官方SDK,低端型号可能仅兼容专属APP。
  • 蓝牙权限要适配系统版本:Android 12+必须添加BLUETOOTH_CONNECT权限,iOS需配置NSBluetoothAlwaysUsageDescription。
  • 预构建后避免手动修改原生文件,后续更新使用npx expo prebuild --clean重新生成。
  • 测试时确保打印机处于可连接状态,且未被其他APP占用。

4. 替代打印机推荐

  • Zebra ZQ系列:支持蓝牙/USB打印,有成熟的React Native第三方库(react-native-zebra-printer),适配Expo预构建工作流。
  • Epson TM-P系列:便携热敏打印机,官方提供完整SDK,可通过原生桥接实现Expo集成。
  • Rollo Wireless:专注标签打印,支持蓝牙连接,提供简单HTTP打印API,无需复杂SDK集成。

内容的提问来源于stack exchange,提问作者ofir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 09:07:42