安卓3.1 USB主机 - BroadcastReceiver的不接收USB_DEVICE_ATTACHED [英] Android 3.1 USB-Host - BroadcastReceiver does not receive USB_DEVICE_ATTACHED

查看:950
本文介绍了安卓3.1 USB主机 - BroadcastReceiver的不接收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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆