Flutter USB HID设备通信插件dartusbhid的使用

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

Flutter USB HID设备通信插件dartusbhid的使用

简介

dartusbhid 是一个用于与人类输入设备(HID)进行通信的Dart包装库,基于libusbhid。它在自己的隔离环境中运行,并支持以下功能:

  • 枚举USB HID设备(支持vendorIdproductIdserialNumberreleaseNumbermanufacturerStringproductStringusagePageusageinterfaceNumber
  • 读取和写入设备报告(带或不带报告ID)

计划中的功能包括读取和写入特征报告。

安装

要安装dartusbhid插件,请在终端中执行以下命令:

flutter pub add dartusbhid

使用示例

以下是完整的示例代码,展示如何使用dartusbhid插件来枚举USB HID设备并与其通信。

import 'package:dartusbhid/enumerate.dart';
import 'dart:typed_data';

void printDeviceList() async {
  // 枚举所有设备
  // 将vendorId和productId设置为0将枚举所有设备。
  final devices = await enumerateDevices(0, 0);
  print('发现的设备数量: ${devices.length}');
  
  for (final device in devices) {
    // 打印设备信息,如产品名称、供应商等
    print(device);
  }

  if (devices.isNotEmpty) {
    // 打开第一个设备
    final openDevice = await devices[0].open();

    // 读取数据(无超时:timeout: null)
    print("等待第一个HID报告");
    final receivedData = await openDevice.readReport(null);
    print("报告ID是: ${receivedData[0]}");
    print(receivedData);

    // 发送64字节的数据到设备
    var uint8list = Uint8List.fromList(List.generate(64, (index) => 0));
    uint8list[0] = 2; // 设置报告ID
    await openDevice.writeReport(uint8list);

    // 关闭设备
    await openDevice.close();
  } else {
    print("没有找到任何设备");
  }
}

void main() {
  printDeviceList();
}

开发环境设置

如果你想尝试这个示例项目,可以按照以下步骤操作:

  1. 克隆仓库:

    git clone https://github.com/TobiasJacob/dartusbhid.git
    
  2. 进入示例目录并运行:

    cd dartusbhid/example
    flutter run
    

从这里开始你可以开发库。发布库时,增加版本号,调整变更日志并使用以下命令发布:

cd dartusbhid
flutter analyze
flutter pub publish

示例应用完整代码

以下是来自示例项目的完整应用代码,包含UI界面以显示设备信息和交互功能。

import 'dart:io';
import 'dart:typed_data';
import 'package:dartusbhid/usb_device.dart';
import 'package:flutter/material.dart';
import 'package:dartusbhid/enumerate.dart';

void exampleComm() async {
  final devices = await enumerateDevices(22352, 1155);
  print('发现的设备数量: ${devices.length}');
  
  for (final device in devices) {
    // 打印设备信息,如产品名称、供应商等
    print(device);
  }

  if (devices.isNotEmpty) {
    final openDevice = await devices[0].open();
    // 读取数据(无超时:timeout: null)
    print("等待第一个HID报告");
    for (var i = 0; i < 100; i++) {
      final receivedData = await openDevice.readReport(null);
      print("接收的数据");
      print(receivedData);
      print("报告ID是: ${receivedData[0]}");

      // 生成64字节的列表
      var uint8list = Uint8List.fromList(List.generate(64, (index) => 0));
      uint8list[0] = 2;
      await openDevice.writeReport(uint8list);
      final echoData = await openDevice.readReport(null);
      print("回显数据");
      print(String.fromCharCodes(echoData));
      sleep(Duration(seconds: 1));
    }
    await openDevice.close();
  }
}

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

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

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

class _MyAppState extends State<MyApp> {
  String text = "Hello world";
  USBDeviceInfo? currentDevice;
  late Future<List<USBDeviceInfo>> devices;

  [@override](/user/override)
  void initState() {
    super.initState();
    devices = getDevices();
  }

  Future<List<USBDeviceInfo>> getDevices() async {
    var devices = await enumerateDevices(0, 0);
    return devices;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('USB HID Report explorer'),
        ),
        body: Row(
          children: [
            Container(
              padding: const EdgeInsets.all(10),
              color: Colors.lightBlue[50],
              width: 300,
              child: FutureBuilder<List<USBDeviceInfo>>(
                future: devices,
                builder: (BuildContext context, AsyncSnapshot<List<USBDeviceInfo>> snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return const Center(child: Text('刷新USB设备'));
                  } else {
                    if (snapshot.hasError) {
                      return Center(child: Text('错误: ${snapshot.error}'));
                    } else {
                      return ListView.separated(
                        padding: const EdgeInsets.all(8),
                        itemCount: snapshot.data!.length,
                        itemBuilder: (BuildContext context, int index) {
                          var device = snapshot.data![index];
                          return GestureDetector(
                            child: Text('${device.productString} - ${device.manufacturerString}'),
                            onTap: () {
                              setState(() {
                                currentDevice = device;
                              });
                            },
                          );
                        },
                        separatorBuilder: (context, index) => const Divider(),
                      );
                    }
                  }
                },
              ),
            ),
            Expanded(
              child: Center(
                child: Text(currentDevice?.productString ?? '请选择一个设备'),
              ),
            )
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,关于在Flutter中使用dartusbhid插件与USB HID(Human Interface Device)设备进行通信,以下是一个示例代码案例。这个示例将展示如何初始化dartusbhid插件,扫描连接的USB HID设备,并与其中一个设备进行简单的数据通信。

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

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

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

接下来是示例代码:

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

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

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

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

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

  Future<void> _initUsbHid() async {
    try {
      // 初始化dartusbhid
      await DartUsbHid.init();
      
      // 扫描连接的USB HID设备
      List<UsbDevice> devices = await DartUsbHid.listDevices();
      setState(() {
        _devices = devices;
      });
    } catch (e) {
      print('初始化USB HID失败: $e');
    }
  }

  Future<void> _connectToDevice(UsbDevice device) async {
    try {
      // 打开设备连接
      UsbConnection connection = await device.open();
      
      // 选择接口(通常第一个接口)
      UsbInterface interface = device.interfaces.first;
      await connection.claimInterface(interface);
      
      // 设置端点(这里假设是输入端点)
      UsbEndpoint endpoint = interface.endpoints.firstWhere((e) => e.direction == UsbEndpointDirection.in_);
      
      setState(() {
        _selectedDevice = device;
      });
      
      // 读取数据(示例:读取64字节)
      Uint8List data = await connection.transferIn(endpoint, 64);
      setState(() {
        _dataReceived = String.fromCharCodes(data);
      });
      
      // 关闭连接
      await connection.releaseInterface(interface);
      await connection.close();
    } catch (e) {
      print('与设备通信失败: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter USB HID通信示例'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            children: [
              Text('连接的USB HID设备:'),
              SizedBox(height: 16),
              Expanded(
                child: ListView.builder(
                  itemCount: _devices.length,
                  itemBuilder: (context, index) {
                    UsbDevice device = _devices[index];
                    return ListTile(
                      title: Text(device.description ?? '未知设备'),
                      subtitle: Text('Vendor ID: ${device.vendorId}, Product ID: ${device.productId}'),
                      onTap: () => _connectToDevice(device),
                    );
                  },
                ),
              ),
              SizedBox(height: 16),
              Text('接收到的数据: $_dataReceived'),
            ],
          ),
        ),
      ),
    );
  }
}

代码说明:

  1. 依赖引入:在pubspec.yaml中添加dartusbhid依赖。
  2. 初始化:在initState方法中调用_initUsbHid函数来初始化dartusbhid并扫描连接的USB HID设备。
  3. 设备列表显示:将扫描到的设备列表显示在UI上,用户可以点击某个设备进行连接。
  4. 设备连接与数据读取:在_connectToDevice函数中打开设备连接,选择接口,设置端点,然后读取数据。读取到的数据会显示在UI上。
  5. 错误处理:在通信过程中捕获并打印任何可能的错误。

请注意,这个示例代码假设你的USB HID设备支持简单的读取操作,并且使用了第一个接口和第一个端点。实际应用中,你可能需要根据设备的具体规范调整接口和端点的选择。此外,由于权限和平台差异,某些操作可能需要在Android或iOS上进行额外的配置。

回到顶部