boot-bixolon-printer
v0.1.4
Published
Eventboot Bixolon Printer Module
Maintainers
Readme
boot-bixolon-printer
빅솔론 라벨 프린터(xq840 SDK)와 POS 프린터(bk5-41 UPOS SDK)를 한 모듈에서 함께 지원하는 Expo Native Module.
| 항목 | 비고 |
| --- | --- |
| 플랫폼 | Android only (iOS 는 stub) |
| 최소 Android | API 23 (Android 6.0) |
| 라벨 SDK | BixolonLabelPrinterLibrary_V2.1.1.jar |
| POS SDK | bixolon_printer_V2.2.10.jar |
| 공통 lib | libcommon_V1.4.4.jar (단일 — 두 SDK 공유) |
| 네이티브 .so | libbxl_common.so × 4 arch (arm64-v8a, armeabi-v7a, x86, x86_64) |
모듈 구성
JS 측에서 호출 가능한 모듈은 4개:
| 모듈 | 용도 |
| --- | --- |
| BootBixolonPrinter | 부트스트랩 (sanity check 용 hello() 만 노출) |
| BootBixolonPrinterLookup | USB/BT/BLE/네트워크 디바이스 통합 검색 + USB 권한 헬퍼 |
| BootBixolonLabelPrinter | BixolonLabelPrinter (xq840) 풀 API 래퍼 |
| BootBixolonPosPrinter | jpos.POSPrinter (bk5-41) 풀 API 래퍼 |
라벨/POS 프록시는 각자 독립된 SDK 인스턴스를 보유하므로 한 앱에서 두 종류의 프린터를 동시에 연결/사용 가능 (예: 영수증 + 라벨 동시 출력).
호스트 앱 설정
이 모듈은 매니페스트와 USB device filter 를 직접 들고 있지 않습니다 — 사용 앱이 정의해야 합니다.
AndroidManifest.xml
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"/>
<uses-feature android:name="android.hardware.usb.host" android:required="false"/>USB 자동 감지 (선택)
USB 케이블 연결 시 시스템이 앱을 자동으로 띄우게 하려면 메인 액티비티에 인텐트 필터를 추가합니다.
<activity ...>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/usb_device_filter"/>
</activity>res/xml/usb_device_filter.xml:
<resources>
<usb-device vendor-id="5380"/> <!-- 0x1504 BIXOLON -->
<usb-device vendor-id="3471"/> <!-- 0x0D8F (구형 일부) -->
</resources>USB 권한 동의는 모듈이 런타임에 처리합니다(requestUSBPermission). 위 인텐트 필터는 자동 감지 UX 용이며 모듈 동작의 필수 조건은 아닙니다.
사용 예
디바이스 검색
import {
BootBixolonPrinterLookup,
parseDeviceList,
} from 'boot-bixolon-printer';
const json = await BootBixolonPrinterLookup.getAllDevices();
const devices = await parseDeviceList(json);
// devices = [
// { interfaceType: 'USB', address: '/dev/bus/usb/001/005', deviceName: '...', vendorId: 5380, ... },
// { interfaceType: 'WIFI', address: '192.168.0.10', port: 9100, ... },
// { interfaceType: 'BLUETOOTH', address: '00:11:22:33:44:55', deviceName: 'BIXOLON SPP-R200III', ... }
// ]라벨 프린터 — 비트맵 1장
import {
BootBixolonLabelPrinter,
LabelMediaType,
LabelSpeed,
} from 'boot-bixolon-printer';
await BootBixolonLabelPrinter.checkAndRequestUSBPermission(usbAddress);
await BootBixolonLabelPrinter.connectUSB(usbAddress);
await BootBixolonLabelPrinter.beginTransactionPrint();
await BootBixolonLabelPrinter.setWidth(640);
await BootBixolonLabelPrinter.setLength(480, 24, LabelMediaType.GAP, 0);
await BootBixolonLabelPrinter.setSpeed(LabelSpeed.IPS_50);
await BootBixolonLabelPrinter.drawBase64Image(base64Png, 0, 0, 640, 0, false);
await BootBixolonLabelPrinter.print(1, 1);
await BootBixolonLabelPrinter.endTransactionPrint();
await BootBixolonLabelPrinter.disconnect();라벨 프린터 — 텍스트 + QR + 바코드 혼합
import { LabelFontSize, LabelQrCodeEcc, LabelBarcode1D, LabelHRI } from 'boot-bixolon-printer';
await BootBixolonLabelPrinter.beginTransactionPrint();
await BootBixolonLabelPrinter.setWidth(640);
await BootBixolonLabelPrinter.setLength(480, 24, LabelMediaType.GAP, 0);
await BootBixolonLabelPrinter.drawText('주문번호 #12345', 20, 20, LabelFontSize.SIZE_15, 1, 1, 0, 0, false, true, 1);
await BootBixolonLabelPrinter.drawQrCode('https://example.com/order/12345', 20, 100, 2, LabelQrCodeEcc.M_15, 6, 0);
await BootBixolonLabelPrinter.draw1dBarcode('1234567890', 20, 250, LabelBarcode1D.CODE128, 2, 4, 60, 0, LabelHRI.BELOW_FONT_SIZE_1, 0);
await BootBixolonLabelPrinter.print(1, 1);
await BootBixolonLabelPrinter.endTransactionPrint();POS 프린터 — 영수증 출력
import {
BootBixolonPosPrinter,
PortType,
PosStation,
POS_CUT_FULL,
POS_PRODUCT_NAME,
} from 'boot-bixolon-printer';
await BootBixolonPosPrinter.checkAndRequestUSBPermission(usbAddress);
const logical = 'BK5-3';
await BootBixolonPosPrinter.setTargetDevice(PortType.USB, logical, POS_PRODUCT_NAME.BK5_3, '');
await BootBixolonPosPrinter.open(logical);
await BootBixolonPosPrinter.claim(5_000);
await BootBixolonPosPrinter.setDeviceEnabled(true);
await BootBixolonPosPrinter.printNormal(PosStation.RECEIPT, '*** 주문 영수증 ***\n');
await BootBixolonPosPrinter.printNormal(PosStation.RECEIPT, '아메리카노 4,500원\n');
await BootBixolonPosPrinter.printNormal(PosStation.RECEIPT, '카페라떼 5,500원\n');
await BootBixolonPosPrinter.printBitmap(PosStation.RECEIPT, base64Logo, 384, -2); // -2 = CENTER
await BootBixolonPosPrinter.printNormal(PosStation.RECEIPT, '\n\n\n');
await BootBixolonPosPrinter.cutPaper(POS_CUT_FULL);
await BootBixolonPosPrinter.setDeviceEnabled(false);
await BootBixolonPosPrinter.release();
await BootBixolonPosPrinter.close();두 프린터 동시 사용
// 라벨과 POS 는 서로 독립이므로 동시 호출 가능
await Promise.all([
printLabelTicket(usbLabelAddr),
printPosReceipt(usbPosAddr),
]);이벤트 구독
import { useEvent } from 'expo';
import { BootBixolonLabelPrinter, BootBixolonPosPrinter } from 'boot-bixolon-printer';
const labelStatus = useEvent(BootBixolonLabelPrinter, 'LabelPrinterStatusEvent');
const posError = useEvent(BootBixolonPosPrinter, 'PosErrorEvent');노출되는 상수
src/constants/ 의 enum/상수를 그대로 import 합니다.
LabelFontSize,LabelRotation,LabelTextAlignment,LabelMediaType,LabelPrintingType,LabelOrientation,LabelSpeed,LabelHRILabelBarcode1D,LabelBarcodeRss,LabelQrCodeModel,LabelQrCodeEcc,LabelPdf417Ecc,LabelMaxicodeModeLabelBlockOption,LabelCircleSize,LabelImageCompression,LabelPrinterInfoType,LabelResponseTypeLABEL_STATUS_BYTE1,LABEL_STATUS_BYTE2PosStation,POS_CUT_FULL,PosAlignment,PosBarcodeTextPosition,PosBarcodeSymbologyPosPageDirection,PosPageModeControl,PosTransactionControl,PosMarkFeedPosCharacterSet,PosStatusUpdate,POS_PRODUCT_NAMEInterfaceType,PortType,DeviceCategoryLabelResultCode,JposErrorCode,USB_PERMISSION_TIMEOUT_DEFAULT_MS
namespace 가져오기도 가능:
import { Label, Pos, Iface } from 'boot-bixolon-printer';
await BootBixolonLabelPrinter.setSpeed(Label.LabelSpeed.IPS_60);
await BootBixolonPosPrinter.setTargetDevice(Iface.PortType.USB, ...);라이브러리 버전 정책
libcommon 은 두 SDK(bk5-41 V1.4.4 / xq840 V1.4.2)에서 클래스 레이아웃이 완전 동일함을 확인하고 V1.4.4 단일 jar 를 채택했습니다. 향후 SDK 업그레이드 시 두 commonlib 버전이 다시 어긋나면 재검증 필요.
boot-printer 와의 차이
기존 boot-printer 모듈은 MPosControllerLabelPrinter (mPOS 변종 V3.0.9) 를 래핑한 라벨 전용입니다. 이 모듈은:
- 공식 빅솔론 SDK (
BixolonLabelPrinter+jpos.POSPrinter) 를 채택 - POS 영수증 프린터 지원 추가
- 패키지 네임스페이스 변경 (
net.eventboot.bootprinter→net.eventboot.bixolon) - 두 모듈을 동시에 호스트 앱에 추가해도
pickFirst 'lib/*/libbxl_common.so'로 .so 충돌을 피하도록 설정
기존 앱에서 boot-printer 와 함께 점진 마이그레이션 가능합니다.
개발
npm install
npm run build
cd example && npm run android매뉴얼:
bixolon-android-sdk/bk5-41/Manual/Manual_BXL_SDK_for_Android_UPOS_compliant_API_Reference_Guide_KOR_V2.30.pdfbixolon-android-sdk/xq840/manual/Manual_Label_Printer_SDK_FOR_Android_API_Reference_Guide_KOR_V1.27.pdf
