正常来说,每次插拔USB设备的时候,系统都会发出广播,所以只需监听对应的广播即可。但是有一小部分设备可能和系统存在兼容问题,导致系统无法发出广播,所以不能准确监听插拔,只能通过其他方式来判断。
一、监听系统广播
1.1注册广播
public void registerReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
mUsbReceiver = new USBReceiver();
mContext.registerReceiver(mUsbReceiver, filter);
}
1.2广播接收类
private class USBReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 这里可以拿到插入的USB设备对象
UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
switch (intent.getAction()) {
case UsbManager.ACTION_USB_DEVICE_ATTACHED: // 插入USB设备
break;
case UsbManager.ACTION_USB_DEVICE_DETACHED: // 拔出USB设备
break;
default:
break;
}
}
}
1.3注销广播
public void unregisterReceiver() {
mContext.unregisterReceiver(mUsbReceiver);
}
二、通过轮询获取USB设备列表的方式判断
之前开发过一款外接USB相机,发现其和Android5.1.1系统不兼容,每次插拔的时候系统并不会发出广播,其他系统版本又正常,无奈app是针对5.1.1系统定制开发的,又必须及时响应USB插拔,所以只能通过其他方式来判断。
2.1获取USB设备列表
UsbManager mUsbManager = (UsbManager) context.getSystemService(context.USB_SERVICE);
HashMap<String, UsbDevice> mDeviceMap = mUsbManager.getDeviceList();
2.2遍历获取到的USB设备列表,判断其中是否有你需要的设备
比如我想过滤的设备是USB相机,可以根据设备的大小类进行判断。
public UsbDevice getUsbCameraDevice() {
if (mDeviceMap!= null) {
for (UsbDevice usbDevice : mDeviceMap.values()) {
if (isUsbCamera(usbDevice)) {
return usbDevice;
}
}
}
return null;
}
public boolean isUsbCamera(UsbDevice usbDevice) {
return usbDevice != null && 239 == usbDevice.getDeviceClass() && 2 == usbDevice.getDeviceSubclass();
}
2.3轮询
进入某个页面时开始轮询,如5秒轮询一次,当getUsbCameraDevice不为空时判断插入了USB相机,就可以处理打开相机的逻辑,为空时则判断USB相机拔出,关闭相机。当然这并不是一个完美的方法,只是一个无奈之举,对于不存在兼容问题的设备还是通过监听系统广播的方式来处理更好。
// 这里使用rxjava来轮询
Observable.interval(1, 5, TimeUnit.SECONDS)
.compose(RxUtil.<Long>io_main())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
if (getUsbCameraDevice() != null) { // 插入了USB设备
} else { // USB设备已拔出
}
}
});