brady_flutter_plugin 3.3.0+1 copy "brady_flutter_plugin: ^3.3.0+1" to clipboard
brady_flutter_plugin: ^3.3.0+1 copied to clipboard

The official Flutter Plugin to integrate the Brady SDK into your Flutter application. The Brady SDK allows users to discover, connect, and print to Brady printers.

example/lib/main.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:brady_flutter_plugin/brady_flutter_plugin.dart';

Uint8List? previewImage;

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _bradyFlutterPlugin = BradyFlutterPlugin();

  bool showImage = false;
  String _status = 'Ready';
  String _details = '';
  List<Map<String, String>> _printers = [];
  List<String> _templateFiles = [];
  String? _selectedTemplate;
  List<String> _assetFiles = [];
  String? _selectedAsset;
  String? _connectedPrinterModel;
  List<String> _availablePrintModes = [];
  String? _selectedPrintMode;

  bool get _isM811J {
    return _connectedPrinterModel == 'M811J';
  }

  bool get _isPiclLite {
    return _connectedPrinterModel == "M211" || _connectedPrinterModel == "M511";
  }

  bool get _isI7500 {
    return _connectedPrinterModel == 'i7500';
  }

  final TextEditingController _placeholderNameController =
      TextEditingController(text: '');
  final TextEditingController _placeholderValueController =
      TextEditingController(text: '');
  final TextEditingController _shutoffTimeController =
      TextEditingController(text: '30');
  final TextEditingController _alignmentOffsetController =
      TextEditingController(text: '0');
  final TextEditingController _maintenanceStationController =
      TextEditingController(text: 'Reset');
  final TextEditingController _rfidOperationsController =
      TextEditingController(text: '[]');
  final TextEditingController _ipAddressController =
      TextEditingController(text: '192.168.1.100');
  final TextEditingController _printerModelController =
      TextEditingController(text: 'M611');

  @override
  void initState() {
    super.initState();
    _loadAssets();
  }

  Future<void> _loadAssets() async {
    try {
      final manifestAsset = await rootBundle.load('AssetManifest.bin');
      final manifestMap =
          const StandardMessageCodec().decodeMessage(manifestAsset) as Map;
      final assetFiles = manifestMap.keys
          .whereType<String>()
          .where((String key) =>
              key.startsWith('assets/') && !key.endsWith("DS_Store"))
          .toList();
      setState(() {
        _assetFiles = assetFiles;
        if (_assetFiles.isNotEmpty) {
          _selectedAsset = _assetFiles.first;
          _callApi(() => _bradyFlutterPlugin.setTemplate(_selectedAsset!),
              'setTemplate');
        }
      });
    } catch (e) {
      // Handle error loading asset manifest
      if (kDebugMode) {
        print("Error loading assets: $e");
      }
    }
  }

  Timer? _discoveryTimer;

  Future<void> _startDiscovery() async {
    setState(() {
      _status = 'Starting discovery...';
      _printers = [];
    });
    try {
      _bradyFlutterPlugin.startBlePrinterDiscovery();
      _bradyFlutterPlugin.startWifiPrinterDiscovery();
      
      _discoveryTimer?.cancel();
      _discoveryTimer = Timer.periodic(const Duration(milliseconds: 500), (timer) async {
        try {
          final printers = await _bradyFlutterPlugin.getPrinters();
          if (mounted) {
            setState(() {
              _printers = printers;
            });
          }
        } catch (e) {
          if (kDebugMode) {
            print("Error getting printers: $e");
          }
        }
      });
    } catch (e) {
      setState(() {
        _status = 'Discovery failed';
        _details = e.toString();
      });
    }
  }

  Future<void> _connectToPrinter(String printerName, String protocol) async {
    final bool isBluetooth = protocol == "BLE";
    await _callApi(
        () => _bradyFlutterPlugin.connect(printerName, isBluetooth), 'connect',
        onSuccess: () async {
      _discoveryTimer?.cancel();
      _bradyFlutterPlugin.stopPrinterDiscovery();
      _getAllDetails();
      final model = await _bradyFlutterPlugin.getPrinterModel();
      
      List<String> printModes = [];
      try {
        if (model == 'M811J') {
          printModes = await _bradyFlutterPlugin.getAvailablePrintQualityModes() ?? [];
        }
      } catch (e) {
        if (kDebugMode) {
          print("Error getting print modes: $e");
        }
      }

      setState(() {
        _connectedPrinterModel = model;
        _availablePrintModes = printModes;
        if (_availablePrintModes.isNotEmpty) {
          _selectedPrintMode = _availablePrintModes.first;
        } else {
          _selectedPrintMode = null;
        }
      });
    });
  }

  Future<void> _callApi(Function apiCall, String name,
      {VoidCallback? onSuccess}) async {
    setState(() {
      _status = 'Calling $name...';
      _details = '';
      showImage = false;
    });
    try {
      final result = await apiCall();
      setState(() {
        _status = 'Success: $name';
        _details = result.toString();
      });
      onSuccess?.call();
    } on PlatformException catch (e) {
      setState(() {
        _status = 'Error: $name';
        _details = "Where: ${e.message!}\nDetails: ${e.details}";
      });
    } catch (e) {
      setState(() {
        _status = 'Error: $name';
        _details = e.toString();
      });
    }
  }

  Future<void> _getAllDetails() async {
    setState(() {
      _status = 'Getting all details...';
      _details = '';
    });

    final detailsMap = <String, dynamic>{};
    final functions = {
      'getPrinterStatus': _bradyFlutterPlugin.getPrinterStatus,
      'getPrinterStatusMessage': _bradyFlutterPlugin.getPrinterStatusMessage,
      'getPrinterStatusMessageTitle':
          _bradyFlutterPlugin.getPrinterStatusMessageTitle,
      'getPrinterStatusRemedyExplanationMessage':
          _bradyFlutterPlugin.getPrinterStatusRemedyExplanationMessage,
      'getPrinterName': _bradyFlutterPlugin.getPrinterName,
      'getPrinterModel': _bradyFlutterPlugin.getPrinterModel,
      'getConnectionType': _bradyFlutterPlugin.getConnectionType,
      'getBatteryLevelPercentage':
          _bradyFlutterPlugin.getBatteryLevelPercentage,
      'getIsAcConnected': _bradyFlutterPlugin.getIsAcConnected,
      'getSupplyName': _bradyFlutterPlugin.getSupplyName,
      'getSupplyRemainingPercentage':
          _bradyFlutterPlugin.getSupplyRemainingPercentage,
      'getSupplyWidth': _bradyFlutterPlugin.getSupplyWidth,
      'getSupplyHeight': _bradyFlutterPlugin.getSupplyHeight,
      'getSupplyColor': _bradyFlutterPlugin.getSupplyColor,
      'getIsSupplyPreSized': _bradyFlutterPlugin.getIsSupplyPreSized,
      'getIsSupplyDirectThermal': _bradyFlutterPlugin.getIsSupplyDirectThermal,
      'getDotsPerInch': _bradyFlutterPlugin.getDotsPerInch,
      'getPostPrintAccessoryType':
          _bradyFlutterPlugin.getPostPrintAccessoryType,
      'getYNumber': _bradyFlutterPlugin.getYNumber,
      'getRibbonName': _bradyFlutterPlugin.getRibbonName,
      'getRibbonRemainingPercentage':
          _bradyFlutterPlugin.getRibbonRemainingPercentage,
      'getRibbonColor': _bradyFlutterPlugin.getRibbonColor,
      'getInkRemainingPercentage':
          _bradyFlutterPlugin.getInkRemainingPercentage,
      'getOutOfInkCmy': _bradyFlutterPlugin.getOutOfInkCmy,
      'getIsCleanPrintheadMaintenanceRecommended':
          _bradyFlutterPlugin.getIsCleanPrintheadMaintenanceRecommended,
      'getCleanPrintheadSuccessful':
          _bradyFlutterPlugin.getCleanPrintheadSuccessful,
      'getMaintenanceStationWarningAway':
          _bradyFlutterPlugin.getMaintenanceStationWarningAway,
      'getMaintenanceStationErrorAway':
          _bradyFlutterPlugin.getMaintenanceStationErrorAway,
      'getAvailablePrintQualityModes':
          _bradyFlutterPlugin.getAvailablePrintQualityModes,
      'getValidInkSupply': _bradyFlutterPlugin.getValidInkSupply,
      'getPrintheadInstalled': _bradyFlutterPlugin.getPrintheadInstalled,
      'getAlignmentOffset': _bradyFlutterPlugin.getAlignmentOffset,
      'suppliesMatch': _bradyFlutterPlugin.suppliesMatch,
      'getErrorSeverity': _bradyFlutterPlugin.getErrorSeverity,
      'getFirmwareVersion': _bradyFlutterPlugin.getFirmwareVersion,
      'getLabelLibraryVersion': _bradyFlutterPlugin.getLabelLibraryVersion,
      'getBluetoothVersion': _bradyFlutterPlugin.getBluetoothVersion,
      'getWifiVersion': _bradyFlutterPlugin.getWifiVersion,
      'isSupplyValid': _bradyFlutterPlugin.isSupplyValid,
      'isRibbonValid': _bradyFlutterPlugin.isRibbonValid,
      'isPreprintedSupply': _bradyFlutterPlugin.isPreprintedSupply,
      'getAutomaticShutdownTime': _bradyFlutterPlugin.getAutomaticShutdownTime,
      'getLastConnectedPrinterName':
          _bradyFlutterPlugin.getLastConnectedPrinterName,
      'getHaveOwnership': _bradyFlutterPlugin.getHaveOwnership,
      'getTemplateSupplyName': _bradyFlutterPlugin.getTemplateSupplyName,
    };

    for (var entry in functions.entries) {
      try {
        final result = await entry.value();
        detailsMap[entry.key] = result ?? 'null';
      } catch (e) {
        detailsMap[entry.key] = 'null';
      }
    }

    try {
      final templateData = await _bradyFlutterPlugin.getTemplateData();
      detailsMap['getTemplateData'] = templateData;
    } catch (e) {
      // Ignore error from getTemplateData as it may be the source of the crash
    }

    final formattedDetails =
        detailsMap.entries.map((e) => '${e.key}: ${e.value}').join('\n');

    setState(() {
      _status = 'Finished getting all details';
      _details = formattedDetails;
    });
  }

  Widget _buildSectionHeader(String title) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(16, 24, 16, 8),
      child: Text(
        title,
        style: const TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.bold,
          color: Colors.black,
        ),
      ),
    );
  }

  Widget _buildApiButton(String title, VoidCallback onPressed) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
      child: ElevatedButton(
        onPressed: onPressed,
        child: Text(title, textAlign: TextAlign.center),
      ),
    );
  }

  Widget _buildTextField(TextEditingController controller, String label) {
    return TextField(
      controller: controller,
      style: const TextStyle(color: Colors.black),
      decoration: InputDecoration(
        labelText: label,
        labelStyle: const TextStyle(color: Colors.black54),
        enabledBorder: const UnderlineInputBorder(
          borderSide: BorderSide(color: Colors.black54),
        ),
      ),
    );
  }

  Widget _buildInputRow(
      String buttonTitle, VoidCallback onPressed, List<Widget> textFields) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
      child: Row(
        children: [
          Expanded(
            flex: 2,
            child: Column(children: textFields),
          ),
          const SizedBox(width: 8),
          Expanded(
            flex: 1,
            child: _buildApiButton(buttonTitle, onPressed),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light().copyWith(
        primaryColor: const Color(0xFF0D47A1),
        scaffoldBackgroundColor: Colors.grey[200],
        colorScheme: const ColorScheme.light(
          primary: Color(0xFF0D47A1),
          secondary: Color(0xFF0D47A1),
        ),
        cardColor: Colors.white,
        elevatedButtonTheme: ElevatedButtonThemeData(
          style: ElevatedButton.styleFrom(
            backgroundColor: const Color(0xFF0D47A1),
            foregroundColor: Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(8),
            ),
            padding: const EdgeInsets.symmetric(vertical: 12),
          ),
        ),
        appBarTheme: const AppBarTheme(
          titleTextStyle: TextStyle(
            color: Colors.white,
            fontSize: 20,
            fontWeight: FontWeight.w500,
          ),
        ),
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Brady SDK Flutter Wrapper'),
          backgroundColor: const Color(0xFF1E1E1E),
          elevation: 4,
        ),
        backgroundColor: Colors.grey[200],
        body: Column(
          children: [
            Card(
              elevation: 4,
              margin: const EdgeInsets.all(8.0),
              color: Colors.white,
              child: Padding(
                padding: const EdgeInsets.all(12.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Text(
                      'Status: $_status',
                      style: const TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 16,
                          color: Colors.black),
                    ),
                    const SizedBox(height: 8),
                    if (_details.isNotEmpty)
                      SizedBox(
                        height: 100, // Give it a fixed height
                        child: SingleChildScrollView(
                          child: Text(
                            _details,
                            style: const TextStyle(
                                fontSize: 14, color: Colors.black87),
                          ),
                        ),
                      ),
                  ],
                ),
              ),
            ),
            Expanded(
              child: ListView(
                padding: const EdgeInsets.symmetric(horizontal: 8.0),
                children: [
                  _buildSectionHeader('Discovery & Connection'),
                  _buildApiButton('Start Discovery', _startDiscovery),
                  if (_printers.isNotEmpty)
                    SizedBox(
                      height: 150,
                      child: Card(
                        color: Colors.white,
                        child: ListView.builder(
                          itemCount: _printers.length,
                          itemBuilder: (context, index) {
                            Map<String, String> currentPrinter = _printers[index];
                            String key = currentPrinter.keys.first;
                            return ListTile(
                              title: Text(key,
                                  style: const TextStyle(color: Colors.black)),
                              subtitle: Text(currentPrinter[key]!,
                                  style:
                                      const TextStyle(color: Colors.black87)),
                              onTap: () =>
                                  _connectToPrinter(key, currentPrinter[key]!),
                            );
                          },
                        ),
                      ),
                    ),
                  _buildInputRow(
                      'Connect w/ IP',
                      () => _callApi(
                              () => _bradyFlutterPlugin.connectWithManualIP(
                                  _ipAddressController.text,
                                  _printerModelController.text),
                              'connectWithManualIP', onSuccess: () async {
                            final model =
                                await _bradyFlutterPlugin.getPrinterModel();
                            
                            List<String> printModes = [];
                            try {
                              if (model == 'M811J') {
                                printModes = await _bradyFlutterPlugin.getAvailablePrintQualityModes() ?? [];
                              }
                            } catch (e) {
                              if (kDebugMode) {
                                print("Error getting print modes: $e");
                              }
                            }
                                
                            setState(() {
                              _connectedPrinterModel = model;
                              _availablePrintModes = printModes;
                              if (_availablePrintModes.isNotEmpty) {
                                _selectedPrintMode = _availablePrintModes.first;
                              } else {
                                _selectedPrintMode = null;
                              }
                            });
                          }),
                      [
                        _buildTextField(_ipAddressController, 'IP Address'),
                        _buildTextField(
                            _printerModelController, 'Printer Model'),
                      ]),
                  _buildApiButton(
                      'Disconnect',
                      () =>
                          _callApi(_bradyFlutterPlugin.disconnect, 'disconnect',
                              onSuccess: () {
                            setState(() {
                              _connectedPrinterModel = null;
                              _availablePrintModes = [];
                              _selectedPrintMode = null;
                            });
                          })),
                  _buildApiButton(
                      'Disconnect Without Forget',
                      () => _callApi(
                          _bradyFlutterPlugin.disconnectWithoutForget,
                          'disconnectWithoutForget')),
                  _buildApiButton(
                      'Forget Last Printer',
                      () => _callApi(
                          _bradyFlutterPlugin.forgetLastConnectedPrinter,
                          'forgetLastConnectedPrinter')),
                  _buildSectionHeader('Printer Status & Info'),
                  _buildApiButton('Get All Details', _getAllDetails),
                  _buildSectionHeader('Template & Printing'),
                  if (_assetFiles.isNotEmpty)
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: DropdownButton<String>(
                        value: _selectedAsset,
                        isExpanded: true,
                        dropdownColor: Colors.grey[200],
                        onChanged: (String? newValue) {
                          setState(() {
                            _selectedAsset = newValue;
                          });
                          if (newValue != null) {
                            _callApi(
                                () => _bradyFlutterPlugin.setTemplate(newValue),
                                'setTemplate');
                          }
                        },
                        items: _assetFiles
                            .map<DropdownMenuItem<String>>((String value) {
                          return DropdownMenuItem<String>(
                            value: value,
                            child: Text(value.split('/').last,
                                style: const TextStyle(color: Colors.black)),
                          );
                        }).toList(),
                      ),
                    ),
                  if (_templateFiles.isNotEmpty)
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: DropdownButton<String>(
                        value: _selectedTemplate,
                        isExpanded: true,
                        dropdownColor: Colors.grey[200],
                        onChanged: (String? newValue) {
                          setState(() {
                            _selectedTemplate = newValue;
                          });
                          if (newValue != null) {
                            _callApi(
                                () => _bradyFlutterPlugin.setTemplate(newValue),
                                'setTemplate');
                          }
                        },
                        items: _templateFiles
                            .map<DropdownMenuItem<String>>((String value) {
                          return DropdownMenuItem<String>(
                            value: value,
                            child: Text(value.split('/').last,
                                style: const TextStyle(color: Colors.black)),
                          );
                        }).toList(),
                      ),
                    ),
                  _buildInputRow(
                      'Set Placeholder',
                      () => _callApi(
                          () => _bradyFlutterPlugin.setPlaceholderValue(
                              _placeholderNameController.text,
                              _placeholderValueController.text),
                          'setPlaceholderValue'),
                      [
                        _buildTextField(
                            _placeholderNameController, 'Placeholder Name'),
                        _buildTextField(
                            _placeholderValueController, 'Placeholder Value'),
                      ]),
                  _buildApiButton(
                      'Get Preview',
                      () => _callApi(() async {
                            final base64 =
                                await _bradyFlutterPlugin.getPreview(200);
                            if (base64 != null) {
                              setState(() {
                                previewImage = base64Decode(base64);
                                showImage = true;
                              });
                            }
                          }, 'getPreview')),
                  _buildApiButton(
                      'Print',
                      () => _callApi(
                          () => _bradyFlutterPlugin.print(1, false, true, true),
                          'print')),
                  if (_isI7500)
                    _buildInputRow('Print with RFID', () {
                      try {
                        final ops = json.decode(_rfidOperationsController.text);
                        _callApi(
                            () => _bradyFlutterPlugin.printWithRfid(
                                ops, 1, "EndOfLabel", false, true),
                            'printWithRfid');
                      } catch (e) {
                        setState(() {
                          _status = 'Error: Invalid JSON';
                          _details = e.toString();
                        });
                      }
                    }, [
                      _buildTextField(
                          _rfidOperationsController, 'RFID Ops (JSON)')
                    ]),
                  _buildApiButton(
                      'Print PDF',
                      () => _callApi(
                          () => _bradyFlutterPlugin.printPDF(
                              "assets/add_analytics_for_printer_status_screen_small.pdf",
                              0,
                              1,
                              "EndOfLabel",
                              true,
                              true),
                          'printPDF')),
                  if (_isPiclLite || _isM811J) ...[
                    _buildSectionHeader('Maintenance & Supply'),
                    _buildApiButton(
                        'Feed Supply',
                        () => _callApi(
                            _bradyFlutterPlugin.feedSupply, 'feedSupply')),
                    _buildApiButton(
                        'Cut Supply',
                        () => _callApi(
                            _bradyFlutterPlugin.cutSupply, 'cutSupply')),
                    _buildInputRow(
                        'Set Auto Shutoff',
                        () => _callApi(
                            () => _bradyFlutterPlugin.setAutomaticShutoffTime(
                                int.parse(_shutoffTimeController.text)),
                            'setAutomaticShutoffTime'),
                        [_buildTextField(_shutoffTimeController, 'Minutes')]),
                  ],
                  if (_isM811J) ...[
                    _buildSectionHeader('M811J Specific Settings'),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: DropdownButton<String>(
                        value: _selectedPrintMode,
                        isExpanded: true,
                        dropdownColor: Colors.white,
                        onChanged: (String? newValue) {
                          setState(() {
                            _selectedPrintMode = newValue;
                          });
                        },
                        items: _availablePrintModes
                            .map<DropdownMenuItem<String>>((String value) {
                          return DropdownMenuItem<String>(
                            value: value,
                            child: Text(value),
                          );
                        }).toList(),
                      ),
                    ),
                    _buildApiButton('Set Print Mode', () {
                      if (_selectedPrintMode != null) {
                        _callApi(
                            () => _bradyFlutterPlugin
                                .setPrintQualityMode(_selectedPrintMode!),
                            'setPrintQualityMode');
                      }
                    }),
                    _buildApiButton(
                        'Clean Printhead',
                        () => _callApi(_bradyFlutterPlugin.cleanPrinthead,
                            'cleanPrinthead')),
                    _buildApiButton(
                        'Print Alignment Label',
                        () => _callApi(_bradyFlutterPlugin.printAlignmentLabel,
                            'printAlignmentLabel')),
                    _buildInputRow(
                        'Set Alignment Offset',
                        () => _callApi(
                            () => _bradyFlutterPlugin.setAlignmentOffset(
                                int.parse(_alignmentOffsetController.text)),
                            'setAlignmentOffset'),
                        [
                          _buildTextField(
                              _alignmentOffsetController, 'Offset')
                        ]),
                    _buildInputRow(
                        'Set Maint. Property',
                        () => _callApi(
                            () => _bradyFlutterPlugin
                                .setMaintenanceStationProperty(
                                    _maintenanceStationController.text),
                            'setMaintenanceStationProperty'),
                        [
                          _buildTextField(
                              _maintenanceStationController, 'Property')
                        ]),
                  ],
                  if (showImage && previewImage != null)
                    Card(
                      margin: const EdgeInsets.all(16),
                      color: Colors.white,
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Image.memory(previewImage!),
                      ),
                    ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _discoveryTimer?.cancel();
    _placeholderNameController.dispose();
    _placeholderValueController.dispose();
    _shutoffTimeController.dispose();
    _alignmentOffsetController.dispose();
    _maintenanceStationController.dispose();
    _rfidOperationsController.dispose();
    _ipAddressController.dispose();
    _printerModelController.dispose();
    super.dispose();
  }
}
4
likes
150
points
10
downloads

Documentation

API reference

Publisher

verified publishersdk.bradyid.com

Weekly Downloads

The official Flutter Plugin to integrate the Brady SDK into your Flutter application. The Brady SDK allows users to discover, connect, and print to Brady printers.

Homepage

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on brady_flutter_plugin

Packages that implement brady_flutter_plugin