pda_608_plugin 0.0.13
pda_608_plugin: ^0.0.13 copied to clipboard
A Flutter plugin for interfacing with PDA 608 hardware (printer and scanner).
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pda_608_plugin/pda_608_plugin.dart';
import 'dart:typed_data';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const Pda608TestApp());
}
class Pda608TestApp extends StatelessWidget {
const Pda608TestApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'PDA 608 Scanner & Printer',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const PdaMainScreen(),
);
}
}
class PdaMainScreen extends StatefulWidget {
const PdaMainScreen({Key? key}) : super(key: key);
@override
_PdaMainScreenState createState() => _PdaMainScreenState();
}
class _PdaMainScreenState extends State<PdaMainScreen> {
final _printTextController = TextEditingController();
final _scanResultController = TextEditingController();
bool _isInitialized = false;
bool _isPrinting = false;
String _statusMessage = 'Initializing...';
String _lastError = '';
@override
void initState() {
super.initState();
_initializePlugin();
// Listen for scan results
Pda608Plugin.scanResults.listen(
(result) {
setState(() {
_scanResultController.text = result.text;
_statusMessage = 'Scan received: ${result.text}';
});
},
onError: (error) {
setState(() {
_lastError = error.toString();
_statusMessage = 'Scan error: $error';
});
},
);
}
@override
void dispose() {
_printTextController.dispose();
_scanResultController.dispose();
_closePlugin();
super.dispose();
}
Future<void> _initializePlugin() async {
setState(() {
_statusMessage = 'Initializing...';
});
try {
final result = await Pda608Plugin.init();
setState(() {
_isInitialized = result;
_statusMessage = result
? 'Device ready. Use hardware scan button.'
: 'Failed to initialize device';
});
} catch (e) {
setState(() {
_isInitialized = false;
_lastError = e.toString();
_statusMessage = 'Error initializing: $e';
});
}
}
Future<void> _closePlugin() async {
if (_isInitialized) {
try {
await Pda608Plugin.close();
} catch (e) {
debugPrint('Error closing plugin: $e');
}
}
}
Future<void> _printText() async {
if (!_isInitialized) {
setState(() {
_statusMessage = 'Cannot print: Device not initialized';
});
return;
}
final text = _printTextController.text;
if (text.isEmpty) {
setState(() {
_statusMessage = 'Please enter text to print';
});
return;
}
setState(() {
_isPrinting = true;
_statusMessage = 'Printing...';
_lastError = '';
});
try {
final result = await Pda608Plugin.printText(
text: text,
size: 1, // Normal size
align: 1, // Center aligned
paperWidth: 80, // 80mm paper width
isLabel: false, // Not using label paper
tear: true, // Auto tear
);
setState(() {
_isPrinting = false;
_statusMessage = result
? 'Text printed successfully'
: 'Print failed, check printer';
});
} catch (e) {
setState(() {
_isPrinting = false;
_lastError = e.toString();
_statusMessage = 'Error printing: $e';
});
}
}
Future<void> _printQrCode() async {
if (!_isInitialized) {
setState(() {
_statusMessage = 'Cannot print: Device not initialized';
});
return;
}
final text = _printTextController.text;
if (text.isEmpty) {
setState(() {
_statusMessage = 'Please enter content for QR code';
});
return;
}
setState(() {
_isPrinting = true;
_statusMessage = 'Printing QR code...';
_lastError = '';
});
try {
final result = await Pda608Plugin.printQrCode(
data: text,
width: 300,
height: 300,
showText: true,
fontSize: 16,
align: 1,
paperWidth: 80, // 80mm paper
isLabel: false,
tear: true,
);
setState(() {
_isPrinting = false;
_statusMessage = result
? 'QR code printed successfully'
: 'QR code print failed';
});
} catch (e) {
setState(() {
_isPrinting = false;
_lastError = e.toString();
_statusMessage = 'Error printing QR code: $e';
});
}
}
Future<void> _printTestImage() async {
print("_printTestImage function started");
if (!_isInitialized) {
setState(() {
_statusMessage = 'Cannot print: Device not initialized';
});
return;
}
setState(() {
_isPrinting = true;
_statusMessage = 'Loading and printing image...';
_lastError = '';
});
try {
print("Loading test image from assets");
// First try to load the image from assets
final ByteData data = await rootBundle.load('assets/test_logo.png');
print("Image loaded, size: ${data.lengthInBytes} bytes");
final Uint8List imageData = data.buffer.asUint8List();
print("Sending image to printer");
final result = await Pda608Plugin.printImage(
imageData: imageData,
align: 1, // Center aligned
paperWidth: 80, // 80mm paper width
isLabel: false,
tear: true,
);
setState(() {
_isPrinting = false;
_statusMessage = result
? 'Image printed successfully'
: 'Image print failed, check printer';
});
} catch (e) {
print("Error printing image: $e");
// If image printing fails, try fallback to QR code
print("Falling back to QR code for testing");
try {
final result = await Pda608Plugin.printQrCode(
data: "IMAGE PRINT TEST FALLBACK",
width: 200,
height: 200,
showText: true,
fontSize: 24,
align: 1,
paperWidth: 80,
isLabel: false,
tear: true,
);
setState(() {
_isPrinting = false;
_lastError = 'Image printing failed, used QR code fallback';
_statusMessage = result
? 'Fallback QR code printed successfully'
: 'Printing failed';
});
} catch (e2) {
setState(() {
_isPrinting = false;
_lastError = e.toString() + "\nFallback error: " + e2.toString();
_statusMessage = 'All printing attempts failed';
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('PDA 608 Scanner & Printer'),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _isInitialized ? _initializePlugin : null,
tooltip: 'Reinitialize device',
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Status card
Card(
color: _isInitialized ? Colors.green.shade50 : Colors.red.shade50,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
_isInitialized ? Icons.check_circle : Icons.error,
color: _isInitialized ? Colors.green : Colors.red,
),
const SizedBox(width: 8),
Text(
'Status: ${_isInitialized ? 'Ready' : 'Not initialized'}',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
],
),
const SizedBox(height: 8),
Text(_statusMessage),
if (_lastError.isNotEmpty) ...[
const SizedBox(height: 8),
Text(
'Error: $_lastError',
style: const TextStyle(color: Colors.red),
),
],
],
),
),
),
const SizedBox(height: 24),
// Scanner section
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.blue.shade300),
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.qr_code_scanner, color: Colors.blue.shade700),
const SizedBox(width: 8),
Text(
'Barcode Scanner',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.blue.shade700,
),
),
],
),
const SizedBox(height: 16),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.yellow.shade100,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.orange),
),
child: Row(
children: const [
Icon(Icons.info_outline, color: Colors.orange),
SizedBox(width: 8),
Expanded(
child: Text(
'Please use the hardware scan button on the side of the device to scan barcodes',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
],
),
),
const SizedBox(height: 16),
TextField(
controller: _scanResultController,
decoration: const InputDecoration(
labelText: 'Scan Result',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.qr_code),
),
readOnly: true,
maxLines: 4,
minLines: 1,
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton.icon(
icon: const Icon(Icons.copy),
label: const Text('Copy Result'),
onPressed: _scanResultController.text.isEmpty
? null
: () {
Clipboard.setData(ClipboardData(
text: _scanResultController.text,
));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Copied to clipboard'),
),
);
},
),
const SizedBox(width: 8),
OutlinedButton.icon(
icon: const Icon(Icons.clear),
label: const Text('Clear'),
onPressed: _scanResultController.text.isEmpty
? null
: () {
setState(() {
_scanResultController.clear();
});
},
),
],
),
],
),
),
const SizedBox(height: 24),
// Printer section
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.green.shade300),
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.print, color: Colors.green.shade700),
const SizedBox(width: 8),
Text(
'Thermal Printer (80mm)',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.green.shade700,
),
),
],
),
const SizedBox(height: 16),
TextField(
controller: _printTextController,
decoration: const InputDecoration(
labelText: 'Text to Print',
border: OutlineInputBorder(),
hintText: 'Enter text to print...',
),
maxLines: 5,
enabled: _isInitialized && !_isPrinting,
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: ElevatedButton.icon(
icon: const Icon(Icons.print),
label: const Text('Print Text'),
onPressed: (!_isInitialized || _isPrinting) ? null : _printText,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12),
backgroundColor: Colors.green,
),
),
),
const SizedBox(width: 8),
Expanded(
child: ElevatedButton.icon(
icon: const Icon(Icons.qr_code),
label: const Text('Print as QR'),
onPressed: (!_isInitialized || _isPrinting) ? null : _printQrCode,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12),
backgroundColor: Colors.green.shade700,
),
),
),
],
),
const SizedBox(height: 8),
ElevatedButton.icon(
icon: const Icon(Icons.image),
label: const Text('Print Test Image'),
onPressed: (!_isInitialized || _isPrinting)
? null
: () {
print("Print Test Image button pressed"); // Debug output
_printTestImage();
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 12),
backgroundColor: Colors.blue.shade700,
minimumSize: const Size(double.infinity, 48),
),
), ],
),
),
],
),
),
);
}
}