USB_DEVICE_ATTACHED意图不发射

有没有人能够得到android.hardware.usb.action.USB_DEVICE_ATTACHED“工作?

好,所以我试图使用新的USB主机模式function来检测何时连接的USB设备。 为了我的目的,我想随时通知一个设备连接。 我无法看到它发生。 我使用的广播接收器,我知道的作品(当我有听其他事情,如主页button被按下。无论我尝试我似乎无法得到意图开火….所以使事情变得简单我决定忘记我的项目,并试图使用谷歌自己的示例代码,看看我是否至less可以做到这一点。我没有一个missle发射器,但我想我至less可以得到它的USB_Device_Attached我调整了代码为其他设备工作,首先我试着调整设备filterxml。我添加了我的设备(键盘):

<usb-device vendor-id="1050" product-id="0010" /> 

我从lsusb命令中获得了供应商和产品。 当设备连接时,logcat显示设备已find

 D/EventHub( 144): No input device configuration file found for device 'Yubico Yubico Yubikey II'. I/EventHub( 144): New device: id=43, fd=219, path='/dev/input/event8', name='Yubico Yubico Yubikey II', classes=0x80000003, configuration='', keyLayout='/system/usr/keylayout/Generic.kl', keyCharacterMap='/system/usr/keychars/Generic.kcm', builtinKeyboard=false I/InputReader( 144): Device added: id=43, name='Yubico Yubico Yubikey II', sources=0x00000101 I/ActivityManager( 144): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=2/1/1 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=47} D/MissileLauncherActivity(16191): intent: android.intent.action.MAIN I/EventHub( 144): Removed device: path=/dev/input/event8 name=Yubico Yubico Yubikey II id=43 fd=219 classes=0x80000003 I/InputReader( 144): Device removed: id=43, name='Yubico Yubico Yubikey II', sources=0x00000101 I/ActivityManager( 144): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=48} D/dalvikvm( 144): GC_EXPLICIT freed 78K, 26% free 14717K/19719K, paused 3ms+3ms D/MissileLauncherActivity(16191): intent: android.intent.action.MAIN 

xoom确实find了键盘,它可以从设备上使用(我可以在浏览器中使用它来键入字母)。 而意图类的火灾(但它只会触发android.intent.action.MAIN)我永远不会得到DEVICE_ATTACHED意图。 日志条目来自示例代码:

 Log.d(TAG, "intent: " + intent.getAction().toString()); 

在恢复function。 经过更多的挖掘和删除对USB的任何引用,我发现每一个应用程序,我得到的键盘被附加/分离(因此intent:android.intent.action.MAIN日志条目)时调用的简历。 现在我唯一能想到的就是它是android源代码中的一个bug。 顺便说一下,我使用的是与OS 3.1的WiFi xoom。

Solutions Collecting From Web of "USB_DEVICE_ATTACHED意图不发射"

我也有同样的问题。 我终于明白,在设备filterxml中,我们应该添加以下行。

 <usb-device vendor-id-"xxxxx" product-id="yyyyy"> 

xxxxx和yyyyy应该是十进制数字。 不是hex代码。 那么这一切都像广告一样工作! 我知道这是晚了,但我希望它有帮助。

所以我find了解决问题的办法,我也学到了很多,希望能帮助别人。

所以,首先closuresHID设备不会有任何意图 。 它们也不出现在mUsbManager.getDeviceList()列表中。 其他事情,但是。 我给了一个USB记忆棒一个去,你知道设备列在设备列表中。 我还发现返回的设备没有类,子类或协议。 debugging显示父接口确实有适当的类/子类/协议。 另外如果你必须有一个设备filter。 我结束了class=0008 (USB STORAGE)为我的目的工作。 我猜其他class也可以。

所以现在去搞清楚意图。 原来,意图必须附加到启动器的活动。 我把它附加到服务或接收器上的尝试将不会有任何成果。 所以,现在我意图开火,现在看到通知popup时,我附加我的设备(USB记忆棒)它要求我将我的应用程序设置为该设备的默认值。 现在完美我的应用程序每次我附加该设备运行。 请注意,系统会提示您input每个唯一的设备。 但只有一次。 它似乎很像默认程序注册。

那么,我想这个总结了我发现的东西。 太糟糕了,当键盘/鼠标被连接时,你无法得到通知。 还有件事儿。 tiamat内核没有任何问题,现在运行,没有问题。

我最近发现了一个类似问题的解决scheme。

正如有人已经指出, HID devices不启动一个意图 ,我认为这是你的问题。

但是,相关的问题是,如果程序设置为在USB设备连接时运行,那么即使应用程序运行一次,您也无法捕获USB_DEVICE_ATTACHED操作。 相反,系统看到了这个意图,并说:“哦,这意味着这个应用程序想要运行(如清单中声明),然后它发送给你的android.intent.action.MAIN行动,而不是USB_DEVICE_ATTACHED行动,它调用onResume() 。即使你的应用程序正在运行,所以据我所知,如果你的清单声明你的应用程序将在USB设备连接时运行,你不能捕获USB_DEVICE_ATTACHED意图,你只需要在onResume()检查USB是否连接,即使程序正在运行,当连接USB设备时,onResume将再次被调用。

我在这里更详细地注意到我的解决scheme: Android 3.1 USB主机 – BroadcastReceiver不会收到USB_DEVICE_ATTACHED

枚举设备

如果您的应用程序有兴趣检查应用程序运行时连接的所有USB设备,它可以枚举总线上的设备。 使用getDeviceList()方法获取所有连接的USB设备的哈希映射。 如果要从地图获取设备,哈希映射由USB设备的名称键入。

 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); 

如果需要,您也可以从哈希映射中获取迭代器,并逐一处理每个设备:

 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() //your code } 

我有同样的问题。 我的最终解决scheme是使用旧式的轮询技术。 这是一个相当小的课程,解决了我的问题。

 package com.YourCompancy.YourProduct; import android.app.*; import android.content.*; import android.hardware.usb.*; import java.util.*; import android.util.*; import android.os.*; public class UsbDeviceWatcher extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) { UsbDevice d = (UsbDevice) intent.getExtras().get(UsbManager.EXTRA_DEVICE); DeviceConnect(d, false); } } public void DeviceConnect(UsbDevice device, boolean Attached) { if (Attached) { // Some suggestions ... // play sound effect // notify consumer software // determine if interested in device // etc Log.i("usb", "device attached"); } else { Log.i("usb", "device detached"); } } public UsbManager manager; public Handler handler; public UsbDeviceWatcher(Context context, Handler handle) { this.handler = handle; manager = (UsbManager) context.getSystemService(Context.USB_SERVICE); IntentFilter dev = new IntentFilter(); dev.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); context.registerReceiver(this, dev); final UsbDeviceWatcher _this = this; Thread thread = new Thread(new Runnable() { public void run() { LinkedList<UsbDevice> seen = new LinkedList<UsbDevice>(); LinkedList<UsbDevice> attached = new LinkedList<UsbDevice>(); //there is a need for multithread support here // so the thread can watch for an exit condition while (true) { HashMap<String, UsbDevice> D = manager.getDeviceList(); for (UsbDevice d : D.values()) { if (!seen.contains(d)) { if (!attached.contains(d)) { final UsbDevice dev = d; handler.post(new Runnable(){ public void run() { DeviceConnect(dev, true); } }); } seen.add(d); } } for (UsbDevice d : seen) { if (!D.values().contains(d)) seen.remove(d); } try { Thread.sleep(500); } catch (InterruptedException exception) { return; } } } }); thread.start(); } } 

另一个解决方法是使用

 new FileObserver("/dev/input") { @Override public void onEvent(int event, String path) { //gets called on input device insert / remove } }; 

这将适用于一些USB设备(键盘,鼠标)

确定更多的工作,更多的失败,但有一些进展。

我从sdk文档中find了更多。 看起来你必须有设备filter才能使用意图。 所以我决定尝试使用类filter,而不是供应商/产品ID。 我认为这将是更一般的,希望赶上隐藏设备。 我使用03h作为类ID,我尝试了各种格式,我尝试了子类,我甚至使用lsusb来发现,类,子类和我的设备的协议。 这些似乎没有帮助。 所以我进一步到sdk文件,并决定尝试枚举所有的设备,看看什么操作系统看到类/子类/协议整数。 我复制了代码粘贴到click监听器并添加log.v语句。 logcat中没有显示。

它看起来像美国系统没有看到任何设备(即使设备实际工作)。现在这是非常明确的USB设备连接意图不发射。 现在我必须说我在xoom(tiamat)中使用了一个自定义内核。 我认为这可能与前一个问题有关,所以我回到了库存3.1。 现在还在进步。 现在这是一阵子之前,我试图枚举之前,所以现在我将恢复阿加,并继续与股票工作,直到我确定内核不是问题。 当我发现更多时,我会再回来。 成功或失败。 当然,如果有其他人比我更擅长这一点,请加以注意。最后一个注释我很担心整个OTG主机模式,当我在文档中看到这个时。注意coe是一样的,甚至认为它引用了两种方法枚举。 可能只是一个复制作家的错误,但仍然担心一些这一切的失败。

这是我做的检测USB /媒体连接。

清单文件

  <receiver android:name=".UsbReceiver" android:enabled="true" > <intent-filter> <action android:name="android.intent.action.MEDIA_MOUNTED"/> <action android:name="android.intent.action.MEDIA_UNMOUNTED"/> <data android:scheme="file"/> </intent-filter> </receiver> 

我没有做任何事情,也没有做我的接收器。

看起来像这条线正在做的东西。

 <data android:scheme="file"/> 

从我的testing中,Android 可以在连接HID设备时触发一个意图。 (MissileLauncher示例应用程序可以做到这一点。请参阅示例源代码以获取更多信息。)

导弹发射器(Dream Cheeky USB Missle Launcher)HID设备的子类和协议设置为0x00。 欲了解更多信息,请参阅: http : //www.mattcutts.com/blog/playing-with-a-usb-missile-launcher/

需要注意的是,Android并没有专门针对鼠标和键盘设备(可能更多)。 但是,我可以检测到它们的InterfaceClass = 0x03,InterfaceSubClass = 0x00,InterfaceProtocol = 0x00的HID设备。 对于我的应用程序,我的HID设备是embedded式控制器,因此设置子类和协议不是问题。

我有我的应用程序设置为launchMode="singleTop" ,在这种模式下,它看起来像getIntent().getAction()始终等于第一次启动应用程序的操作。

所以,如果你手动启动应用程序, 然后插入一个设备(即使离开那个应用程序),你会收到android.intent.action.MAIN

如果你杀了应用程序,然后插入设备,你总是会得到android.hardware.usb.action.USB_DEVICE_ATTACHED ,甚至切换离开,回到你的应用程序,甚至旋转设备

当拔下USB设备的时候,我真的很奇怪地接受了这个意图,我不认为这是logging在案 – 当然,当我的设备被分离时,我收到了USB_DEVICE_ATTACHED

如果没有singleTop ,它会像预期的那样工作,但是如果你的应用程序已经打开,并且你插入了设备,那么你会得到另一个愚蠢的额外的活动。

Android的API又一次出错,过于复杂和难以使用。

连接USB键盘WONT fire USB_DEVICE_ATTACHED

相反,系统会触发Intent.ACTION_CONFIGURATION_CHANGED 。 但是,随着configuration更改,系统将重新启动活动。 您不会在重新启动Activity的情况下捕捉到该操作。 在这种情况下,您需要在Android清单中添加android:configChanges =“keyboard | keyboardHidden” ,以便在外接键盘连接后不会重新启动活动。