有没有人能够让android.hardware.usb.action.USB_DEVICE_ATTACHED“工作?”
好的,所以我正在尝试使用新的USB主机模式功能来检测何时连接USB设备。出于我的目的,我希望在设备连接时得到通知。我无法看到它发生。我正在使用我知道有效的广播接收器(当我听到其他东西时,例如按下主页按钮。无论我尝试什么,我似乎无法获得触发的意图......所以让事情更简单我决定忘记我的项目,并尝试使用谷歌自己的示例代码,看看我是否至少可以做到这一点。我没有一个导弹发射器,但我想我至少可以得到它USB_Device_Attached不用了。我修改了代码以适用于其他设备。首先我尝试调整设备过滤器xml。 我添加了我的设备(键盘):
<usb-device vendor-id="1050" product-id="0010" />
我从lsusb命令获得了供应商和产品。连接设备后,logcat会显示找到设备
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确实找到了键盘,它可以在设备上使用(我可以在浏览器中使用它来输入字母)。意图类型的火(但它只触发android.intent.action.MAIN)我没有得到DEVICE_ATTACHED意图。日志条目来自示例代码:
Log.d(TAG, "intent: " + intent.getAction().toString());
在恢复功能中。在更多地挖掘并删除对usb的任何引用后,我发现每个应用程序都会在连接/分离键盘时调用简历(因此意图:android.intent.action.MAIN日志条目)。 现在我唯一可以想到的是它是android源码中的一个bug。 顺便说一下,我正在使用带有操作系统3.1的wifi xoom。
答案 0 :(得分:21)
我也有同样的问题。我终于发现在设备过滤器xml中我们应该添加以下行。
<usb-device vendor-id-"xxxxx" product-id="yyyyy">
xxxxx和yyyyy应为十进制数。不是HEX代码。然后这一切都像宣传的那样工作! 我知道它已经晚了但我希望它有所帮助。
答案 1 :(得分:13)
所以我找到了解决问题的方法,并且我已经学到了很多东西,希望它可以帮助别人。
首先关闭 HID设备不会启动任何意图。它们也不会出现在mUsbManager.getDeviceList()
列表中。然而其他事情。我给了一个usb记忆棒,你知道该设备列在设备列表中。我还发现返回的设备没有类,子类或协议。调试显示父接口确实具有适当的类/子类/协议。
此外,如果您必须有设备筛选器。我最终得到class=0008 (USB STORAGE)
为我的目的工作。我猜其他课也可以。
所以现在要搞清楚意图。事实证明,意图必须附加到启动器活动。我试图将它附加到服务或接收器上的尝试不会有任何成果。所以现在我得到了解雇的意图我现在看到当我连接我的设备(usb记忆棒)时弹出通知它它要求我将我的应用程序设置为该设备的默认设置。现在完美我的应用程序每次连接该设备时都会运行。请注意,系统将提示您输入每个唯一的设备。但只有一次。它看起来很像默认程序。
嗯,我认为这总结了我发现的东西。当键盘/鼠标连接时,你无法收到通知。还有件事儿。 tiamat内核没有任何问题,现在运行它没有任何问题。
答案 2 :(得分:7)
我最近发现了类似问题的解决方案。
有人已经注意到,HID devices
没有启动意图,我认为这是你的问题。
但是,相关的问题是,如果您的程序设置为在连接USB设备时运行,那么即使您的应用程序运行,您也无法捕获USB_DEVICE_ATTACHED
操作。相反,系统会看到该意图,并说“哦,这意味着该应用程序想要运行(如清单中所声明的那样),然后它会向您发送android.intent.action.MAIN操作而不是USB_DEVICE_ATTACHED
操作,并调用onResume()
。即使您的应用程序正在运行。据我所知,如果您的清单声明您的应用程序将在连接USB设备时运行,则无法捕获USB_DEVICE_ATTACHED
意图你只需要在onResume()
中放一些代码来检查USB是否已连接。即使你的程序正在运行,当连接USB设备时,onResume也会再次被调用。
我在这里更详细地注意到我的解决方案:Android 3.1 USB-Host - BroadcastReceiver does not receive USB_DEVICE_ATTACHED
答案 3 :(得分:2)
枚举设备
如果您的应用程序有兴趣在应用程序运行时检查当前连接的所有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
}
答案 4 :(得分:2)
我遇到了同样的问题。我的最终解决方案是使用老式的轮询技术。这是一个相当小的课程,它解决了我满意的问题。
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();
}
}
答案 5 :(得分:2)
另一种解决方法是使用
new FileObserver("/dev/input") {
@Override public void onEvent(int event, String path) {
//gets called on input device insert / remove
}
};
适用于某些USB设备(键盘,鼠标)
答案 6 :(得分:1)
确定更多工作,更多失败,但取得了一些进展。
我从sdk文档中发现了更多信息。您似乎必须拥有设备过滤器才能使用意图。所以我决定尝试使用类过滤器而不是供应商/产品ID。我认为这将是更一般的,并希望抓住隐藏设备。我使用03h作为类ID,我尝试了各种格式,我尝试了子类,我甚至使用lsusb来发现我的设备的类,子类和协议。这些似乎没有任何帮助。所以我进一步研究了sdk文档,并决定尝试枚举所有设备,看看os看到了类/子类/协议整数。我将粘贴的代码复制到click侦听器并添加了log.v语句。 logcat中没有显示任何内容。
它看起来像美国系统没有看到任何设备(即使设备实际工作。)现在这非常表明USB设备连接意图没有触发。现在我必须说我在我的xoom(tiamat)中使用自定义内核。我以为这可能与前一段时间的问题有关,所以我恢复了库存3.1。现在还在进步现在这是在我尝试枚举之前,所以现在我将恢复agaian并继续使用库存,直到我确定内核不是问题。当我发现更多时,我会回来查看。成功与失败。当然,如果有其他人比我更好地解读这个请求。 最后一点说明当我在文档中看到这个时,我非常担心整个otg主机模式。请注意,即使它参考两种枚举方法,coe也是相同的。可能只是一个复制作者的错误,但仍然担心所有这些失败。答案 7 :(得分:1)
我的应用设置为launchMode="singleTop"
,在该模式下,似乎getIntent().getAction()
始终等于首次启动应用的操作。
因此,如果您手动启动应用程序并然后插入设备(即使在离开该应用程序后),您将收到android.intent.action.MAIN
。
如果你杀了应用程序然后插入设备,你将永远得到android.hardware.usb.action.USB_DEVICE_ATTACHED
,即使是切换回你的应用程序,甚至旋转设备。 / p>
我实际上在拔掉USB设备时非常奇怪地接受了意图,我认为这些设备没有记录 - 当然,当我的设备被拆卸时,我会收到USB_DEVICE_ATTACHED
。
如果没有singleTop
,它会按预期工作,但如果您的应用已经打开并插入设备,那么您将获得另一项愚蠢的额外活动。
Android的API再次出现问题,过于复杂且难以使用。
答案 8 :(得分:1)
这是我检测USB / Media Connect的方法。
清单文件
<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"/>
答案 9 :(得分:0)
根据我的测试,Android 可以在连接HID设备时触发意图。 (MissileLauncher示例应用程序就是这样做的。有关详细信息,请参阅示例源代码。)
Missile Launcher(Dream Cheeky USB Missle Launcher)HID Device的子类和协议设置为0x00。有关详细信息,请参阅:http://www.mattcutts.com/blog/playing-with-a-usb-missile-launcher/
需要注意的是,Android并没有特别针对鼠标和键盘设备(可能更多)。但是,我可以检测到其InterfaceClass = 0x03,InterfaceSubClass = 0x00,InterfaceProtocol = 0x00的HID设备。对于我的应用程序,我的HID设备是嵌入式控制器,因此设置子类和协议不是问题。
答案 10 :(得分:0)
连接Usb键盘 WONT 触发 USB_DEVICE_ATTACHED 。
相反,系统将触发 Intent.ACTION_CONFIGURATION_CHANGED 。但是,由于存在配置更改,系统将重新启动Activity。在重新启动Activity时,您不会捕获该操作。在这种情况下,您需要在Android Manifest中添加 android:configChanges =“keyboard | keyboardHidden”,以便在连接外部键盘后不会重新启动Activity。