HarmonyOS 鸿蒙Next 5.0 USB应用开发Demo

HarmonyOS 鸿蒙Next 5.0 USB应用开发Demo

import { systemDateTime, usbManager } from '@kit.BasicServicesKit';

const TAG: string = "USB => "

@Entry
@Component
struct Index {
  @State mDeviceId: string = '';
  @State mUsbDevice: usbManager.USBDevice | null = null
  @State mPipe: usbManager.USBDevicePipe | null = null
  @State mInterfaces: usbManager.USBInterface | null = null
  @State mRet: number = -1
  @State mReadChannel: usbManager.USBEndpoint | null = null
  @State mWriteChannel: usbManager.USBEndpoint | null = null
  @State @Watch("registerReadChange") mIsRegisterRead: boolean = false
  @State @Watch("registerWriteChange") mIsRegisterWrite: boolean = false
  @State mIsRegisterReadAndWrite: boolean = false
  @State mBulkTransferTime: number = 1000
  @State mIntervalTime: number = 1000
  @State mReadInterval: number = -1
  @State mWriteInterval: number = -1
  @State mReadAndWriteInterval: number = -1
  @State mIsReadFree: boolean = true
  @State mIsWriteFree: boolean = true
  @State mIsFirstReed: boolean = true

  registerReadChange(){
    if (this.mIsRegisterWrite) {
      this.mIsRegisterReadAndWrite = true
    }
  }

  registerWriteChange(){
    if (this.mIsRegisterRead) {
      this.mIsRegisterReadAndWrite = true
    }
  }

  /**
   * 读取 USB 缓冲区数据
   */
  async readData() {
    // 读通道是否空闲
    if (this.mIsReadFree) {
      console.info(TAG, "读取数据...")
      const startTime = systemDateTime.getTime()

      this.mIsReadFree = false

      // 读取
      let cache = new Uint8Array(512)

      const dataLength = await usbManager.bulkTransfer(this.mPipe, this.mReadChannel, cache, this.mBulkTransferTime)
      if (dataLength > 0) {
        console.info(TAG, String.fromCharCode(...cache.slice(0, dataLength)))
      } else {
        console.info(TAG, "无数据...")
      }

      const endTime = systemDateTime.getTime()

      // 非第一次读取数据,如果小于延迟时间,则外设可能已经断开
      if (!this.mIsFirstReed){
        if (endTime - startTime < this.mBulkTransferTime - 1) {
          console.info(TAG, `外设可能已经断开`)
        }
      }

      this.mIsFirstReed = false
      this.mIsReadFree = true

    } else {
      // console.warn(TAG, "读通道繁忙...")
    }
  }

  /**
   * 向 USB 设备写入数据
   */
  async writeData() {
    // 写通道是否空闲
    if (this.mIsWriteFree) {
      console.info(TAG, "写数据...")
      this.mIsWriteFree = false

      // 写入数据
      const writeData = new Uint8Array([29, 73, 67])
      const dataLength =
        await usbManager.bulkTransfer(this.mPipe, this.mWriteChannel, writeData, this.mBulkTransferTime)

      this.mIsWriteFree = true

    } else {
      console.warn(TAG, "写通道繁忙...")
    }
  }

  build() {
    Column({ space: 8 }) {
      Divider().height(8)

      // USB设备
      Scroll() {
        Text(JSON.stringify(this.mUsbDevice, null, 2))
      }
      .layoutWeight(1)

      Divider().height(8)

      Column({ space: 8 }) {

        if (!this.mUsbDevice) {
          Button("搜索并连接USB设备")
            .width("80%")
            .onClick(async () => {
              // 搜索USB设备
              let devicesList: Array<usbManager.USBDevice> = usbManager.getDevices()
              if (devicesList.length === 0) {
                console.error("未找到USB设备")
                return
              }

              // 选第一个
              let device: usbManager.USBDevice = devicesList[0]

              // 保存
              this.mUsbDevice = device
              this.mDeviceId = device.name

              // 是否有访问权限
              let right: boolean = usbManager.hasRight(this.mDeviceId)
              if (!right) {
                // 申请权限
                await usbManager.requestRight(this.mDeviceId)
              }

              // 连接设备
              let pipe: usbManager.USBDevicePipe = usbManager.connectDevice(this.mUsbDevice)
              this.mPipe = pipe

              // 获取数据传输接口
              let interfaces: usbManager.USBInterface = this.mUsbDevice.configs[0].interfaces[0]
              this.mInterfaces = interfaces

              // 打开接口
              let ret: number = usbManager.claimInterface(pipe, interfaces)
              this.mRet = ret

              // 获取读写通道
              this.mReadChannel = interfaces.endpoints.find(endpoint =>
              endpoint.direction === usbManager.USBRequestDirection.USB_REQUEST_DIR_FROM_DEVICE
              )!!

              this.mWriteChannel = interfaces.endpoints.find(endpoint =>
              endpoint.direction === usbManager.USBRequestDirection.USB_REQUEST_DIR_TO_DEVICE
              )!!
            })
        } else {
          Button("已连接", { stateEffect: false })
            .opacity(0.4)
            .width("80%")

          Button("读一次数据")
            .width("80%")
            .onClick(() => {
              console.info(TAG, "读一次数据")
              this.readData()
            })

          Button("写一次数据")
            .width("80%")
            .onClick(() => {
              console.info(TAG, "写一次数据")
              this.writeData()
            })

          Button("轮询读取数据")
            .width("80%")
            .onClick(() => {
              if (this.mIsRegisterRead) {
                console.warn(TAG, "已经开始轮询读取数据")
                return
              }
              this.mIsRegisterRead = true
              this.mReadInterval = setInterval(() => {
                this.readData()
              }, 0)
            })

          Button("轮询写入数据")
            .width("80%")
            .onClick(async () => {
              if (this.mIsRegisterWrite) {
                console.warn(TAG, "已经开始轮询写入数据")
                return
              }
              this.mIsRegisterWrite = true
              this.mWriteInterval = setInterval(() => {
                this.writeData()
              }, this.mIntervalTime)
            })

          Button("轮询读写数据")
            .width("80%")
            .onClick(async () => {
              if (this.mIsRegisterReadAndWrite) {
                return
              }
              this.mIsRegisterRead = true
              this.mIsRegisterWrite = true
              this.mIsRegisterReadAndWrite = true
              this.mReadAndWriteInterval = setInterval(() => {
                this.readData()
                this.writeData()
              }, this.mIntervalTime)
            })

          Button("清空定时器")
            .width("80%")
            .onClick(() => {
              console.info(TAG, "清空定时器")
              clearInterval(this.mReadInterval)
              clearInterval(this.mWriteInterval)
              clearInterval(this.mReadAndWriteInterval)
              this.mIsRegisterRead = false
              this.mIsRegisterWrite = false
              this.mIsRegisterReadAndWrite = false
            })
        }
      }
    }
    .height('100%')
    .width('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next 5.0 USB应用开发Demo的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS 鸿蒙Next 5.0 USB应用开发Demo的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next 5.0中,USB应用开发可以通过[@ohos](/user/ohos).usb模块实现。以下是一个简单的USB设备连接与数据传输的Demo:

  1. 导入模块

    import usb from '[@ohos](/user/ohos).usb';
    
  2. 获取USB管理器

    let usbManager = usb.getUsbManager();
    
  3. 监听USB设备连接

    usbManager.on('attach', (device) => {
        console.log('USB设备已连接:', device);
    });
    
  4. 打开设备并获取接口

    let device = usbManager.getDeviceList()[0];
    usbManager.openDevice(device);
    let interface = device.getInterface(0);
    
  5. 数据传输

    let endpoint = interface.getEndpoint(0);
    let data = new Uint8Array([0x01, 0x02, 0x03]);
    usbManager.bulkTransfer(device, endpoint, data, (err, result) => {
        if (!err) {
            console.log('数据传输成功:', result);
        }
    });
    
  6. 关闭设备

    usbManager.closeDevice(device);
    

此Demo展示了如何连接USB设备并进行数据传输。开发者可根据需求扩展功能,如处理更多设备事件或实现复杂的数据交互。

回到顶部