USB_DEVICE_ATTACHED意图不开火

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

好吧,我正在尝试使用新的USB主机模式function来检测何时连接USB设备。 出于我的目的,我希望在设备连接时得到通知。 我无法看到它发生。 我正在使用我知道有效的广播接收器(当我听到其他东西时,例如按下主页按钮。无论我尝试什么,我似乎无法获得触发的意图……所以让事情更简单我决定忘记我的项目,并尝试使用谷歌自己的示例代码,看看我是否至少可以做到这一点。我没有一个导弹发射器,但我想我至少可以得到它USB_Device_Attached没有去。我调整了代码以适用于其他设备。首先我尝试调整设备filterxml。我添加了我的设备(键盘):

 

我从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了键盘,它可以在设备上使用(我可以在浏览器中使用它来输入字母)。 并且意图types的火(但它只触发android.intent.action.MAIN)我没有得到DEVICE_ATTACHED意图。 日志条目来自示例代码:

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

在恢复function中。 在更多地挖掘并删除对usb的任何引用之后,我发现每个应用程序都会在连接/分离键盘时调用简历(因此意图:android.intent.action.MAIN日志条目)。 现在我唯一可以想到的是它是android源码中的一个bug。 顺便说一下,我正在使用带有操作系统3.1的wifi xoom。

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

  

xxxxx和yyyyy应为十进制数。 不是HEX代码。 然后这一切都像宣传的那样工作! 我知道它已经晚了但我希望它有所帮助。

所以我find了解决问题的方法,并且我已经学到了很多东西,希望它可以帮助别人。

因此,首先关闭HID设备不会启动任何意图 。 它们也不会出现在mUsbManager.getDeviceList()列表中。 然而其他事情。 我给了一个usb记忆棒,你知道该设备列在设备列表中。 我还发现返回的设备没有类,子类或协议。 调试显示父接口确实具有适当的类/子类/协议。 此外,如果您必须有设备筛选器。 我最终得到了一个class=0008 (USB STORAGE)来为我的目的工作。 我猜其他课也会奏效。

所以现在要搞清楚意图。 事实certificate,意图必须附加到启动器活动。 我试图将它附加到服务或接收器上的尝试将不会产生任何成果。 所以现在我得到了解雇的意图我现在看到当我连接我的设备(usb记忆棒)时popup通知它要求我将我的应用程序设置为该设备的默认设置。 现在完美我的应用程序每次连接该设备时都会运行。 请注意,系统将提示您输入每个唯一的设备。 但只有一次。 它看起来很像默认程序。

好吧,我认为这总结了我发现的东西。 太糟糕了,键盘/鼠标连接时无法得到通知。 还有件事儿。 tiamat内核没有任何问题,现在运行它没有问题。

我最近发现了类似问题的解决方案。

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

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

我在这里更详细地注意到我的解决方案: Android 3.1 USB-Host – BroadcastReceiver没有收到USB_DEVICE_ATTACHED

枚举设备

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

 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); HashMap deviceList = manager.getDeviceList(); 

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

 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); HashMap deviceList = manager.getDeviceList(); Iterator deviceIterator = deviceList.values().iterator(); while(deviceIterator.hasNext()){ UsbDevice device = deviceIterator.next() //your code } 

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

 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 seen = new LinkedList(); LinkedList attached = new LinkedList(); //there is a need for multithread support here // so the thread can watch for an exit condition while (true) { HashMap 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文档中发现了更多信息。 您似乎必须拥有设备filter才能使用意图。 所以我决定尝试使用类filter而不是供应商/产品ID。 我认为这将是更一般的,并希望抓住隐藏设备。 我使用03h作为类ID,我尝试了各种格式,我尝试了子类,我甚至使用lsusb来发现我的设备的类,子类和协议。 这些似乎没有任何帮助。 所以我进一步研究了sdk文档,并决定尝试枚举所有设备,看看os看到了类/子类/协议整数。 我将粘贴的代码复制到click侦听器并添加了log.v语句。 logcat中没有显示任何内容。

它看起来像美国系统没有看到任何设备(即使设备实际工作。)现在这非常表明USB设备连接意图没有触发。 现在我必须说我在我的xoom(tiamat)中使用自定义内核。 我以为这可能与前一段时间的问题有关,所以我回到了3.1。 现在仍在进步 现在这是在我尝试枚举之前,所以现在我将恢复agaian并继续使用库存,直到我确定内核不是问题。 当我发现更多时,我会回来查看。 成功与失败。 当然,如果还有其他任何人比我更好地解读这个问题,那么请进入最后一个注意事项当我在文档中看到这一点时,我对整个otg主机模式感到非常担心..请注意,系数是相同的,甚至认为它引用了两种方法枚举。 可能只是一个副本编写者的错误,但仍然担心一些因为所有这些失败。

我的应用程序设置为launchMode="singleTop" ,在该模式下,似乎getIntent().getAction()始终等于首次启动应用程序的操作。

因此,如果您手动启动应用程序然后插入设备(即使在切换远离该应用程序后),您将收到android.intent.action.MAIN

如果您终止应用程序然后插入设备,您将始终获得android.hardware.usb.action.USB_DEVICE_ATTACHED ,即使是切换回您的应用程序,甚至是旋转设备

我实际上在拔掉USB设备时很奇怪地收到意图,我认为没有记录 – 当然,当我的设备分离时,我会收到USB_DEVICE_ATTACHED

如果没有singleTop ,它会按预期工作,但如果您的应用已经打开并且您插入设备,那么您将获得另一个愚蠢的额外活动。

Android的API再次出现问题,过于复杂且难以使用。

这就是我检测USB / Media Connect的方法。

清单文件

         

我没有在活动和接收器中做任何事情。

看起来这条线正在做的事情。

  

根据我的测试,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设备是嵌入式控制器,因此设置子类和协议不是问题。

连接Usb键盘WONT消防USB_DEVICE_ATTACHED

相反,系统将触发Intent.ACTION_CONFIGURATION_CHANGED 。 但是,由于存在配置更改,系统将重新启动Activity。 您不会在重新启动活动时捕获该操作。 在这种情况下,您需要在Android Manifest中添加android:configChanges =“keyboard | keyboardHidden” ,以便在连接外部键盘后不会重新启动Activity。