参考http://stackoverflow.com/questions/25662307/android-l-libusb-init-returns-libusb-error-other-99 html
http://stackoverflow.com/questions/8854359/exception-open-failed-eacces-permission-denied-on-android java
和http://www.freehum.com/2014/06/operate-usb-device-under-android-by-libusb-without-root.htmllinux
在将原来的程序(Android 4.x)部署到Android 5.0和6.0的时候,遇到libusb_init失败和open failed (Permission denied)的错误,Google以后,发现是权限问题。android
Android 5.0以后强制开启了Selinux:git
Android sandbox reinforced with SELinux. Android now requires SELinux in enforcing mode for all domains. SELinux is a mandatory access control (MAC) system in the Linux kernel used to augment the existing discretionary access control (DAC) security model. This new layer provides additional protection against potential security vulnerabilities.github
详见https://source.android.com/security/enhancements/enhancements50.html dom
解决办法有2种tcp
安装SELinuxModeChanger,将模式改成permissive —— 貌似须要rootide
修改libusb,stackoverflow上说以下2个连接已经fix了:https://github.com/martinmarinov/rtl_tcp_andro-和https://github.com/Gritzman/libusb函数
本人使用的https://github.com/Gritzman/libusb
另外,可能须要增长libusb_open_fd,编译以后的so见http://pan.baidu.com/s/1hrzAfZ2
1) core.c 中在 libusb_open 后面增长 libusb_open_fd 函数
int API_EXPORTED libusb_open_fd(libusb_device *dev, libusb_device_handle **handle, int fd) { struct libusb_context *ctx = DEVICE_CTX(dev); struct libusb_device_handle *_handle; size_t priv_size = usbi_backend->device_handle_priv_size; int r; usbi_dbg("open %d.%d", dev->bus_number, dev->device_address); _handle = malloc(sizeof(*_handle) + priv_size); if (!_handle) return LIBUSB_ERROR_NO_MEM; r = usbi_mutex_init(&_handle->lock, NULL); if (r) { free(_handle); return LIBUSB_ERROR_OTHER; } _handle->dev = libusb_ref_device(dev); _handle->claimed_interfaces = 0; memset(&_handle->os_priv, 0, priv_size); r = usbi_backend->open_fd(_handle, fd); if (r < 0) { usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r); libusb_unref_device(dev); usbi_mutex_destroy(&_handle->lock); free(_handle); return r; } usbi_mutex_lock(&ctx->open_devs_lock); list_add(&_handle->list, &ctx->open_devs); usbi_mutex_unlock(&ctx->open_devs_lock); *handle = _handle; /* At this point, we want to interrupt any existing event handlers so * that they realise the addition of the new device's poll fd. One * example when this is desirable is if the user is running a separate * dedicated libusb events handling thread, which is running with a long * or infinite timeout. We want to interrupt that iteration of the loop, * so that it picks up the new fd, and then continues. */ usbi_fd_notification(ctx); return 0; }
2) os/linux_usbfs.c 中在 op_open 后面增长 op_open_fd 函数
static int op_open_fd(struct libusb_device_handle *handle, int fd) { struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); hpriv->fd = fd; return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT); }
3)os/linux_usbfs.c中.open = op_open,后添加.open_fd = op_open_fd,
4) 在libusbi.h中,
int (*open)(struct libusb_device_handle *handle);
后添加
int (*open_fd)(struct libusb_device_handle *handle, int fd);
API 23(6.0)以后,须要请求读写外设权限
private static final int REQUEST_EXTERNAL_STORAGE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; //在须要读写外设的地方 int permission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { // We don't have permission so prompt the user requestPermissions(PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE); }