- 背景:有些usb设备用Android通信不上或者检测不到。如hid usb设备
- 实现思路:在jni里面搞一个线程,让线程去检测。
- 以下是简单实现的代码:
#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;
}