Flutter USB通信插件smart_usb_android的使用

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

Flutter USB通信插件smart_usb_android的使用

使用

列出设备

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

带有额外描述的列出设备

返回带有制造商、产品和序列号描述的设备列表。

任何这些属性都可以为 null

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

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

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

获取设备描述

返回指定设备的制造商、产品和序列号描述。

任何这些属性都可以为 null

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

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

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

连接设备

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

检查权限

(仅限Android)

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

请求权限

(仅限Android)

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

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

打开/关闭设备

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

获取/设置配置

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

声明/释放接口

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

发送数据

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

批量传输输入/输出

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

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

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

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

此功能仅在 Linux 上受支持,在其他平台上此函数不起作用。

await SmartUsbAndroid.setAutoDetachKernelDriver(true);

完整示例Demo

// 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_android/smart_usb_android.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() {
    // TODO: implement initState
    super.initState();
    SmartUsbAndroid.init();
    _scan();
  }

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

  Future<bool> connectDevice(UsbDeviceDescription device) async {
    var isConnect = await SmartUsbAndroid.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 SmartUsbAndroid.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 SmartUsbAndroid.connectDevice(device.device);
    print(isConnect);
    if (isConnect) {
      await SmartUsbAndroid.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) => 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_android的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用smart_usb_android插件进行USB通信的示例代码。请注意,smart_usb_android是一个专门用于Android平台的Flutter插件,用于与USB设备进行通信。

首先,确保你已经在pubspec.yaml文件中添加了smart_usb_android依赖:

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

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用smart_usb_android插件:

  1. 请求USB权限:在Android上,你需要请求用户授予USB权限。

  2. 列出连接的USB设备:获取当前连接的USB设备列表。

  3. 与USB设备进行通信:选择一个设备并进行数据通信。

以下是一个简单的示例代码,展示了如何实现这些步骤:

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

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

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

class _MyAppState extends State<MyApp> {
  SmartUsbAndroid? _usb;
  List<UsbDevice> _devices = [];

  @override
  void initState() {
    super.initState();
    _usb = SmartUsbAndroid();
    _requestUsbPermission();
  }

  Future<void> _requestUsbPermission() async {
    bool hasPermission = await _usb!.requestUsbPermission();
    if (hasPermission) {
      _getUsbDevices();
    } else {
      // 处理权限被拒绝的情况
      print("USB permission denied");
    }
  }

  Future<void> _getUsbDevices() async {
    setState(() {
      _devices = [];
    });
    List<UsbDevice> devices = await _usb!.getUsbDevices();
    setState(() {
      _devices = devices;
    });
  }

  Future<void> _communicateWithDevice(UsbDevice device) async {
    // 假设我们有一个简单的通信协议,例如发送一个字符串
    String dataToSend = "Hello, USB Device!";
    bool success = await _usb!.sendDataToDevice(device, dataToSend);
    if (success) {
      print("Data sent successfully");
    } else {
      print("Failed to send data");
    }

    // 接收来自设备的数据(假设设备会响应)
    String? receivedData = await _usb!.receiveDataFromDevice(device);
    if (receivedData != null) {
      print("Received data: $receivedData");
    } else {
      print("No data received");
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter USB Communication'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            children: [
              Text('Connected USB Devices:'),
              SizedBox(height: 16),
              Expanded(
                child: ListView.builder(
                  itemCount: _devices.length,
                  itemBuilder: (context, index) {
                    UsbDevice device = _devices[index];
                    return ListTile(
                      title: Text(device.deviceName),
                      onTap: () {
                        _communicateWithDevice(device);
                      },
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class UsbDevice {
  final String deviceName;
  // 其他属性可以根据需要添加,如vendorId, productId等

  UsbDevice({required this.deviceName});
}

注意

  1. 上述代码中的SmartUsbAndroid类及其方法(如requestUsbPermission, getUsbDevices, sendDataToDevice, receiveDataFromDevice)是假设存在的,实际使用时需要参考smart_usb_android插件的官方文档来调整。

  2. UsbDevice类是一个简单的示例,用于存储设备信息。实际使用时,你可能需要根据插件返回的数据结构来定义这个类。

  3. 由于USB通信的复杂性,你可能需要处理更多的错误情况、边缘情况以及设备兼容性问题。

  4. 插件的具体API可能会随着版本更新而变化,因此务必参考最新的官方文档。

  5. 在实际部署之前,请在多种设备和Android版本上进行充分的测试。

回到顶部