JNI里面用Libusb监听设备接入、拔出

2 篇文章 1 订阅
  1. 背景:有些usb设备用Android通信不上或者检测不到。如hid usb设备
  2. 实现思路:在jni里面搞一个线程,让线程去检测。
  3. 以下是简单实现的代码:
#include <jni.h>

#include <android/log.h>
//
#include <stdlib.h>    // standard lib functions
#include <stddef.h>    // standard definitions
#include <stdint.h>    // standard integer definition
#include <stdbool.h>   // boolean definition
#include <string.h>
#include <stdint.h>

#include "libusb.h"


#include <sys/types.h>
#include <dirent.h>         //Linux目录相关
#include <fcntl.h>          //open()
#include <linux/hidraw.h>   //hidraw设备相关
#include <stdint.h>
#include <stdio.h>
#include <sys/ioctl.h>      //ioctl()
#include <sys/stat.h>       //stat()
#include <sys/time.h>       //struct timeval
#include <unistd.h>         //close()
#include "pthread.h"
#define LOG_TAG "USB-Native"

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)


static libusb_context *ctx;
static struct libusb_device_handle *dev_handle = NULL;
static struct libusb_device *usb_dev = NULL;

//以下是监听hotplug事件  
pthread_t usb_listener_thread;
//热插拔的回调监听函数
//不要在回调函数中调用可能阻塞的操作,否则可能造成libusb的其他函数执行失败
static int hotplug_callback(
    struct libusb_context *ctx,
    struct libusb_device *device,
    libusb_hotplug_event event,
    void *user_data)
{

    //通过设备获取设备地址
    uint8_t deviceAddress = libusb_get_device_address(device);

    struct libusb_device_descriptor desc;
    memset(&desc,sizeof(struct libusb_device_descriptor),0);
    if(libusb_get_device_descriptor(device,&desc) != 0){  //获取usb描述符
        LOGE("invoke libusb_get_device_descriptor fail...");
    }else{
        LOGD("vid:0x%04x pid:0x%04x", desc.idVendor, desc.idProduct);
    }

    if(event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
        LOGD("设备连接 \n");
    } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) {
        LOGD("设备断开 \n");
    }
    return 0;
}

void *usb_listener_method(void *data){

      libusb_context *context;
      //初始化libusb,要最先调用
      int ret = libusb_init(&context);

       if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)){
          LOGD("this version's libusb doesn't support hotplug");
     }else{
           LOGD("this version's libusb can support hotplug");

           int vendor_id = LIBUSB_HOTPLUG_MATCH_ANY; //不限制vid
            //需要监控的PID 设置为LIBUSB_HOTPLUG_MATCH_ANY,则不判断PID
           int product_id = LIBUSB_HOTPLUG_MATCH_ANY;//不限制pid
           int device_class = LIBUSB_HOTPLUG_MATCH_ANY;//不限制class

           //句柄,具体啥作用目前未知
           libusb_hotplug_callback_handle handle;

           //设备回调过来的数据
           void *user_data;

           int result_Register = libusb_hotplug_register_callback(context, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED| LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 1, vendor_id, product_id, device_class, hotplug_callback, &user_data, &handle);
           if (result_Register != LIBUSB_SUCCESS) {
                LOGD("resigter hotplug_callback failed");
           } else {
                LOGD("resigter hotplug_callback successfully");

             //注册了热插拔事件,必须要在循环中调用libusb_handle_events
               //在阻塞模式中处理任何挂起的事件。
               while(1) {
                     //设置允许处理事件的超时时间
                     libusb_handle_events(context);
               }

           }
     }

} 
jint JNI_OnLoad(JavaVM* vm, void* reserved){

      pthread_create(&usb_listener_thread, NULL, usb_listener_method, NULL);

      return JNI_VERSION_1_6;
  }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值