安卓3.1 USB主机 - BroadcastReceiver的不接收USB_DEVICE_ATTACHED [英] Android 3.1 USB-Host - BroadcastReceiver does not receive USB_DEVICE_ATTACHED
问题描述
我在developer.android.com曾通过的描述,来样USB主机来检测安装和拆卸的USB设备。
I worked through the description and samples for USB host at developer.android.com to detect attached and detached USB-devices.
如果我使用一个意图过滤器清单文件中,当一个设备连接到启动我的应用程序,它工作完全正常:插上,设备检测,机器人要求的权限启动应用程序,设备信息会显示在一个桌子。
If I use an intent-filter in the manifest file to start my application when a device is attached, it works perfectly fine: Plug in, device is detected, android asks for permission to start the application, device information is displayed in a table.
我正在开发不应该启动的应用程序/只完成了设备是否连接/分离(如数据管理)。此外,我不希望开对话框弹出,如果应用程序已经在运行。所以,我决定不直接启动活动,如果一个设备连接,而是注册一个BroadcastReceiver,它是(后)应该通知活动设备是否AT- /分离。该接收机识别分离动作就好了,但没有附加动作。
The application I'm developing shouldn't be started/finished only if a device is attached/detached (e.g. data management purposes). Also I do not want the open-dialog to pop up if the app is already running. So I decided not to start the activity directly if a device is attached, but to register a BroadcastReceiver, which is (later) supposed to notify the activity if a device is at-/detached. This receiver recognizes the detach-action just fine, but not the attach-action.
我缺少权限或数据的属性或类似的东西?本教程和样品不说有关的其他必要的属性什么。
Am I missing a permission or data attribute or something like that? The tutorial and samples don't say anything about additional necessary attributes.
下面是清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="de.visira.smartfdr"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="12" />
<uses-feature android:name="android.hardware.usb.host" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name=".usb.Detector">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
android:resource="@xml/device_filter" />
</receiver>
</application>
和接收器:
public class FDRDetector extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Toast.makeText(context, "Action: " + action, 3).show();
// pops up only if action == DETACHED
}
我不明白为什么同样的意图过滤器的作品,如果我使用他们的活动,但如果它们应用到接收机?即使我成立于code接收器和过滤器,十分不认可。
I don't understand why the same intent-filter works, if I use them on an activity, but not if they are applied to a receiver? Even if I set up the receiver and filter in code, attaches are not recognized.
我的工作环境: IDE:Eclipse的3.7与Android插件
My work environment: IDE: Eclipse 3.7 with Android Plugin
设备:宏碁ICONIA TAB A500
Device: Acer Iconia Tab A500
Android版本:3.1
Android: 3.1
在此先感谢
推荐答案
啊哈!我想到了。我有完全相同的问题。
Aha! I figured it out. I was having the exact same problem.
它的要点是 - 如果你有你的应用程序启动时自动将设备插入(使用清单文件),随后便出现了Android的系统的获取ACTION_USB_DEVICE_ATTACHED意图,然后自它知道你的应用程序要在这种情况下运行,它实际上将您的应用程序android.intent.action.MAIN意图。它永远不会发送,因为它认为它已经知道你的应用程序想要做在这种情况下什么ACTION_USB_DEVICE_ATTACHED行动,你的应用程序。
The gist of it is - if you have your application launch automatically when a device is plugged in (using the manifest file), then it appears the Android system gets the ACTION_USB_DEVICE_ATTACHED intent, and then since it knows your application wants to run in that situation, it actually sends your application the android.intent.action.MAIN intent. It never sends the ACTION_USB_DEVICE_ATTACHED action to your application because it thinks it already knows what your application wants to do in that situation.
我刚才发现的问题,我想我有一个解决办法,但我可以告诉你,我已经找到了:
I've just now identified the problem, and I think I have a solution, but I can tell you what I've found:
即使你的应用程序正在运行,并在前台,当你插上USB设备,Android系统得到ACTION_USB_DEVICE_ATTACHED意图,它会在你的活动调用onResume()。
Even if your app is running and in the foreground, when you plug in the USB device and the Android system gets the ACTION_USB_DEVICE_ATTACHED intent, it will call onResume() in your activity.
不幸的是,你不能只是做到这一点:
Unfortunately, you cannot just do this:
@Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
Log.d(TAG, "intent: " + intent);
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
//do something
}
}
由于意图会回来的android.intent.action.MAIN,不ACTION_USB_DEVICE_ATTACHED。
Because the intent will come back as android.intent.action.MAIN, NOT ACTION_USB_DEVICE_ATTACHED.
这是烦人,你的也的获取android.intent.action.MAIN如果你只是离开应用程序,但不要拔下USB。我想象把设备休眠和唤醒它备份会做同样的事情。
An annoyingly, you also get android.intent.action.MAIN if you just leave the app, but don't unplug USB. I imagine putting the device to sleep and waking it back up will do the same thing.
因此,从我发现,你不能得到的意图直接,但它似乎是你可以依靠onResume()被调用时,将USB设备插入,所以解决方法就是检查如果USB每次都连接你会得到一个onResume。您还可以设置当然是因为一个标志,当USB断开,断开USB意图火灾就好了。
So from what I have found, you can't get the intent directly, but it does appear that you can rely on onResume() being called when a USB device is plugged in, so the solution is to just check to see if USB is connected every time you get an onResume. You can also set a flag when USB is disconnected, because of course the USB disconnect intent fires just fine.
因此,在总,你的广播接收器可能是这样的:
So in total, your broadcast receiver might look like this:
// BroadcastReceiver when remove the device USB plug from a USB port
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
usbConnected=false;
}
}
};
您已经有了这个里面的onCreate的:
You'd have this inside of onCreate:
// listen for new devices
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(mUsbReceiver, filter);
这正好在你的清单中的活动标记中:
This goes inside of the activity tag in your manifest:
<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/device_filter" />
您将有看起来像这样在你的/ RES / XML /文件夹中的文件device_filter.xml:
You'll have a device_filter.xml file in your /res/xml/ folder that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1027" product-id="24577" />
<usb-device vendor-id="1118" product-id="688" />
</resources>
(当然,与任何厂商ID和你需要的产品的ID)
(of course with whatever vendor IDs and product IDs you need)
然后你的onCreate看起来是这样的:
And then your onCreate looks something like this:
@Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
Log.d(TAG, "intent: " + intent);
String action = intent.getAction();
if (usbConnected==false ) {
//check to see if USB is now connected
}
}
我没有具体的$ C $下检查是否USB连接,我居然还没有深入研究的呢。我使用的库,如果能够将只需连接,所以我的应用程序,我可以只启动一个循环,我很好。
I don't have specific code for checking to see if USB is connected as I actually haven't delved into that yet. I'm using a library that will just connect if it can, so for my application I can just start that loop and I'm good.
它也可能是重要的它重新运行时,它已经运行,或者插入USB设备设置你的活动launchmode在清单中,以singleTask,以prevent将刚刚推出的第二个实例您应用!
Its also probably important to set the launchmode of your activity in the manifest to "singleTask" to prevent it from running again when its already running, or else plugging in a USB device will just launch a second instance of your application!
所以在我的清单我的整个活动代码如下所示:
So my whole activity tag in my manifest looks like this:
<activity
android:label="@string/app_name"
android:name="com.awitness.common.TorqueTablet"
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden"
android:launchMode="singleTask"
>
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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/device_filter" />
</activity>
无论如何,我希望这可以帮助别人!我很惊讶,我无法找到一个解决方案了!
Anyway, I hope this helps someone! I was surprised that I was unable to find a solution for this already!
这篇关于安卓3.1 USB主机 - BroadcastReceiver的不接收USB_DEVICE_ATTACHED的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!