Flutter USB通信插件smart_usb的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter USB通信插件smart_usb的使用

使用

列出设备

await SmartUsb.init();
// ...
var deviceList = await SmartUsb.getDeviceList();
// ...
await SmartUsb.exit();

列出带有额外描述的设备

返回带有制造商、产品和序列号描述的设备列表。这些属性中任何一个都可以为null。

var descriptions = await SmartUsb.getDevicesWithDescription();
var deviceList = descriptions.map((e) => e.device).toList();
print('descriptions $descriptions');

(仅限Android) 在Android上,每个设备都需要权限才能获取序列号。如果需要,用户将被要求对每个设备进行授权。如果您不需要序列号,可以避免请求权限:

var descriptions = await SmartUsb.getDevicesWithDescription(requestPermission: false);

获取设备描述

返回指定设备的制造商、产品和序列号描述。这些属性中任何一个都可以为null。

var description = await SmartUsb.getDeviceDescription(device);
print('description ${description.toMap()}');

(仅限Android) 在Android上,每个设备都需要权限才能获取序列号。如果需要,用户将被要求对每个设备进行授权。如果您不需要序列号,可以避免请求权限:

var description = await SmartUsb.getDeviceDescription(requestPermission: false);

连接设备

var connectDevice = await SmartUsb.connectDevice(device);
print('connectDevice $connectDevice');
// ...

检查权限

(仅限Android)

var hasPermission = await SmartUsb.hasPermission(device);
print('hasPermission $hasPermission');

请求权限

(仅限Android)

请求设备权限。如果应用程序已经具有访问设备的权限,则不会显示权限对话框。

var hasPermission = await SmartUsb.requestPermission(device);
print('hasPermission $hasPermission');

打开/关闭设备

var openDevice = await SmartUsb.openDevice(device);
print('openDevice $openDevice');
// ...
await SmartUsb.closeDevice();

获取/设置配置

var configuration = await SmartUsb.getConfiguration(index);
print('getConfiguration $configuration');
// ...
var setConfiguration = await SmartUsb.setConfiguration(configuration);
print('setConfiguration $getConfiguration');

声明/释放接口

var claimInterface = await SmartUsb.claimInterface(interface);
print('claimInterface $claimInterface');
// ...
var releaseInterface = await SmartUsb.releaseInterface(interface);
print('releaseInterface $releaseInterface');

打印

var send = await SmartUsb.send(bytes);
print('send $send');

批量传输(输入/输出)

var bulkTransferIn = await SmartUsb.bulkTransferIn(endpoint, 1024, timeout: 2000);
print('bulkTransferIn ${hex.encode(bulkTransferIn)}');
// ...
var bulkTransferOut = await SmartUsb.bulkTransferOut(endpoint, data, timeout: 2000);
print('bulkTransferOut $bulkTransferOut');

设置自动分离内核驱动程序

启用/禁用Linux上的libusb自动分离内核驱动程序。启用此功能后,libusb将在声明接口时自动分离内核驱动程序,并在释放接口时重新附加它。

自动内核驱动程序分离在新打开的设备句柄上默认禁用。

此功能仅在Linux上受支持,在其他平台上该函数无操作。

await SmartUsb.setAutoDetachKernelDriver(true);

示例代码

以下是一个完整的示例,展示了如何使用smart_usb插件来连接USB设备并打印测试票据。

// ignore_for_file: non_constant_identifier_names
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/material.dart';
import 'package:smart_usb/smart_usb.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<UsbDeviceDescription> _deviceList = [];

  [@override](/user/override)
  void initState() {
    super.initState();
    SmartUsb.init();
    _scan();
  }

  void _scan() async {
    _deviceList.clear();
    var descriptions =
        await SmartUsb.getDevicesWithDescription(requestPermission: false);
    print(descriptions);
    _deviceList = descriptions;
    setState(() {});
  }

  Future<bool> connectDevice(UsbDeviceDescription device) async {
    var isConnect = await SmartUsb.connectDevice(device.device);
    print(isConnect);
    return isConnect;
  }

  Future _printReceiveTest(UsbDeviceDescription device) async {
    List<int> bytes = [];

    // Xprinter XP-N160I
    final profile = await CapabilityProfile.load(name: 'XP-N160I');
    // PaperSize.mm80 or PaperSize.mm58
    final generator = Generator(PaperSize.mm80, profile);
    bytes += generator.setGlobalCodeTable('CP1252');
    bytes += generator.text('Test Print',
        styles: const PosStyles(align: PosAlign.center));
    bytes += generator.cut();
    await SmartUsb.send(bytes);
  }

  Future _connectWithPrint(UsbDeviceDescription device) async {
    List<int> bytes = [];

    // Xprinter XP-N160I
    final profile = await CapabilityProfile.load(name: 'XP-N160I');
    // PaperSize.mm80 or PaperSize.mm58
    final generator = Generator(PaperSize.mm80, profile);
    bytes += generator.setGlobalCodeTable('CP1252');
    bytes += generator.text('Test Print',
        styles: const PosStyles(align: PosAlign.center));

    _printEscPos(device, bytes, generator);
  }

  /// print ticket
  void _printEscPos(
      UsbDeviceDescription device, List<int> bytes, Generator generator) async {
    //bytes += generator.feed(2);
    bytes += generator.cut();
    var isConnect = await SmartUsb.connectDevice(device.device);
    print(isConnect);
    if (isConnect) {
      await SmartUsb.send(bytes);
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
        home: DefaultTabController(
            length: 2,
            child: Scaffold(
                appBar: AppBar(
                  title: const Text('Flutter Smart Usb example app'),
                  bottom: const TabBar(
                    tabs: [
                      Tab(icon: Icon(Icons.home_max)),
                      Tab(icon: Icon(Icons.connect_without_contact_rounded)),
                    ],
                  ),
                ),
                floatingActionButton: FloatingActionButton(
                  onPressed: () {
                    _scan();
                  },
                  child: const Icon(Icons.refresh),
                ),
                body: TabBarView(children: [
                  Center(
                      child: Container(
                    height: double.infinity,
                    constraints: const BoxConstraints(maxWidth: 400),
                    child: SingleChildScrollView(
                      padding: EdgeInsets.zero,
                      child: Column(
                        children: [
                          Column(
                              children: _deviceList
                                  .map(
                                    (device) => ListTile(
                                      title: Text('${device.product}'),
                                      subtitle:
                                          Text("${device.device.vendorId}"),
                                      onTap: () {
                                        // do something
                                      },
                                      trailing: OutlinedButton(
                                        onPressed: () async {
                                          _connectWithPrint(device);
                                        },
                                        child: const Padding(
                                          padding: EdgeInsets.symmetric(
                                              vertical: 2, horizontal: 20),
                                          child: Text("Print test ticket",
                                              textAlign: TextAlign.center),
                                        ),
                                      ),
                                    ),
                                  )
                                  .toList()),
                        ],
                      ),
                    ),
                  )),
                  Row(
                    mainAxisSize: MainAxisSize.min,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          SingleChildScrollView(
                            padding: EdgeInsets.zero,
                            child: Column(
                                mainAxisSize: MainAxisSize.min,
                                children: _deviceList
                                    .map(
                                      (device) =&gt; Row(
                                        crossAxisAlignment:
                                            CrossAxisAlignment.center,
                                        children: [
                                          Column(
                                            crossAxisAlignment:
                                                CrossAxisAlignment.start,
                                            children: [
                                              Text('${device.product}'),
                                              Text("${device.device.vendorId}"),
                                            ],
                                          ),
                                          const SizedBox(
                                            width: 10,
                                          ),
                                          OutlinedButton(
                                            onPressed: () async {
                                              connectDevice(device);
                                            },
                                            child: const Padding(
                                              padding: EdgeInsets.symmetric(
                                                  vertical: 2, horizontal: 20),
                                              child: Text("Connect Printer",
                                                  textAlign: TextAlign.center),
                                            ),
                                          ),
                                          const SizedBox(
                                            width: 10,
                                          ),
                                          OutlinedButton(
                                            onPressed: () async {
                                              _printReceiveTest(device);
                                            },
                                            child: const Padding(
                                              padding: EdgeInsets.symmetric(
                                                  vertical: 2, horizontal: 20),
                                              child: Text("Print test ticket",
                                                  textAlign: TextAlign.center),
                                            ),
                                          ),
                                        ],
                                      ),
                                    )
                                    .toList()),
                          ),
                        ],
                      ),
                    ],
                  ),
                ]))));
  }

  void log(String info) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(info)));
  }
}

更多关于Flutter USB通信插件smart_usb的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter USB通信插件smart_usb的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用smart_usb插件进行USB通信的示例代码。smart_usb是一个用于Flutter的USB通信插件,允许你与连接的USB设备进行数据交换。

首先,你需要在你的pubspec.yaml文件中添加smart_usb依赖:

dependencies:
  flutter:
    sdk: flutter
  smart_usb: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来获取依赖。

接下来是具体的代码示例,包括如何请求USB权限、列出连接的USB设备、以及进行简单的数据通信。

主应用代码 (main.dart)

import 'package:flutter/material.dart';
import 'package:smart_usb/smart_usb.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  SmartUsb? _smartUsb;
  List<UsbDevice> _devices = [];
  String _dataReceived = '';

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

  Future<void> _initUsb() async {
    _smartUsb = SmartUsb();

    // 请求USB权限
    bool hasPermission = await _smartUsb!.requestUsbPermission();
    if (hasPermission) {
      // 列出连接的USB设备
      _devices = await _smartUsb!.getUsbDevices();
      setState(() {});
    } else {
      print("USB权限被拒绝");
    }
  }

  Future<void> _sendDataToDevice(UsbDevice device) async {
    // 假设我们要发送的数据
    String dataToSend = "Hello, USB Device!";
    await _smartUsb!.writeData(device, dataToSend.codeUnits);
  }

  Future<void> _listenToDevice(UsbDevice device) async {
    // 监听来自USB设备的数据
    _smartUsb!.onDataReceived!.listen((UsbDataReceivedEvent event) {
      setState(() {
        _dataReceived = String.fromCharCodes(event.data);
      });
    });

    // 开始与设备通信
    await _smartUsb!.startUsbDevice(device);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter USB通信示例'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            children: [
              Text("已连接的USB设备:"),
              SizedBox(height: 16),
              Expanded(
                child: ListView.builder(
                  itemCount: _devices.length,
                  itemBuilder: (context, index) {
                    UsbDevice device = _devices[index];
                    return ListTile(
                      title: Text(device.deviceName),
                      subtitle: Text("Vendor ID: ${device.vendorId}, Product ID: ${device.productId}"),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          ElevatedButton(
                            onPressed: () async {
                              await _sendDataToDevice(device);
                            },
                            child: Text('发送数据'),
                          ),
                          SizedBox(width: 8),
                          ElevatedButton(
                            onPressed: () async {
                              await _listenToDevice(device);
                            },
                            child: Text('监听数据'),
                          ),
                        ],
                      ),
                    );
                  },
                ),
              ),
              SizedBox(height: 16),
              Text("接收到的数据: $_dataReceived"),
            ],
          ),
        ),
      ),
    );
  }
}

注意事项

  1. 权限处理:确保在Android的AndroidManifest.xml中添加了必要的USB权限。
  2. 设备兼容性smart_usb插件可能不支持所有USB设备,具体兼容性请参考插件的文档和源码。
  3. 数据格式:发送和接收的数据通常是字节数组,因此需要根据实际设备的协议进行编码和解码。
  4. 错误处理:在实际应用中,需要添加更多的错误处理逻辑,以确保应用的健壮性。

这个示例展示了如何使用smart_usb插件进行基本的USB通信。根据实际需求,你可能需要调整代码以适应具体的USB设备和通信协议。

回到顶部