easy_blue_printer 2.2.0 copy "easy_blue_printer: ^2.2.0" to clipboard
easy_blue_printer: ^2.2.0 copied to clipboard

The **Easy Blue Printer** plugin allows seamless integration of Bluetooth printers in a Flutter app, enabling the scanning, connection, and printing functionality.

Easy Blue Printer #

pub package license platform

A Flutter plugin for Bluetooth thermal printers. Scan, connect, and print text or images with just a few lines of code.

English | Portugues


English #

Features #

  • Scan nearby Bluetooth devices
  • Connect and disconnect from printers
  • Print text with font size, alignment, and bold options
  • Print images from bytes
  • Print empty lines (paper feed)
  • Check connection status
  • Configure paper roll size (58mm, 80mm, or custom) for accurate image printing
  • Built-in print queue — sequential, non-concurrent writes with no manual delays needed
  • Works on Android and iOS

Supported Platforms #

Platform Minimum Version
Android SDK 24 (7.0)
iOS 13.0
Flutter 3.44.0
Dart 3.12.0

On iOS the plugin ships both a Swift Package (ios/easy_blue_printer/Package.swift) and a CocoaPods podspec, so it works with either integration — no extra setup required.

On Android the plugin uses Built-in Kotlin: it no longer applies the Kotlin Gradle Plugin, so it does not trigger the plugins that apply Kotlin Gradle Plugin (KGP) build warning.

Installation #

Add to your pubspec.yaml:

dependencies:
  easy_blue_printer: ^latest_version

Then run:

flutter pub get

Platform Setup #

Android #

Add these permissions to android/app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <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" />

    <application ...>

On Android 12+ the plugin automatically requests runtime permissions.

iOS #

Add these keys to ios/Runner/Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth to connect to printers</string>

<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs Bluetooth to connect to printers</string>

Quick Start #

import 'package:easy_blue_printer/easy_blue_printer.dart';

final printer = EasyBluePrinter.instance;

// 1. Scan for devices
final devices = await printer.getPairedDevices();

// 2. Connect to a device
final connected = await printer.connectToDevice(devices.first);

// 3. Configure paper roll size (call once after connecting)
await printer.configurePrinter(PaperConfig.roll80mm); // or PaperConfig.roll58mm

// 4. Print text
await printer.printData(
  data: 'Hello, World!',
  fontSize: FS.medium,
  textAlign: TA.center,
  bold: true,
);

// 5. Feed paper
await printer.printEmptyLine(callTimes: 5);

// 6. Disconnect
await printer.disconnectFromDevice();

API Reference #

EasyBluePrinter.instance #

Singleton instance. Use this to access all methods.


getPairedDevices() #

Scans and returns a list of available Bluetooth devices.

Future<List<BluetoothDevice>> getPairedDevices()

Returns: List of BluetoothDevice objects with name and address properties.


connectToDevice(device) #

Connects to a Bluetooth printer.

Future<bool> connectToDevice(BluetoothDevice device)
Parameter Type Description
device BluetoothDevice Device returned by getPairedDevices()

Returns: true if connected successfully.


disconnectFromDevice() #

Disconnects from the current printer.

Future<bool> disconnectFromDevice()

Returns: true if disconnected successfully.


printData(...) #

Prints formatted text.

Future<bool> printData({
  required String data,
  required FS fontSize,
  required TA textAlign,
  required bool bold,
})
Parameter Type Description
data String Text to print
fontSize FS Font size (see Enums)
textAlign TA Alignment (see Enums)
bold bool Enable bold text

Returns: true if printed successfully.


printEmptyLine(callTimes) #

Feeds paper by printing empty lines.

Future<void> printEmptyLine({required int callTimes})
Parameter Type Description
callTimes int Number of empty lines to print

printImage(bytes, textAlign) #

Prints an image on the thermal printer.

Future<bool> printImage({
  required Uint8List bytes,
  required TA textAlign,
})
Parameter Type Description
bytes Uint8List Image data as bytes
textAlign TA Image alignment (see Enums)

Returns: true if printed successfully.

Example — print from assets:

import 'package:flutter/services.dart';

final byteData = await rootBundle.load('assets/images/logo.png');
final bytes = byteData.buffer.asUint8List();

await printer.printImage(bytes: bytes, textAlign: TA.center);

configurePrinter(config) #

Configures the paper roll size used when printing images. Call this once after connecting to the printer.

Future<void> configurePrinter(PaperConfig config)
Parameter Type Description
config PaperConfig Paper roll configuration

Example:

// 58mm roll (default)
await printer.configurePrinter(PaperConfig.roll58mm);

// 80mm roll
await printer.configurePrinter(PaperConfig.roll80mm);

// Custom width in pixels
await printer.configurePrinter(PaperConfig(widthPixels: 480));

Only affects printImage. Text printing is handled by the printer firmware and does not require this configuration.


isConnected() #

Checks if a printer is currently connected.

Future<bool> isConnected()

Returns: true if connected.


commandDelay #

Configurable delay applied between consecutive print commands. The built-in queue already serializes all commands; this delay gives the printer extra time to process each command before the next one arrives.

Duration commandDelay  // default: Duration(milliseconds: 100)

Example:

// Increase for slower printers that still show corrupted output
printer.commandDelay = const Duration(milliseconds: 150);

// Disable for fast printers that don't need it
printer.commandDelay = Duration.zero;

Only applies between queued print commands. Does not add latency after the last command in a batch.


Enums #

FS — Font Size #

Value Description
FS.normal Normal size
FS.medium Medium size
FS.large Large size
FS.huge Extra large

TA — Text Alignment #

Value Description
TA.left Left align
TA.center Center align
TA.right Right align

PaperConfig — Paper Roll Size #

Value / Constructor Width Description
PaperConfig.roll58mm 384 px 58mm roll (most common, default)
PaperConfig.roll80mm 576 px 80mm roll
PaperConfig(widthPixels: n) custom Any custom width in pixels

PrintDensity — Print Darkness #

Optional. Controls how much the thermal head heats each dot (ESC 7). More heat darkens the stroke and makes small text and barcodes easier to read, at the cost of printing slightly slower and wearing the head faster.

Value Heating time Description
omitted (default) Sends no command; keeps the printer's factory value
PrintDensity.normal 80 Factory default of most thermal printers
PrintDensity.dark 120 One step darker — usually fixes faded small text
PrintDensity.darkest 160 Practical limit before the stroke starts to blur
// Darker print on an 80mm roll
await printer.configurePrinter(
  PaperConfig.roll80mm.copyWith(density: PrintDensity.dark),
);

Not every printer implements ESC 7. Most that don't simply ignore it, but a few print the parameters as text — that is why nothing is sent unless you ask for a density.

Complete Example #

import 'package:easy_blue_printer/easy_blue_printer.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: const PrinterPage());
  }
}

class PrinterPage extends StatefulWidget {
  const PrinterPage({super.key});

  @override
  State<PrinterPage> createState() => _PrinterPageState();
}

class _PrinterPageState extends State<PrinterPage> {
  final printer = EasyBluePrinter.instance;

  List<BluetoothDevice> devices = [];
  bool isConnected = false;
  bool isLoading = false;

  Future<void> scan() async {
    setState(() => isLoading = true);
    devices = await printer.getPairedDevices();
    setState(() => isLoading = false);
  }

  Future<void> connect(BluetoothDevice device) async {
    setState(() => isLoading = true);
    isConnected = await printer.connectToDevice(device);
    setState(() => isLoading = false);
  }

  Future<void> printReceipt() async {
    await printer.printData(
      data: 'My Store',
      fontSize: FS.large,
      textAlign: TA.center,
      bold: true,
    );
    await printer.printData(
      data: '------------------------',
      fontSize: FS.normal,
      textAlign: TA.center,
      bold: false,
    );
    await printer.printData(
      data: 'Item 1          R$ 10.00',
      fontSize: FS.normal,
      textAlign: TA.left,
      bold: false,
    );
    await printer.printData(
      data: 'Item 2          R$ 25.00',
      fontSize: FS.normal,
      textAlign: TA.left,
      bold: false,
    );
    await printer.printData(
      data: '------------------------',
      fontSize: FS.normal,
      textAlign: TA.center,
      bold: false,
    );
    await printer.printData(
      data: 'TOTAL           R$ 35.00',
      fontSize: FS.medium,
      textAlign: TA.left,
      bold: true,
    );
    await printer.printEmptyLine(callTimes: 5);
  }

  Future<void> disconnect() async {
    await printer.disconnectFromDevice();
    setState(() => isConnected = false);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Printer Example')),
      body: Column(
        children: [
          // Scan button
          Padding(
            padding: const EdgeInsets.all(16),
            child: ElevatedButton(
              onPressed: isLoading ? null : scan,
              child: isLoading
                  ? const CircularProgressIndicator()
                  : const Text('Scan Devices'),
            ),
          ),

          // Device list
          Expanded(
            child: ListView.builder(
              itemCount: devices.length,
              itemBuilder: (context, index) {
                final device = devices[index];
                return ListTile(
                  title: Text(device.name),
                  subtitle: Text(device.address),
                  onTap: () => connect(device),
                );
              },
            ),
          ),

          // Print and disconnect buttons
          if (isConnected) ...[
            ElevatedButton(
              onPressed: printReceipt,
              child: const Text('Print Receipt'),
            ),
            TextButton(
              onPressed: disconnect,
              child: const Text('Disconnect'),
            ),
            const SizedBox(height: 16),
          ],
        ],
      ),
    );
  }
}

Donations #

If this package helped you, consider buying me a coffee!

PIX: 17ec92dc-89cf-4eb9-be90-8cab0fc2460c

Contributing #

Contributions are welcome! Feel free to open a PR or report issues on the repository.

License #

This project is distributed under the MIT license. See the LICENSE file for details.


Portugues #

Funcionalidades #

  • Escanear dispositivos Bluetooth
  • Conectar e desconectar de impressoras
  • Imprimir texto com tamanho de fonte, alinhamento e negrito
  • Imprimir imagens a partir de bytes
  • Imprimir linhas em branco (alimentar papel)
  • Verificar status da conexao
  • Configurar o tamanho da bobina (58mm, 80mm ou customizado) para impressao correta de imagens
  • Fila de impressao embutida — envios sequenciais e nao concorrentes, sem necessidade de delays manuais
  • Funciona no Android e iOS

Plataformas Suportadas #

Plataforma Versao Minima
Android SDK 24 (7.0)
iOS 13.0
Flutter 3.44.0
Dart 3.12.0

No iOS o plugin fornece tanto um Swift Package (ios/easy_blue_printer/Package.swift) quanto o podspec do CocoaPods, entao funciona nas duas integracoes sem configuracao extra.

No Android o plugin usa Built-in Kotlin: nao aplica mais o Kotlin Gradle Plugin, portanto nao dispara mais o aviso de build plugins that apply Kotlin Gradle Plugin (KGP).

Instalacao #

Adicione no seu pubspec.yaml:

dependencies:
  easy_blue_printer: ^latest_version

Depois execute:

flutter pub get

Configuracao por Plataforma #

Android #

Adicione estas permissoes no android/app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <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" />

    <application ...>

No Android 12+ o plugin solicita as permissoes automaticamente em tempo de execucao.

iOS #

Adicione estas chaves no ios/Runner/Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>Este app precisa do Bluetooth para conectar a impressoras</string>

<key>NSBluetoothPeripheralUsageDescription</key>
<string>Este app precisa do Bluetooth para conectar a impressoras</string>

Inicio Rapido #

import 'package:easy_blue_printer/easy_blue_printer.dart';

final printer = EasyBluePrinter.instance;

// 1. Escanear dispositivos
final devices = await printer.getPairedDevices();

// 2. Conectar a um dispositivo
final connected = await printer.connectToDevice(devices.first);

// 3. Configurar tamanho da bobina (chamar uma vez apos conectar)
await printer.configurePrinter(PaperConfig.roll80mm); // ou PaperConfig.roll58mm

// 4. Imprimir texto
await printer.printData(
  data: 'Ola, Mundo!',
  fontSize: FS.medium,
  textAlign: TA.center,
  bold: true,
);

// 5. Alimentar papel
await printer.printEmptyLine(callTimes: 5);

// 6. Desconectar
await printer.disconnectFromDevice();

Referencia da API #

EasyBluePrinter.instance #

Instancia singleton. Use para acessar todos os metodos.


getPairedDevices() #

Escaneia e retorna uma lista de dispositivos Bluetooth disponiveis.

Future<List<BluetoothDevice>> getPairedDevices()

Retorno: Lista de objetos BluetoothDevice com as propriedades name e address.


connectToDevice(device) #

Conecta a uma impressora Bluetooth.

Future<bool> connectToDevice(BluetoothDevice device)
Parametro Tipo Descricao
device BluetoothDevice Dispositivo retornado por getPairedDevices()

Retorno: true se conectou com sucesso.


disconnectFromDevice() #

Desconecta da impressora atual.

Future<bool> disconnectFromDevice()

Retorno: true se desconectou com sucesso.


printData(...) #

Imprime texto formatado.

Future<bool> printData({
  required String data,
  required FS fontSize,
  required TA textAlign,
  required bool bold,
})
Parametro Tipo Descricao
data String Texto para imprimir
fontSize FS Tamanho da fonte (ver Enums)
textAlign TA Alinhamento (ver Enums)
bold bool Ativar negrito

Retorno: true se imprimiu com sucesso.


printEmptyLine(callTimes) #

Alimenta o papel imprimindo linhas em branco.

Future<void> printEmptyLine({required int callTimes})
Parametro Tipo Descricao
callTimes int Quantidade de linhas em branco

printImage(bytes, textAlign) #

Imprime uma imagem na impressora termica.

Future<bool> printImage({
  required Uint8List bytes,
  required TA textAlign,
})
Parametro Tipo Descricao
bytes Uint8List Dados da imagem em bytes
textAlign TA Alinhamento da imagem (ver Enums)

Retorno: true se imprimiu com sucesso.

Exemplo — imprimir dos assets:

import 'package:flutter/services.dart';

final byteData = await rootBundle.load('assets/images/logo.png');
final bytes = byteData.buffer.asUint8List();

await printer.printImage(bytes: bytes, textAlign: TA.center);

configurePrinter(config) #

Configura o tamanho da bobina utilizado na impressao de imagens. Chame uma vez apos conectar na impressora.

Future<void> configurePrinter(PaperConfig config)
Parametro Tipo Descricao
config PaperConfig Configuracao da bobina

Exemplo:

// Bobina 58mm (padrao)
await printer.configurePrinter(PaperConfig.roll58mm);

// Bobina 80mm
await printer.configurePrinter(PaperConfig.roll80mm);

// Largura customizada em pixels
await printer.configurePrinter(PaperConfig(widthPixels: 480));

Afeta apenas printImage. A impressao de texto e controlada pelo firmware da impressora e nao precisa desta configuracao.


isConnected() #

Verifica se uma impressora esta conectada.

Future<bool> isConnected()

Retorno: true se estiver conectado.


commandDelay #

Delay configuravel aplicado entre comandos de impressao consecutivos. A fila interna ja serializa todos os comandos; este delay da tempo extra para a impressora processar cada comando antes do proximo chegar.

Duration commandDelay  // padrao: Duration(milliseconds: 100)

Exemplo:

// Aumentar para impressoras mais lentas que ainda mostram caracteres invalidos
printer.commandDelay = const Duration(milliseconds: 150);

// Desativar para impressoras rapidas que nao precisam
printer.commandDelay = Duration.zero;

Aplicado apenas entre comandos enfileirados. Nao adiciona latencia apos o ultimo comando de um lote.


Enums #

FS — Tamanho da Fonte #

Valor Descricao
FS.normal Tamanho normal
FS.medium Tamanho medio
FS.large Tamanho grande
FS.huge Tamanho extra grande

TA — Alinhamento do Texto #

Valor Descricao
TA.left Alinhar a esquerda
TA.center Centralizar
TA.right Alinhar a direita

PaperConfig — Tamanho da Bobina #

Valor / Construtor Largura Descricao
PaperConfig.roll58mm 384 px Bobina de 58mm (mais comum, padrao)
PaperConfig.roll80mm 576 px Bobina de 80mm
PaperConfig(widthPixels: n) custom Qualquer largura customizada em pixels

PrintDensity — Densidade de Impressao #

Opcional. Controla quanto a cabeca termica aquece a cada ponto (ESC 7). Mais calor escurece o traco e melhora a leitura de texto pequeno e de codigos de barras, ao custo de imprimir um pouco mais devagar e de gastar mais a cabeca.

Valor Aquecimento Descricao
omitido (padrao) Nao envia comando; mantem o valor de fabrica da impressora
PrintDensity.normal 80 Padrao de fabrica da maioria das termicas
PrintDensity.dark 120 Um passo mais escuro — resolve texto miudo apagado
PrintDensity.darkest 160 Limite pratico antes de o traco comecar a borrar
// Impressao mais escura numa bobina de 80mm
await printer.configurePrinter(
  PaperConfig.roll80mm.copyWith(density: PrintDensity.dark),
);

Nem toda impressora implementa o ESC 7. A maioria das que nao implementam simplesmente o ignora, mas ha modelos que imprimem os parametros como texto — por isso nada e enviado a menos que voce peca uma densidade.

Exemplo Completo #

import 'package:easy_blue_printer/easy_blue_printer.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: const PrinterPage());
  }
}

class PrinterPage extends StatefulWidget {
  const PrinterPage({super.key});

  @override
  State<PrinterPage> createState() => _PrinterPageState();
}

class _PrinterPageState extends State<PrinterPage> {
  final printer = EasyBluePrinter.instance;

  List<BluetoothDevice> devices = [];
  bool isConnected = false;
  bool isLoading = false;

  Future<void> scan() async {
    setState(() => isLoading = true);
    devices = await printer.getPairedDevices();
    setState(() => isLoading = false);
  }

  Future<void> connect(BluetoothDevice device) async {
    setState(() => isLoading = true);
    isConnected = await printer.connectToDevice(device);
    setState(() => isLoading = false);
  }

  Future<void> printReceipt() async {
    await printer.printData(
      data: 'Minha Loja',
      fontSize: FS.large,
      textAlign: TA.center,
      bold: true,
    );
    await printer.printData(
      data: '------------------------',
      fontSize: FS.normal,
      textAlign: TA.center,
      bold: false,
    );
    await printer.printData(
      data: 'Item 1          R\$ 10,00',
      fontSize: FS.normal,
      textAlign: TA.left,
      bold: false,
    );
    await printer.printData(
      data: 'Item 2          R\$ 25,00',
      fontSize: FS.normal,
      textAlign: TA.left,
      bold: false,
    );
    await printer.printData(
      data: '------------------------',
      fontSize: FS.normal,
      textAlign: TA.center,
      bold: false,
    );
    await printer.printData(
      data: 'TOTAL           R\$ 35,00',
      fontSize: FS.medium,
      textAlign: TA.left,
      bold: true,
    );
    await printer.printEmptyLine(callTimes: 5);
  }

  Future<void> disconnect() async {
    await printer.disconnectFromDevice();
    setState(() => isConnected = false);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Exemplo Impressora')),
      body: Column(
        children: [
          // Botao de escanear
          Padding(
            padding: const EdgeInsets.all(16),
            child: ElevatedButton(
              onPressed: isLoading ? null : scan,
              child: isLoading
                  ? const CircularProgressIndicator()
                  : const Text('Escanear Dispositivos'),
            ),
          ),

          // Lista de dispositivos
          Expanded(
            child: ListView.builder(
              itemCount: devices.length,
              itemBuilder: (context, index) {
                final device = devices[index];
                return ListTile(
                  title: Text(device.name),
                  subtitle: Text(device.address),
                  onTap: () => connect(device),
                );
              },
            ),
          ),

          // Botoes de imprimir e desconectar
          if (isConnected) ...[
            ElevatedButton(
              onPressed: printReceipt,
              child: const Text('Imprimir Recibo'),
            ),
            TextButton(
              onPressed: disconnect,
              child: const Text('Desconectar'),
            ),
            const SizedBox(height: 16),
          ],
        ],
      ),
    );
  }
}

Doacoes #

Se este pacote te ajudou, considere me pagar um cafe!

PIX: 17ec92dc-89cf-4eb9-be90-8cab0fc2460c

Contribuindo #

Contribuicoes sao bem-vindas! Sinta-se a vontade para abrir um PR ou reportar problemas no repositorio.

Licenca #

Este projeto e distribuido sob a licenca MIT. Veja o arquivo LICENSE para mais detalhes.

4
likes
150
points
437
downloads

Documentation

API reference

Publisher

verified publisherlucassilva.dev

Weekly Downloads

The **Easy Blue Printer** plugin allows seamless integration of Bluetooth printers in a Flutter app, enabling the scanning, connection, and printing functionality.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on easy_blue_printer

Packages that implement easy_blue_printer