Skip to content
rdlabo.dev

@rdlabo/capacitor-brotherprint

Capacitor Brother Print is a native Brother Print SDK implementation for iOS & Android. Support These models.

This plugin is still in the RC (release candidate) phase.

iOS 15 or later is required. Brother does not distribute its SDK through CocoaPods or Swift
Package Manager, so download the SDK and expose the XCFramework as the local package described
below. The plugin supports Capacitor projects that use either package manager.

Supported models

Each product link is an Amazon affiliate link. If you choose to make a purchase through these links, it would be greatly appreciated and would help support development costs. Thank you!

Product Model iOS/WiFi iOS/BT iOS/BLE Android/USB Android/WiFi Android/BT Android/BLE
QL-810W QL_810W
QL-820NWB QL_820NWB ※1
QL-820NWBc QL_820NWB ※2
TD-2320D TD_2320D_203
TD-2350D TD_2350D_300

Amazon Affiliate Links: https://amzn.to/3AiiOFT

Supplement

description
Supported and tested
Implemented but not tested
- Plugin is not supported
Device is not supported
BT Bluetooth
BLE Bluetooth Low Energy

※1 Due to low Bluetooth version, connection is not possible with iOS. Ref: https://okbizcs.okwave.jp/brother/qa/q9932082.html

※2 The iOS/BT implementation for the QL-820NWBc is in place, but it’s uncertain if it functions correctly. It’s unclear whether this is an implementation issue, as Brother’s official app also doesn’t work well.

How to install

% npm install @rdlabo/capacitor-brotherprint

Initialize the Brother SDK

Android configuration

  1. Place the following files in the android folder of your Capacitor project:
  • android/BrotherPrintLibrary/BrotherPrintLibrary.aar
  • android/BrotherPrintLibrary/build.gradle

The BrotherPrintLibrary.aar file is the Brother Print SDK library, which you can download from the Brother website: https://support.brother.co.jp/j/s/es/dev/ja/mobilesdk/android/index.html?c=jp&lang=ja&navi=offall&comple=on&redirect=on#ver4

  1. In the android/BrotherPrintLibrary/build.gradle file, include the following content:
configurations.maybeCreate('default')
artifacts.add('default', file('BrotherPrintLibrary.aar'))
  1. Open android/settings.gradle and add the following lines:
include ':BrotherPrintLibrary'
project(':BrotherPrintLibrary').projectDir = new File('./BrotherPrintLibrary/')

These steps will integrate the Brother Print SDK with your Capacitor Android project.

iOS configuration

  1. Place the following files in the ios folder of your Capacitor project:
  • ios/LocalPackages/BRLMPrinterKit/Sources/BRLMPrinterKit.xcframework
  • ios/LocalPackages/BRLMPrinterKit/BRLMPrinterKit.podspec
  • ios/LocalPackages/BRLMPrinterKit/Package.swift

The BRLMPrinterKit.xcframework file is the Brother Print SDK library, which you can download from the Brother website: https://support.brother.co.jp/j/s/es/dev/ja/mobilesdk/ios/index.html?c=jp&lang=ja&navi=offall&comple=on&redirect=on#ver4

BRLMPrinterKit.podspec content is here:

Pod::Spec.new do |s|
  s.name             = 'BRLMPrinterKit'
  s.version          = '4.12.0'
  s.homepage         = 'https://support.brother.co.jp/j/s/support/html/mobilesdk/index.html'
  s.source           = { :path => './Sources' }
  s.summary          = "Pod for the BRLMPrinterKit / Brother's printers"
  s.description      = "This project is only a Pod for the Brother SDK v#{s.version}"
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'Masahiko Sakakibara' => 'sakakibara@rdlabo.jp' }
  s.ios.deployment_target = '15.0'
  s.ios.vendored_frameworks = 'Sources/BRLMPrinterKit.xcframework'
  s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
  s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
end

Package.swift content is here:

// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "BRLMPrinterKit",
    platforms: [
        .iOS(.v15)
    ],
    products: [
        .library(name: "BRLMPrinterKit", targets: ["BRLMPrinterKit"])
    ],
    targets: [
        .binaryTarget(
            name: "BRLMPrinterKit",
            path: "Sources/BRLMPrinterKit.xcframework"
        )
    ]
)
  1. If your Capacitor project uses CocoaPods, update its ios/App/Podfile.
  target 'App' do
    capacitor_pods
    # Add your Pods here
+   pod 'BRLMPrinterKit', :path => '../LocalPackages/BRLMPrinterKit'
  end

Then run pod update in the ios directory. If your project uses Swift Package Manager, the local
Package.swift above is used instead; run npx cap sync ios after placing the package.

Permission configuration

Android configuration

Update AndroidManifest.xml to include the following permissions:

- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
...
+     <!-- For Bluetooth -->
+     <uses-permission android:name="android.permission.BLUETOOTH" />
+     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+     <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

+     <!-- For Bluetooth Low Energy, Android 11 and earlier-->
+     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

+     <!-- For Bluetooth Low Energy, Android 12 and later -->
+     <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
+         android:usesPermissionFlags="neverForLocation"
+         tools:targetApi="s" />

More information is here: https://support.brother.co.jp/j/s/support/html/mobilesdk/guide/getting-started/getting-started-android.html

iOS configuration

Update Info.plist to include the following permissions:

+ <key>NSBluetoothAlwaysUsageDescription</key>
+ <string>【Why use Bluetooth for your app.】</string>
+ <key>NSBluetoothPeripheralUsageDescription</key>
+ <string>【Why use Bluetooth for your app.】</string>
+ <key>NSBonjourServices</key>
+ <array>
+ 	<string>_pdl-datastream._tcp</string>
+ 	<string>_printer._tcp</string>
+ 	<string>_ipp._tcp</string>
+ </array>
+ <key>NSLocalNetworkUsageDescription</key>
+ <string>【Why use WiFi for your app.】</string>
+ <key>UISupportedExternalAccessoryProtocols</key>
+ <array>
+ 	<string>com.brother.ptcbp</string>
+ </array>

More information is here: https://support.brother.co.jp/j/s/support/html/mobilesdk/guide/getting-started/getting-started-ios.html

How to use

import { Component, OnDestroy, OnInit, signal } from '@angular/core';
import type { PluginListenerHandle } from '@capacitor/core';
import {
  BrotherPrint,
  BrotherPrintEventsEnum,
  BRLMPrinterLabelName,
  BRLMPrinterModelName,
  BRLMPrinterPort,
} from '@rdlabo/capacitor-brotherprint';
import type {
  BRLMChannelResult,
  BRLMPrintOptions,
} from '@rdlabo/capacitor-brotherprint';

@Component({
  selector: 'brother-print',
  templateUrl: 'brother.component.html',
  styleUrls: ['brother.component.scss'],
})
export class BrotherComponent implements OnInit, OnDestroy {
  readonly #listenerHandlers: PluginListenerHandle[] = [];
  readonly printers = signal<BRLMChannelResult[]>([]);

  async ngOnInit() {
    this.#listenerHandlers.push(
      await BrotherPrint.addListener(BrotherPrintEventsEnum.onPrint, () => {
        console.log('onPrint');
      }),
    );
    this.#listenerHandlers.push(
      await BrotherPrint.addListener(
        BrotherPrintEventsEnum.onPrintError,
        info => {
          console.log('onPrintError');
        },
      ),
    );
    this.#listenerHandlers.push(
      await BrotherPrint.addListener(
        BrotherPrintEventsEnum.onPrintFailedCommunication,
        info => {
          console.log('onPrintFailedCommunication');
        },
      ),
    );
    this.#listenerHandlers.push(
      await BrotherPrint.addListener(
        BrotherPrintEventsEnum.onPrinterAvailable,
        printer => {
          this.printers.update(prev => [...prev, printer]);
        },
      ),
    );
  }

  async ngOnDestroy() {
    this.#listenerHandlers.forEach(handler => handler.remove());
  }

  async searchPrinter(port: BRLMPrinterPort) {
    // This method return void. Get the printer list by listening to the event.
    await BrotherPrint.search({
      port,
      searchDuration: 15, // seconds
    });
  }

  print() {
    if (this.printers().length === 0) {
      console.error('No printer found');
      return;
    }

    const defaultPrintSettings: BRLMPrintOptions = {
      modelName: BRLMPrinterModelName.QL_820NWB,
      labelName: BRLMPrinterLabelName.RollW62,
      encodedImage: 'base64 removed mime-type', // base64
      numberOfCopies: 1, // default 1
      autoCut: true, // default true
    };

    BrotherPrint.printImage({
      ...defaultPrintSettings,
      ...{
        port: this.printers()[0].port,
        channelInfo: this.printers()[0].channelInfo,
      },
    });
  }
}

See demo for complete code:
https://github.com/rdlabo-dev/capacitor-brotherprint/blob/v8.1.1/demo/src/app/home/home.page.tshttps://github.com/rdlabo-dev/capacitor-brotherprint/blob/v8.1.1/demo/src/app/home/home.page.ts

API

<docgen-index>

</docgen-index>

<docgen-api>

printImage(...)

printImage(options: BRLMPrintOptions) => Promise<void>
Param Type
options <code><a href="#brlmprintoptions">BRLMPrintOptions</a></code>

search(...)

search(option: BRLMSearchOption) => Promise<void>

Search for printers. If not found, it will return an empty array.(not error)

Param Type
option <code><a href="#brlmsearchoption">BRLMSearchOption</a></code>

isChannelAvailable(...)

isChannelAvailable(option: BRLMChannelResult) => Promise<isChannelAvailableResult>

If you have saved the last connected <a href="#brlmchannelresult">BRLMChannelResult</a>,
you can use it to verify whether it is currently usable.

Param Type
option <code><a href="#brlmchannelresult">BRLMChannelResult</a></code>

Returns: <code>Promise<<a href="#ischannelavailableresult">isChannelAvailableResult</a>></code>


cancelSearchWiFiPrinter()

cancelSearchWiFiPrinter() => Promise<void>

Basically, it times out, so there is no need to use it. Use it when you want to run multiple connectType searches at the same time and time out any of them manually.


cancelSearchBluetoothPrinter()

cancelSearchBluetoothPrinter() => Promise<void>

Basically, it times out, so there is no need to use it. Use it when you want to run multiple connectType searches at the same time and time out any of them manually.


addListener(BrotherPrintEventsEnum.onPrinterAvailable, ...)

addListener(eventName: BrotherPrintEventsEnum.onPrinterAvailable, listenerFunc: (printers: BRLMChannelResult) => void) => Promise<PluginListenerHandle>

Find the printer that can connected to the device.

Param Type
eventName <code><a href="#brotherprinteventsenum">BrotherPrintEventsEnum.onPrinterAvailable</a></code>
listenerFunc <code>(printers: <a href="#brlmchannelresult">BRLMChannelResult</a>) => void</code>

Returns: <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>


addListener(BrotherPrintEventsEnum.onPrint, ...)

addListener(eventName: BrotherPrintEventsEnum.onPrint, listenerFunc: () => void) => Promise<PluginListenerHandle>

Success Print Event

Param Type
eventName <code><a href="#brotherprinteventsenum">BrotherPrintEventsEnum.onPrint</a></code>
listenerFunc <code>() => void</code>

Returns: <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>


addListener(BrotherPrintEventsEnum.onPrintFailedCommunication, ...)

addListener(eventName: BrotherPrintEventsEnum.onPrintFailedCommunication, listenerFunc: (info: ErrorInfo) => void) => Promise<PluginListenerHandle>

Failed to connect to the printer.
ex: Bluetooth is off, Printer is off, etc.

Param Type
eventName <code><a href="#brotherprinteventsenum">BrotherPrintEventsEnum.onPrintFailedCommunication</a></code>
listenerFunc <code>(info: <a href="#errorinfo">ErrorInfo</a>) => void</code>

Returns: <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>


addListener(BrotherPrintEventsEnum.onPrintError, ...)

addListener(eventName: BrotherPrintEventsEnum.onPrintError, listenerFunc: (info: ErrorInfo) => void) => Promise<PluginListenerHandle>

Failed to print.

Param Type
eventName <code><a href="#brotherprinteventsenum">BrotherPrintEventsEnum.onPrintError</a></code>
listenerFunc <code>(info: <a href="#errorinfo">ErrorInfo</a>) => void</code>

Returns: <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>


Interfaces

PluginListenerHandle

Prop Type
remove <code>() => Promise<void></code>

Type Aliases

BRLMPrintOptions

<code>{ encodedImage: string; /** * Should use enum <a href="#brlmprintermodelname">BRLMPrinterModelName</a> */ modelName: <a href="#brlmprintermodelname">BRLMPrinterModelName</a>; } & <a href="#partial">Partial</a><<a href="#brlmchannelresult">BRLMChannelResult</a>> & (<a href="#brlmprinterqlmodelsettings">BRLMPrinterQLModelSettings</a> | <a href="#brlmprintertdmodelsettings">BRLMPrinterTDModelSettings</a>)</code>

Partial

Make all properties in T optional

<code>{
[P in keyof T]?: T[P];
}</code>

BRLMChannelResult

<code>{ port: <a href="#brlmprinterport">BRLMPrinterPort</a>; modelName: string; serialNumber: string; macAddress: string; nodeName: string; location: string; /** * This need to connect to the printer. * wifi: IP Address * bluetooth: macAddress * bluetoothLowEnergy: modelName for bluetoothLowEnergy */ channelInfo: string; }</code>

BRLMPrinterQLModelSettings

<code>{ /** * Should use enum <a href="#brlmprinterlabelname">BRLMPrinterLabelName</a> */ labelName: <a href="#brlmprinterlabelname">BRLMPrinterLabelName</a>; } & <a href="#brlmprintersettings">BRLMPrinterSettings</a></code>

BRLMPrinterSettings

These are optional. If these are not set, default values are assigned by the printer.

<code>{ /** * The number of copies you print. / numberOfCopies?: <a href="#brlmprinternumberofcopies">BRLMPrinterNumberOfCopies</a>; /* * Whether the auto-cut is enabled or not. If true, your printer cut the paper each page. / autoCut?: <a href="#brlmprinterautocuttype">BRLMPrinterAutoCutType</a>; /* * A scale mode that specifies how your data is scaled in a print area of your printer. / scaleMode?: <a href="#brlmprinterscalemode">BRLMPrinterScaleMode</a>; /* * A scale value. This is effective when ScaleMode is ScaleValue. / scaleValue?: <a href="#brlmprinterscalevaluetype">BRLMPrinterScaleValueType</a>; /* * A way to rasterize your data. / halftone?: <a href="#brlmprinterhalftone">BRLMPrinterHalftone</a>; /* * A threshold value. This is effective when the Halftone is Threshold. / halftoneThreshold?: <a href="#brlmprinterhalftonethresholdtype">BRLMPrinterHalftoneThresholdType</a>; /* * An image rotation that specifies the angle in which your data is placed in the print area. Rotation direction is clockwise. / imageRotation?: <a href="#brlmprinterimagerotation">BRLMPrinterImageRotation</a>; /* * A vertical alignment that specifies how your data is placed in the printable area. / verticalAlignment?: <a href="#brlmprinterverticalalignment">BRLMPrinterVerticalAlignment</a>; /* * A horizontal alignment that specifies how your data is placed in the printable area. / horizontalAlignment?: <a href="#brlmprinterhorizontalalignment">BRLMPrinterHorizontalAlignment</a>; /* * A compress mode that specifies how to compress your data. * note: This is ios only. / compressMode?: <a href="#brlmprintercompressmode">BRLMPrinterCompressMode</a>; /* * A priority that is print speed or print quality. Whether or not this has an effect is depend on your printer. */ printQuality?: <a href="#brlmprinterprintquality">BRLMPrinterPrintQuality</a>; }</code>

BRLMPrinterNumberOfCopies

<code>number</code>

BRLMPrinterAutoCutType

<code>boolean</code>

BRLMPrinterScaleValueType

<code>number</code>

BRLMPrinterHalftoneThresholdType

<code>number</code>

BRLMPrinterTDModelSettings

<code>{ /** * Should use enum BRLMPrinterCustomPaperType / paperType: <a href="#brlmprintercustompapertype">BRLMPrinterCustomPaperType</a>; /* * The width of the label. For example, the RD-U04J1 is 60.0 wide. / tapeWidth: number; /* * The length of the label. For example, the RD-U04J1 is 60.0 wide. / tapeLength: number; /* * It is the difference between a sticker and a mount. * For example, the RD-U04J1 is 1.0, 2.0, 1.0, 2.0 / marginTop: number; marginRight: number; marginBottom: number; marginLeft: number; /* * The spacing between seals. For example, the RD-U04J1 is 0.2. / gapLength: number; paperMarkPosition: number; paperMarkLength: number; /* * Should use enum BRLMPrinterCustomPaperUnit. * For example, the RD-U04J1 is mm. */ paperUnit: <a href="#brlmprintercustompaperunit">BRLMPrinterCustomPaperUnit</a>; }</code>

BRLMSearchOption

<code>{ /** * 'usb' is android only, and now developing. / port: <a href="#brlmprinterport">BRLMPrinterPort</a>; /* * searchDuration is the time to end search for devices. * default is 15 seconds. * use only port is 'wifi' or 'bluetoothLowEnergy'. */ searchDuration: number; }</code>

isChannelAvailableResult

<code>{ result: boolean; }</code>

ErrorInfo

<code>{ message: string; code: number; }</code>

Enums

BRLMPrinterModelName

Members Value
QL_800 <code>'QL_800'</code>
QL_810W <code>'QL_810W'</code>
QL_820NWB <code>'QL_820NWB'</code>
TD_2320D_203 <code>'TD_2320D_203'</code>
TD_2030AD <code>'TD_2030AD'</code>
TD_2350D_300 <code>'TD_2350D_300'</code>

BRLMPrinterPort

Members Value
usb <code>'usb'</code>
wifi <code>'wifi'</code>
bluetooth <code>'bluetooth'</code>
bluetoothLowEnergy <code>'bluetoothLowEnergy'</code>

BRLMPrinterLabelName

Members Value Description
DieCutW17H54 <code>'DieCutW17H54'</code>
DieCutW17H87 <code>'DieCutW17H87'</code>
DieCutW23H23 <code>'DieCutW23H23'</code>
DieCutW29H42 <code>'DieCutW29H42'</code>
DieCutW29H90 <code>'DieCutW29H90'</code>
DieCutW38H90 <code>'DieCutW38H90'</code>
DieCutW39H48 <code>'DieCutW39H48'</code>
DieCutW52H29 <code>'DieCutW52H29'</code>
DieCutW62H29 <code>'DieCutW62H29'</code>
DieCutW62H60 <code>'DieCutW62H60'</code>
DieCutW62H75 <code>'DieCutW62H75'</code>
DieCutW62H100 <code>'DieCutW62H100'</code>
DieCutW60H86 <code>'DieCutW60H86'</code>
DieCutW54H29 <code>'DieCutW54H29'</code>
DieCutW102H51 <code>'DieCutW102H51'</code>
DieCutW102H152 <code>'DieCutW102H152'</code>
DieCutW103H164 <code>'DieCutW103H164'</code>
RollW12 <code>'RollW12'</code>
RollW29 <code>'RollW29'</code>
RollW38 <code>'RollW38'</code>
RollW50 <code>'RollW50'</code>
RollW54 <code>'RollW54'</code>
RollW62 <code>'RollW62'</code>
RollW62RB <code>'RollW62RB'</code>
RollW102 <code>'RollW102'</code>
RollW103 <code>'RollW103'</code>
DTRollW90 <code>'DTRollW90'</code>
DTRollW102 <code>'DTRollW102'</code>
DTRollW102H51 <code>'DTRollW102H51'</code>
DTRollW102H152 <code>'DTRollW102H152'</code>
RoundW12DIA <code>'RoundW12DIA'</code>
RoundW24DIA <code>'RoundW24DIA'</code>
RoundW58DIA <code>'RoundW58DIA'</code>
RDDieCutW60H60 <code>'RDDieCutW60H60'</code> For TD series
RDDieCutW50H30 <code>'RDDieCutW50H30'</code>
RDDieCutW40H60 <code>'RDDieCutW40H60'</code>
RDDieCutW40H50 <code>'RDDieCutW40H50'</code>
RDDieCutW40H40 <code>'RDDieCutW40H40'</code>
RDDieCutW30H30 <code>'RDDieCutW30H30'</code>
RDDieCutW50H35 <code>'RDDieCutW50H35'</code>
RDDieCutW60H80 <code>'RDDieCutW60H80'</code>
RDDieCutW60H100 <code>'RDDieCutW60H100'</code>

BRLMPrinterScaleMode

Members Value
ActualSize <code>'ActualSize'</code>
FitPageAspect <code>'FitPageAspect'</code>
FitPaperAspect <code>'FitPaperAspect'</code>
ScaleValue <code>'ScaleValue'</code>

BRLMPrinterHalftone

Members Value
Threshold <code>'Threshold'</code>
ErrorDiffusion <code>'ErrorDiffusion'</code>
PatternDither <code>'PatternDither'</code>

BRLMPrinterImageRotation

Members Value
Rotate0 <code>'Rotate0'</code>
Rotate90 <code>'Rotate90'</code>
Rotate180 <code>'Rotate180'</code>
Rotate270 <code>'Rotate270'</code>

BRLMPrinterVerticalAlignment

Members Value
Top <code>'Top'</code>
Center <code>'Center'</code>
Bottom <code>'Bottom'</code>

BRLMPrinterHorizontalAlignment

Members Value
Left <code>'Left'</code>
Center <code>'Center'</code>
Right <code>'Right'</code>

BRLMPrinterCompressMode

Members Value
None <code>'None'</code>
Tiff <code>'Tiff'</code>
Mode9 <code>'Mode9'</code>

BRLMPrinterPrintQuality

Members Value
Best <code>'Best'</code>
Fast <code>'Fast'</code>

BRLMPrinterCustomPaperType

Members Value
rollPaper <code>'rollPaper'</code>
dieCutPaper <code>'dieCutPaper'</code>
markRollPaper <code>'markRollPaper'</code>

BRLMPrinterCustomPaperUnit

Members Value
mm <code>'mm'</code>
inch <code>'inch'</code>

BrotherPrintEventsEnum

Members Value
onPrinterAvailable <code>'onPrinterAvailable'</code>
onPrint <code>'onPrint'</code>
onPrintFailedCommunication <code>'onPrintFailedCommunication'</code>
onPrintError <code>'onPrintError'</code>

</docgen-api>