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

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

Android crifan 8365浏览 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

中添加:

1
2
3
4
<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.郁闷了。

因为刚刚测试了如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    @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加入:

1
2
3
4
5
<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的配置:

1
2
3
4
5
6
7
8
9
10
<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.194 seconds, using 22.16MB memory