Skip to content

A comprehensive Cordova plugin that provides cross-platform Bluetooth thermal printer functionality for iOS and Android applications. Supports ESC/POS printing protocols with advanced features for text, images, barcodes, and QR codes.

Notifications You must be signed in to change notification settings

kikwaib/BluetoothPrinter

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

46 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Cordova Bluetooth Printer Plugin

A comprehensive Cordova plugin that provides cross-platform Bluetooth thermal printer functionality for iOS and Android applications. Supports ESC/POS printing protocols with advanced features for text, images, barcodes, and QR codes.

Note: This plugin is a fork of lynzz/BluetoothPrinter with enhanced cross-platform support, modern Android permissions, and comprehensive documentation.

NPM License: MIT

πŸš€ Features

  • βœ… Cross-platform support - iOS & Android
  • βœ… Multiple Bluetooth protocols - Bluetooth Classic (Android) and Bluetooth Low Energy (iOS)
  • βœ… ESC/POS thermal printer compatibility
  • βœ… Rich content printing - Text, images, barcodes, QR codes
  • βœ… Builder pattern for complex print jobs
  • βœ… Automatic image processing and optimization
  • βœ… Multiple font sizes and alignment options
  • βœ… Paper cutting support
  • βœ… Connection management with auto-reconnect
  • βœ… Configurable paper width (58mm/80mm)

πŸ“¦ Installation

cordova plugin add @kikwaib/cordova-plugin-bluetooth-printer

πŸ”§ Platform Requirements

Android

  • Minimum SDK: 19 (Android 4.4+)
  • Target SDK: 33
  • Permissions: Bluetooth, Location (for device discovery)
  • Bluetooth: Classic SPP profile (00001101-0000-1000-8000-00805F9B34FB)

iOS

  • iOS Version: 9.0+
  • Framework: Core Bluetooth
  • Bluetooth: Low Energy (BLE)
  • Background modes: Bluetooth peripheral connections

⚠️ Android 12+ Important Notes

For Android 12 (API level 31) and above, additional runtime permissions are required:

  • BLUETOOTH_SCAN - for discovering nearby Bluetooth devices
  • BLUETOOTH_CONNECT - for connecting to Bluetooth devices
  • ACCESS_FINE_LOCATION - required for Bluetooth scanning

These permissions are automatically added to your AndroidManifest.xml, but you must request them at runtime:

// Request permissions (you may need cordova-plugin-android-permissions)
cordova.plugins.permissions.requestPermissions(
  [
    cordova.plugins.permissions.BLUETOOTH_SCAN,
    cordova.plugins.permissions.BLUETOOTH_CONNECT,
    cordova.plugins.permissions.ACCESS_FINE_LOCATION,
  ],
  success,
  error
);

πŸ“š API Reference

Core Methods

Device Management

// Scan for available printers
printerHelper.scanForPeripherals(success, error, keepScanning);

// Stop scanning
printerHelper.stopScan(success, error);

// Get discovered devices
printerHelper.getDeviceList(success, error);

// Connect to a specific printer
printerHelper.connectPeripheral(success, error, deviceId);

// Check connection status
printerHelper.isConnectPeripheral(success, error);

// Auto-connect to previously connected device
printerHelper.autoConnectPeripheral(success, error);

// Disconnect
printerHelper.stopConnection(success, error);

Configuration

// Set paper width (58mm or 80mm)
printerHelper.setPrinterPageWidth(success, error, width);

// Get current paper width
printerHelper.getCurrentSetPageWidth(success, error);

// Set maximum length for first column in multi-column layouts
printerHelper.setFirstRankMaxLength(success, error, text3, text4);

Print Job Builder (PrinterInfoHelper)

The plugin uses a builder pattern for constructing complex print jobs:

Basic Usage

// Reset the print job
printerInfoHelper.resetInfos();

// Add various content types
printerInfoHelper.appendText(
  "Hello World",
  BTPAlignmentType.center,
  BTPFontType.middle
);
printerInfoHelper.appendImage(base64ImageData, 300, BTPAlignmentType.center);
printerInfoHelper.appendBarCode("123456789", 300, BTPAlignmentType.center);
printerInfoHelper.appendQrCode(
  "https://example.com",
  12,
  BTPAlignmentType.center
);
printerInfoHelper.appendSeperatorLine();
printerInfoHelper.appendSpaceLine();
printerInfoHelper.appendCutpage();

// Execute the print job
var jsonString = printerInfoHelper.getPrinterInfoJsonString();
printerHelper.setPrinterInfoAndPrinter(success, error, jsonString);

Content Types

Text Printing
// Simple text
printerInfoHelper.appendText(text, alignment, fontType);

// Multi-column lists
printerInfoHelper.appendTextList(
  ["Item", "Price", "Qty"],
  1,
  BTPFontType.middle
); // Header
printerInfoHelper.appendTextList(["Coffee", "$3.50", "2"], 0); // Data row
Image Printing
// Print base64 encoded images (JPEG/PNG)
printerInfoHelper.appendImage(base64ImageData, maxWidth, alignment);
Barcode Printing
// Print 1D barcodes
printerInfoHelper.appendBarCode(data, maxWidth, alignment);
QR Code Printing
// Print QR codes (size 1-16)
printerInfoHelper.appendQrCode(data, size, alignment);
Layout Elements
// Separator line (dashes)
printerInfoHelper.appendSeperatorLine();

// Empty line
printerInfoHelper.appendSpaceLine();

// Paper cut command
printerInfoHelper.appendCutpage();

// Footer text
printerInfoHelper.appendFooter(text);

Constants

Font Types (BTPFontType)

BTPFontType.smalle; // 0 - Small font
BTPFontType.middle; // 1 - Medium font
BTPFontType.big; // 2 - Large font
BTPFontType.big3; // 3 - Extra large
BTPFontType.big4; // 4 - XXL
BTPFontType.big5; // 5 - XXXL
BTPFontType.big6; // 6 - XXXXL
BTPFontType.big7; // 7 - XXXXXL
BTPFontType.big8; // 8 - XXXXXXL

Alignment Types (BTPAlignmentType)

BTPAlignmentType.left; // 0 - Left aligned
BTPAlignmentType.center; // 1 - Center aligned
BTPAlignmentType.right; // 2 - Right aligned

Info Types (BTPInfoType)

BTPInfoType.text; // 0 - Plain text
BTPInfoType.textList; // 1 - Multi-column list
BTPInfoType.barCode; // 2 - 1D Barcode
BTPInfoType.qrCode; // 3 - QR Code
BTPInfoType.image; // 4 - Image
BTPInfoType.seperatorLine; // 5 - Separator line
BTPInfoType.spaceLine; // 6 - Empty line
BTPInfoType.footer; // 7 - Footer text
BTPInfoType.cutpage; // 8 - Paper cut

πŸ’‘ Usage Examples

Simple Receipt

function printSimpleReceipt() {
  printerInfoHelper.resetInfos();

  // Header
  printerInfoHelper.appendText(
    "COFFEE SHOP",
    BTPAlignmentType.center,
    BTPFontType.big
  );
  printerInfoHelper.appendText(
    "123 Main St",
    BTPAlignmentType.center,
    BTPFontType.smalle
  );
  printerInfoHelper.appendSeperatorLine();

  // Items
  printerInfoHelper.appendTextList(["Item", "Price"], 1);
  printerInfoHelper.appendTextList(["Coffee", "$3.50"]);
  printerInfoHelper.appendTextList(["Muffin", "$2.25"]);
  printerInfoHelper.appendSeperatorLine();

  // Total
  printerInfoHelper.appendTextList(["Total:", "$5.75"]);
  printerInfoHelper.appendSpaceLine();

  // Footer
  printerInfoHelper.appendText("Thank you!", BTPAlignmentType.center);
  printerInfoHelper.appendCutpage();

  // Print
  var jsonString = printerInfoHelper.getPrinterInfoJsonString();
  printerHelper.setPrinterInfoAndPrinter(printSuccess, printError, jsonString);
}

Advanced Receipt with QR Code

function printAdvancedReceipt() {
  printerInfoHelper.resetInfos();

  // Logo/Image
  printerInfoHelper.appendImage(logoBase64, 200, BTPAlignmentType.center);

  // Store info
  printerInfoHelper.appendText(
    "RESTAURANT NAME",
    BTPAlignmentType.center,
    BTPFontType.middle
  );
  printerInfoHelper.appendText("Order #12345", BTPAlignmentType.center);
  printerInfoHelper.appendText("Date: " + new Date().toLocaleDateString());
  printerInfoHelper.appendSeperatorLine();

  // Items with quantities
  printerInfoHelper.appendTextList(
    ["Item", "Qty", "Price"],
    1,
    BTPFontType.smalle
  );
  printerInfoHelper.appendTextList(["Burger", "2", "$15.98"]);
  printerInfoHelper.appendTextList(["Fries", "1", "$4.50"]);
  printerInfoHelper.appendTextList(["Drink", "2", "$6.00"]);
  printerInfoHelper.appendSeperatorLine();

  // Totals
  printerInfoHelper.appendTextList(["Subtotal:", "$26.48"]);
  printerInfoHelper.appendTextList(["Tax:", "$2.38"]);
  printerInfoHelper.appendTextList(["Total:", "$28.86"], 0, BTPFontType.middle);
  printerInfoHelper.appendSpaceLine();

  // Payment method
  printerInfoHelper.appendText("Paid: Credit Card");
  printerInfoHelper.appendSpaceLine();

  // QR code for receipt verification
  printerInfoHelper.appendQrCode(
    "https://restaurant.com/receipt/12345",
    8,
    BTPAlignmentType.center
  );

  // Footer
  printerInfoHelper.appendText(
    "Thank you for your visit!",
    BTPAlignmentType.center
  );
  printerInfoHelper.appendText("Please come again", BTPAlignmentType.center);
  printerInfoHelper.appendCutpage();

  var jsonString = printerInfoHelper.getPrinterInfoJsonString();
  printerHelper.setPrinterInfoAndPrinter(printSuccess, printError, jsonString);
}

Barcode Label

function printBarcodeLabel() {
  printerInfoHelper.resetInfos();

  printerInfoHelper.appendText(
    "PRODUCT LABEL",
    BTPAlignmentType.center,
    BTPFontType.middle
  );
  printerInfoHelper.appendSpaceLine();

  printerInfoHelper.appendText("Product: Coffee Beans", BTPAlignmentType.left);
  printerInfoHelper.appendText("SKU: CB001", BTPAlignmentType.left);
  printerInfoHelper.appendText("Price: $12.99", BTPAlignmentType.left);
  printerInfoHelper.appendSpaceLine();

  // Barcode
  printerInfoHelper.appendBarCode(
    "1234567890123",
    250,
    BTPAlignmentType.center
  );
  printerInfoHelper.appendCutpage();

  var jsonString = printerInfoHelper.getPrinterInfoJsonString();
  printerHelper.setPrinterInfoAndPrinter(printSuccess, printError, jsonString);
}

πŸ” Device Discovery & Connection

// Start scanning for printers
function startScan() {
  printerHelper.scanForPeripherals(
    function (devices) {
      console.log("Found devices:", devices);
      // devices is an array: [{"name":"Printer_2EC1","uuid":"9A87E98E-BE88-5BA6-2C31-ED4869300E6E"}]
      displayDeviceList(devices);
    },
    function (error) {
      console.error("Scan error:", error);
    },
    1 // Keep scanning (1) or scan once (0)
  );
}

// Connect to selected printer
function connectToPrinter(deviceId) {
  printerHelper.connectPeripheral(
    function (success) {
      console.log("Connected successfully");
      // Ready to print
    },
    function (error) {
      console.error("Connection failed:", error);
    },
    deviceId
  );
}

// Check if still connected
function checkConnection() {
  printerHelper.isConnectPeripheral(
    function (status) {
      console.log("Connection status:", status); // "1" = connected, "0" = disconnected
    },
    function (error) {
      console.error("Status check failed:", error);
    }
  );
}

🎯 Framework Integration Examples

Quasar Framework & Vue.js

For complete Quasar Framework and Vue.js integration examples, see the examples/quasar-vuejs/ directory.

This example includes:

  • 🎯 Vue 3 Composition API - Modern, reusable usePrinter composable
  • πŸ“± Quasar Components - Complete PrinterManager component with beautiful UI
  • πŸ”„ Reactive State Management - Real-time connection status and device management
  • ⚑ Error Handling - User-friendly notifications and loading states
  • πŸ“‹ Permission Management - Automatic Android 12+ permission handling
  • πŸ§ͺ Test Interface - Built-in receipt and image printing functionality

Quick start:

cd examples/quasar-vuejs/
npm install
quasar dev -m cordova -T android

Other Frameworks

We welcome contributions for other popular frameworks! Consider submitting examples for:

  • React Native with Expo
  • Ionic Framework with Angular/React
  • Flutter with native plugins
  • PhoneGap/Apache Cordova vanilla JavaScript

πŸ–ΌοΈ Image Processing

The plugin automatically processes images for optimal thermal printing:

Android Image Processing

  • Converts images to 1-bit monochrome
  • Removes transparency (adds white background)
  • Resizes to fit printer width (typically 240px)
  • Optimizes for 24-dot ESC/POS commands

iOS Image Processing

  • Grayscale conversion using standard weights (0.3R + 0.59G + 0.11B)
  • Automatic bitmap context creation
  • Built-in Base64 encoding/decoding

Image Requirements

  • Format: JPEG or PNG
  • Encoding: Base64 string with data URI prefix
  • Width: Recommended 240px or 384px (58mm/80mm printers)
  • Height: Should be divisible by 24 pixels for best results
// Image with data URI prefix
var imageData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAL...";
printerInfoHelper.appendImage(imageData, 240, BTPAlignmentType.center);

πŸ› οΈ Technical Details

ESC/POS Commands

The plugin generates standard ESC/POS commands:

  • Text printing: Direct byte array transmission with GBK encoding (Android)
  • Image printing: ESC * n nL nH [bitmap data] commands
  • Formatting: ESC commands for alignment, fonts, line spacing
  • Paper cutting: ESC m command for automatic cutter

Bluetooth Protocols

  • Android: Bluetooth Classic with SPP profile
  • iOS: Bluetooth Low Energy with automatic service/characteristic discovery
  • Connection management: Auto-reconnect and connection status monitoring

Memory Management

  • Android: Pre-allocated buffers for bitmap processing (width * height / 8 + 1000)
  • iOS: Proper CGContext and CGImage lifecycle management
  • Data chunking: Automatic data splitting for BLE characteristics

πŸ› Troubleshooting

Common Issues

  1. Print Quality Problems

    • Ensure image dimensions are multiples of 8/24 pixels
    • Check bitmap conversion maintains proper contrast
    • Verify ESC/POS commands match printer specifications
  2. Bluetooth Connection Issues

    • Android: Verify UUID compatibility (00001101-0000-1000-8000-00805F9B34FB)
    • iOS: Check service and characteristic UUIDs match printer
    • Handle connection timeouts and implement retry logic
  3. Permission Issues (Android 12+)

    • Request runtime permissions for BLUETOOTH_SCAN, BLUETOOTH_CONNECT, ACCESS_FINE_LOCATION
    • Check that location services are enabled on the device
  4. Character Encoding Issues

    • Android: Plugin handles UTF-8 β†’ GBK conversion automatically
    • Special characters may not display correctly on all printers

Debug Mode

// Enable debug logging (iOS)
printerHelper.printOCLog(
  function (success) {
    console.log("Debug:", success);
  },
  function (error) {
    console.error("Debug error:", error);
  },
  "Your debug message"
);

πŸ“„ License

MIT License - see LICENSE for details.

🀝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“ž Support

🏷️ Version History

See Releases for version history and changelog.

About

A comprehensive Cordova plugin that provides cross-platform Bluetooth thermal printer functionality for iOS and Android applications. Supports ESC/POS printing protocols with advanced features for text, images, barcodes, and QR codes.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Objective-C 60.1%
  • Java 32.6%
  • JavaScript 5.5%
  • C 1.8%