Flutter USB通信插件libusb的使用

Flutter USB通信插件libusb的使用

环境

  • Windows (10)
  • macOS
  • Linux (Ubuntu 18.04 LTS)

使用

查看示例代码。

特性和问题

请在问题跟踪器提交功能请求和错误报告。

构建

准备LLVM (9+)

  • Windows: winget install -e --id LLVM.LLVM
  • macOS: brew install llvm
  • Linux: sudo apt install libclang-10-dev

构建libusb_xxx.dart

Windows/Linux:

pub run ffigen
mv lib/libusb.dart lib/libusb64.dart

timeval重命名为timeval64

macOS:

pub run ffigen
mv lib/libusb.dart lib/libusb32.dart

timeval重命名为timeval32

贡献

准备libusb.h

这里下载xxx版本并提取libusb.h

准备libusb-1.0动态库

Windows:

这里下载xxx版本并提取

copy libusb-1.0.23\MS64\dll\libusb-1.0.dll libusb-1.0\

macOS:

这里下载xxx版本并提取

cp libusb/1.0.23/lib/libusb-1.0.dylib libusb-1.0/

Linux:

这里下载xxx版本并安装

cp /lib/x86_64-linux-gnu/libusb-1.0.so.0.xxx libusb-1.0/libusb-1.0.so

完整示例Demo

示例代码

主文件 (main.dart)

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter USB Communication'),
        ),
        body: Center(
          child: RaisedButton(
            onPressed: () {
              // 初始化USB设备
              var context = LibUsbContext();
              LibUsb.init(context);

              // 打开设备
              var deviceList = LibUsb.getDeviceList(context);
              if (deviceList.isNotEmpty) {
                var device = deviceList[0];
                LibUsb.open(device, null);

                // 读取数据
                var buffer = List<int>.filled(64, 0);
                var transfer = LibUsb.allocTransfer(buffer.length);
                LibUsb.setTransferBuffer(transfer, buffer);
                LibUsb.submitTransfer(transfer);
                LibUsb.waitForTransfer(transfer, 1000);

                print("Received data: ${buffer}");

                // 清理
                LibUsb.freeTransfer(transfer);
                LibUsb.close(device);
                LibUsb.freeDeviceList(deviceList, true);
              } else {
                print("No devices found.");
              }

              LibUsb.exit(context);
            },
            child: Text('Read USB Data'),
          ),
        ),
      ),
    );
  }
}

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

1 回复

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


在Flutter中使用libusb进行USB通信可以通过编写自定义插件来实现。libusb是一个用于访问USB设备的跨平台库,支持Windows、macOS、Linux等操作系统。以下是如何在Flutter中集成并使用libusb的步骤:

1. 创建Flutter插件

首先,创建一个Flutter插件项目:

flutter create --template=plugin --platforms=android,ios,windows,linux,macos usb_communication
cd usb_communication

2. 添加libusb依赖

对于不同的平台,libusb的集成方式有所不同。

Android

android/build.gradle中添加libusb依赖:

dependencies {
    implementation 'com.github.mik3y:usb-serial-for-android:3.4.3' // 这是一个Android的USB库,支持libusb
}

iOS

ios/usb_communication.podspec中添加libusb依赖:

s.dependency 'libusb', '~> 1.0.0'

Windows/Linux/macOS

对于桌面平台,你可以直接使用libusb的C/C++库。你需要下载并编译libusb,然后在项目中链接它。

3. 编写平台通道代码

在Flutter插件中,使用平台通道(Platform Channels)来调用原生代码。

Dart代码

lib/usb_communication.dart中定义Dart接口:

import 'package:flutter/services.dart';

class UsbCommunication {
  static const MethodChannel _channel = MethodChannel('usb_communication');

  static Future<void> openDevice() async {
    try {
      await _channel.invokeMethod('openDevice');
    } on PlatformException catch (e) {
      print("Failed to open device: '${e.message}'.");
    }
  }

  static Future<void> writeData(List<int> data) async {
    try {
      await _channel.invokeMethod('writeData', data);
    } on PlatformException catch (e) {
      print("Failed to write data: '${e.message}'.");
    }
  }

  static Future<List<int>> readData() async {
    try {
      final result = await _channel.invokeMethod('readData');
      return List<int>.from(result);
    } on PlatformException catch (e) {
      print("Failed to read data: '${e.message}'.");
      return [];
    }
  }
}

Android代码

android/src/main/kotlin/com/example/usb_communication/UsbCommunicationPlugin.kt中实现Android端的逻辑:

package com.example.usb_communication

import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar

class UsbCommunicationPlugin: MethodCallHandler {
  companion object {
    @JvmStatic
    fun registerWith(registrar: Registrar) {
      val channel = MethodChannel(registrar.messenger(), "usb_communication")
      channel.setMethodCallHandler(UsbCommunicationPlugin())
    }
  }

  override fun onMethodCall(call: MethodCall, result: Result) {
    when (call.method) {
      "openDevice" -> {
        // 打开USB设备的逻辑
        result.success(null)
      }
      "writeData" -> {
        val data = call.arguments as List<Int>
        // 写入数据的逻辑
        result.success(null)
      }
      "readData" -> {
        // 读取数据的逻辑
        result.success(listOf<Int>())
      }
      else -> {
        result.notImplemented()
      }
    }
  }
}

iOS代码

ios/Classes/UsbCommunicationPlugin.m中实现iOS端的逻辑:

#import "UsbCommunicationPlugin.h"
#import <libusb.h>

@implementation UsbCommunicationPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"usb_communication"
            binaryMessenger:[registrar messenger]];
  UsbCommunicationPlugin* instance = [[UsbCommunicationPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([@"openDevice" isEqualToString:call.method]) {
    // 打开USB设备的逻辑
    result(nil);
  } else if ([@"writeData" isEqualToString:call.method]) {
    NSArray<NSNumber*>* data = call.arguments;
    // 写入数据的逻辑
    result(nil);
  } else if ([@"readData" isEqualToString:call.method]) {
    // 读取数据的逻辑
    result(@[]);
  } else {
    result(FlutterMethodNotImplemented);
  }
}
@end

Windows/Linux/macOS代码

对于桌面平台,你可以使用flutter_linuxflutter_windows插件模板,并在CMakeLists.txt中链接libusb库。

4. 使用插件

在Flutter应用中使用插件:

import 'package:usb_communication/usb_communication.dart';

void main() async {
  await UsbCommunication.openDevice();
  await UsbCommunication.writeData([0x01, 0x02, 0x03]);
  List<int> data = await UsbCommunication.readData();
  print(data);
}
回到顶部