【背景】
折腾:
期间,需要实现:
android程序在运行期间,可以检测到usb设备的插入。
但是却出现:
android程序运行时可以检测到ACTION_USB_DEVICE_DETACHED:
但是检测不到ACTION_USB_DEVICE_ATTACHED
【折腾过程】
1.去参考:
去试试:
AndroidManifest.xml
中添加:
...
看看效果。
2.不过,参考之前就看到的:
有点明白了:
app,正在运行
USB设备插入
系统检测到ACTION_USB_DEVICE_ATTACHED
但是不会发送给你的当前的app的当前页面
而是:发送给你的app的activity的onResume()
并且是:
即使你在
onResume()
去检测UsbManager.ACTION_USB_DEVICE_ATTACHED
也还是检测不到的。。。
而是:
该intent会回来(??)变成android.intent.action.MAIN的
3.不过,对于
ACTION_USB_DEVICE_DETACHED
参考:
说是:
暂时android有bug,所以,通过代码中去检测:
ACTION_USB_DEVICE_DETACHED
而检测不到。
暂时只能通过:
Manifest文件中去检测
如果是这样的话:
那也忒坑爹了。。。。
关键我就是只需要:
在代码运行时检测usb插入
而不需要程序没运行时,去检测USB插入。。。
5.然后,果然在:
看到,的确是个bug,且暂时还没解决掉。。。。
坑爹。。。
6.评论中,robin说是提交个patch解决了此问题,
然后参考那人的patch:
->
看到是:// Send broadcast to running activity with registered intent
548
mContext.sendBroadcast(intent);
549
// Start activity with registered intent
7.郁闷了。
因为刚刚测试了如下代码:@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
detectUsbDeviceAttach();
}
@Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
String curItentActionName = intent.getAction();
Toast.makeText(getApplicationContext(), String.valueOf("Into onResume"), 1000).show();
Toast.makeText(getApplicationContext(), String.valueOf("curItentActionName=" + curItentActionName), 1000).show();
Toast.makeText(getApplicationContext(), String.valueOf("bUsbConnected=" + bUsbConnected), 1000).show();
if (bUsbConnected==false ) {
//check to see if USB is now connected
}
}
// BroadcastReceiver when remove the device USB plug from a USB port
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//0x0403 / 0x6001: FTDI FT232R UART
final int ft232rUartVid = 0x0403; //1027
final int ft232rUartPid = 0x6001; //24577
Toast.makeText(context, String.valueOf("Into UsbDeviceStateReceiver !"), 1000).show();
String curItentActionName = intent.getAction();
Toast.makeText(context, String.valueOf("Current Intent Action: " + curItentActionName), 1000).show();
if(UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(curItentActionName)){
Toast.makeText(context, String.valueOf("Found USB Device attached +++DEVICE+++ !"), 1000).show();
Toast.makeText(context, String.valueOf("Component: " + intent.getComponent()), 1000).show();
Toast.makeText(context, String.valueOf("Aciton: " + intent.getAction()), 1000).show();
Toast.makeText(context, String.valueOf("Categories: " + intent.getCategories()), 1000).show();
Toast.makeText(context, String.valueOf("Data: " + intent.getData()), 1000).show();
Toast.makeText(context, String.valueOf("DataType: " + intent.getType()), 1000).show();
Toast.makeText(context, String.valueOf("DataSchema: " + intent.getScheme()), 1000).show();
UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
HashMap deviceList = manager.getDeviceList();
Iterator deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next();
int usbVid = device.getVendorId();
int usbPid = device.getProductId();
if((usbVid == ft232rUartVid) && (usbPid ==ft232rUartPid) ){
Toast.makeText(context, "Found Usb device: FT232R UART", Toast.LENGTH_LONG).show();
break;
}
}
}
else if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(curItentActionName)){
bUsbConnected = false;
Toast.makeText(context, String.valueOf("Found USB Device detached ---DEVICE--- !"), 1000).show();
}
else if(UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(curItentActionName)){
Toast.makeText(context, String.valueOf("Found USB accessory attached +++ACCESSORY+++ !"), 1000).show();
}
else if(UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(curItentActionName)){
Toast.makeText(context, String.valueOf("Found USB accessory detached ---ACCESSORY---!"), 1000).show();
}
else{
Toast.makeText(context, String.valueOf("Unrecoginzed action !"), 1000).show();
}
}
};
private void detectUsbDeviceAttach(){
//0x0403 / 0x6001: FTDI FT232R UART
final int ft232rUartVid = 0x0403; //1027
final int ft232rUartPid = 0x6001; //24577
//final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
//listen usb device attach
IntentFilter usbDeviceStateFilter = new IntentFilter();
//usbDeviceStateFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
//usbDeviceStateFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
//usbDeviceStateFilter.addDataScheme("file");
usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
//usbDeviceStateFilter.addAction(ACTION_USB_PERMISSION);
//UsbDeviceStateReceiver usbDeviceStateReceiver = new UsbDeviceStateReceiver();
//registerReceiver(usbDeviceStateReceiver, usbDeviceStateFilter);
registerReceiver(mUsbReceiver, usbDeviceStateFilter);
//UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
//
//HashMap deviceList = manager.getDeviceList();
//Iterator deviceIterator = deviceList.values().iterator();
//while(deviceIterator.hasNext()){
//UsbDevice device = deviceIterator.next();
//int usbVid = device.getVendorId();
//int usbPid = device.getProductId();
//if((usbVid == ft232rUartVid) && (usbPid ==ft232rUartPid) ){
//Toast.makeText(getApplicationContext(), "Found Usb device: FT232R UART", Toast.LENGTH_LONG).show();
//break;
//}
//}
}
结果是:
USB设备插入后:
(1)根本没有进入那个所谓的onResume
(2)的确是UsbSettingsManager.java中的bug,使得app收不到对应的UsbManager.ACTION_USB_DEVICE_ATTACHED
(3)USB设备拔出,倒是一直可以正常检测到的。
【总结】
然后结论是:
1.如果是在AndroidManifest.xml加入:
以及在
res/xml/usbserial.xml
加上对应的vid和pid的配置:
然后对于USB device的插入,Android系统可以检测到,会弹出对应的对话框,问你是否打开你的程序的。
对于USB拔掉的UsbManager.ACTION_USB_DEVICE_DETACHED
更加可以正常工作。
2.但是想要在:
程序正常运行时,去检测
UsbManager.ACTION_USB_DEVICE_ATTACHED
目前无法实现。
因为是android系统有bug:
android 4.2(甚至是4.3)之前(包括:4.0.3,4.1,4.2等等),全部都是:
server/usb/UsbSettingsManager.java
中存在bug:
使得对于插入USB设备的事件,获得不到对应的indent。
(USB设备拔掉,倒是可以获得对应的UsbManager.ACTION_USB_DEVICE_DETACHED)
导致:
我这里,只需要关心,程序在执行期间,检测usb设备插入(对于usb设备拔出我不关心)
却没发很简单的实现。。。
需要以后考虑别的方案了。。。。
坑爹啊。。。
【后记】
后续折腾,详见: