最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【未解决】android程序运行时可以检测到ACTION_USB_DEVICE_DETACHED,但是检测不到ACTION_USB_DEVICE_ATTACHED

Android crifan 8276浏览 0评论

【背景】

折腾:

【已解决】Android设备作为Host希望实现可以检测到USB设备插入

期间,需要实现:

android程序在运行期间,可以检测到usb设备的插入。

但是却出现:

android程序运行时可以检测到ACTION_USB_DEVICE_DETACHED:

intent action can found android.hardware.usb.action.USB_DEVICE_DETACHED

但是检测不到ACTION_USB_DEVICE_ATTACHED

【折腾过程】

1.去参考:

Can’t receive broadcast Intent of UsbManager.ACTION_USB_DEVICE_ATTACHED/UsbManager.ACTION_USB_DEVICE_DETACHED

去试试:

AndroidManifest.xml

中添加:

<application
    ...
    <receiver android:name="UsbDeviceStateReceiver" />
    <!-- <receiver android:name="usbDeviceStateReceiver" /> -->
    

看看效果。

2.不过,参考之前就看到的:

Android 3.1 USB-Host – BroadcastReceiver does not receive USB_DEVICE_ATTACHED

有点明白了:

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

参考:

USB host has confusing documentation

说是:

暂时android有bug,所以,通过代码中去检测:

ACTION_USB_DEVICE_DETACHED

而检测不到。

暂时只能通过:

Manifest文件中去检测

如果是这样的话:

那也忒坑爹了。。。。

关键我就是只需要:

在代码运行时检测usb插入

而不需要程序没运行时,去检测USB插入。。。

5.然后,果然在:

USB host device plugin notification failure

看到,的确是个bug,且暂时还没解决掉。。。。

坑爹。。。

6.评论中,robin说是提交个patch解决了此问题,

然后参考那人的patch:

https://android-review.googlesource.com/#/c/38150/

->

https://android-review.googlesource.com/#/c/38150/1/services/java/com/android/server/usb/UsbSettingsManager.java

看到是:

// Send broadcast to running activity with registered intent

548

mContext.sendBroadcast(intent);

549

550

// 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<String, UsbDevice> deviceList = manager.getDeviceList();
	       		Iterator<UsbDevice> 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<String, UsbDevice> deviceList = manager.getDeviceList();
//		Iterator<UsbDevice> 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加入:

<intent-filter>
    <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>

<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usbserial" />

以及在

res/xml/usbserial.xml

加上对应的vid和pid的配置:

<resources>
<!-- 0x0403 / 0x6001: FTDI FT232R UART -->
<usb-device vendor-id="1027" product-id="24577"/>
<!-- 0x2341 / Arduino -->
<usb-device vendor-id="9025"/>
<!-- 0x16C0 / 0x0483: Teensyduino -->
<usb-device vendor-id="5824" product-id="1155"/>
<!-- 0x10C4 / 0xEA60: CP210x UART Bridge -->
<usb-device vender-id="4292" product-id="60000"/>
</resources>

然后对于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设备拔出我不关心)

却没发很简单的实现。。。

需要以后考虑别的方案了。。。。

坑爹啊。。。


【后记】

后续折腾,详见:

【已解决】Android设备作为Host希望实现可以检测到USB设备插入

转载请注明:在路上 » 【未解决】android程序运行时可以检测到ACTION_USB_DEVICE_DETACHED,但是检测不到ACTION_USB_DEVICE_ATTACHED

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
83 queries in 0.190 seconds, using 22.11MB memory