Flutter USB设备访问插件usb的使用

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

Flutter USB设备访问插件usb的使用

USB 设备访问插件usb的使用

本项目是一个用于Flutter的插件项目,旨在提供一种访问USB设备的方法。此插件包含适用于Android和/或iOS的平台特定实现代码。

开始使用

对于希望开始Flutter开发的开发者,可以参考官方文档,该文档提供了教程、示例、移动开发指南和完整的API引用。

完整示例

以下是一个完整的示例,展示了如何使用usb插件来监听USB设备的连接和断开事件,并记录相关信息。

import 'dart:async';
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:usb/usb.dart';

void main() {
  // 捕获未处理的错误
  runZonedGuarded(startUp, handleUncaughtError);
}

void startUp() async {
  // 启动应用
  runApp(const MyApp());
}

void handleUncaughtError(Object error, StackTrace stack) {
  // 记录错误信息
  log(
    '$error',
    error: error,
    stackTrace: stack,
  );
}

// 主应用类
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'USB',
      theme: ThemeData.light(
        useMaterial3: true,
      ),
      darkTheme: ThemeData.dark(
        useMaterial3: true,
      ),
      home: const HomeView(),
    );
  }
}

// 主视图类
class HomeView extends StatefulWidget {
  const HomeView({super.key});

  [@override](/user/override)
  State<HomeView> createState() => _HomeViewState();
}

// 视图状态类
class _HomeViewState extends State<HomeView> {
  late final USBManager usbManager;
  late final ValueNotifier<List<String>> logs;
  late final StreamSubscription<USBDevice> deviceAttachedSubscription;
  late final StreamSubscription<USBDevice> deviceDetachedSubscription;

  [@override](/user/override)
  void initState() {
    super.initState();
    // 初始化USB管理器
    usbManager = USBManager();
    // 初始化日志通知器
    logs = ValueNotifier([]);
    // 监听USB设备连接事件
    deviceAttachedSubscription = usbManager.deviceAttached.listen(onAttached);
    // 监听USB设备断开事件
    deviceDetachedSubscription = usbManager.deviceDetached.listen(onDeatched);
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    // 构建UI
    return Scaffold(
      body: ValueListenableBuilder(
        valueListenable: logs,
        builder: (context, logs, child) {
          // 显示日志列表
          return ListView.builder(
            itemBuilder: (context, i) {
              final log = logs[i];
              return Text(log);
            },
            itemCount: logs.length,
          );
        },
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    // 清理资源
    super.dispose();
    deviceAttachedSubscription.cancel();
    deviceDetachedSubscription.cancel();
    logs.dispose();
  }

  // 处理设备连接事件
  void onAttached(USBDevice device) async {
    final time = DateTime.now();
    final formattedTime = DateFormat.Hms().format(time);
    final vendorId = await device.getVendorId();
    final productId = await device.getProductId();
    final log = '[$formattedTime] onAttached: ${vendorId.toHexString()} - ${productId.toHexString()}';
    logs.value = [...logs.value, log];
  }

  // 处理设备断开事件
  void onDeatched(USBDevice device) async {
    final time = DateTime.now();
    final formattedTime = DateFormat.Hms().format(time);
    final vendorId = await device.getVendorId();
    final productId = await device.getProductId();
    final log = '[$formattedTime] onDeatched: ${vendorId.toHexString()} - ${productId.toHexString()}';
    logs.value = [...logs.value, log];
  }
}

// 扩展方法,将int转换为十六进制字符串
extension on int {
  String toHexString() {
    return '0x${toRadixString(16).padLeft(4, '0')}';
  }
}

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

1 回复

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


在Flutter中访问USB设备通常需要使用第三方插件,因为Flutter本身并不直接提供对USB设备的访问能力。一个流行的插件是usb_serial,它允许你通过USB接口与串行设备进行通信。下面是一个使用usb_serial插件的基本示例代码,展示如何访问和与USB设备进行交互。

首先,确保在pubspec.yaml文件中添加usb_serial依赖:

dependencies:
  flutter:
    sdk: flutter
  usb_serial: ^x.y.z  # 请替换为最新版本号

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

接下来,在你的Flutter项目中,你可以使用以下代码来访问USB设备:

import 'package:flutter/material.dart';
import 'package:usb_serial/usb_serial.dart';
import 'package:usb_serial/usb_device.dart';
import 'package:usb_serial/usb_port.dart';

void main() => runApp(MyApp());

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

class _MyAppState extends State<MyApp> {
  UsbManager? _usbManager;
  UsbDevice? _selectedDevice;
  UsbPort? _selectedPort;
  UsbSerialPort? _serialPort;
  TextEditingController _inputController = TextEditingController();
  List<UsbDevice> _devices = [];

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

  Future<void> _initUsbManager() async {
    _usbManager = UsbManager();
    _usbManager!.onDeviceAdded!.listen((UsbDevice device) {
      setState(() {
        _devices.add(device);
      });
    });

    _usbManager!.onDeviceRemoved!.listen((UsbDevice device) {
      setState(() {
        _devices.remove(device);
      });
    });

    // 获取已连接的USB设备
    _devices = await _usbManager!.getDevices();
  }

  Future<void> _openPort() async {
    if (_selectedDevice == null || _selectedPort == null) return;

    _serialPort = await _selectedDevice!.create();
    if (_serialPort!.isOpen) {
      _serialPort!.close();
    }
    await _serialPort!.openPort(_selectedPort!);
    _serialPort!.inputStream!.listen((Uint8List data) {
      print('Received: ${String.fromCharCodes(data)}');
    });
  }

  Future<void> _sendData() async {
    if (_serialPort == null || !_serialPort!.isOpen) return;
    String data = _inputController.text;
    await _serialPort!.write(data.codeUnits);
    _inputController.clear();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('USB Serial Communication'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              DropdownButton<UsbDevice?>(
                value: _selectedDevice,
                hint: Text('Select USB Device'),
                onChanged: (UsbDevice? newValue) {
                  setState(() {
                    _selectedDevice = newValue;
                    _selectedPort = null;
                    _serialPort?.close();
                    _serialPort = null;
                  });
                  _updatePorts();
                },
                items: _devices.map<DropdownMenuItem<UsbDevice?>>((UsbDevice device) {
                  return DropdownMenuItem<UsbDevice?>(
                    value: device,
                    child: Text(device.deviceName),
                  );
                }).toList(),
              ),
              SizedBox(height: 16),
              DropdownButton<UsbPort?>(
                value: _selectedPort,
                hint: Text('Select USB Port'),
                onChanged: (UsbPort? newValue) {
                  setState(() {
                    _selectedPort = newValue;
                  });
                },
                items: _selectedDevice?.ports ?? [],
                isEnabled: _selectedDevice != null,
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: _openPort,
                child: Text('Open Port'),
              ),
              SizedBox(height: 16),
              TextField(
                controller: _inputController,
                decoration: InputDecoration(labelText: 'Send Data'),
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: _sendData,
                child: Text('Send'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _updatePorts() async {
    if (_selectedDevice != null) {
      setState(() {
        // 假设UsbDevice类有一个名为ports的属性,它返回一个UsbPort列表
        // 这取决于usb_serial插件的实际API,可能需要调整
        _selectedPort = _selectedDevice!.ports.isEmpty ? null : _selectedDevice!.ports.first;
      });
    }
  }
}

注意

  1. 上面的代码假设UsbDevice类有一个ports属性,它返回一个UsbPort列表。这取决于usb_serial插件的实际API,因此你可能需要根据插件的文档调整这部分代码。
  2. usb_serial插件的实际API可能与示例代码中的假设有所不同,因此请务必查阅最新的插件文档和示例代码。
  3. 在实际部署之前,请确保你的应用具有必要的权限来访问USB设备,这通常需要在Android的AndroidManifest.xml文件中声明相关权限。

这个示例提供了一个基本的框架,用于在Flutter应用中访问和与USB设备进行通信。根据你的具体需求,你可能需要扩展或修改这个示例。

回到顶部