为什么在连接 USB 时 activity 崩溃

Why simply activity crash when USB is attaching

我创建了一个简单的 activity 来测试通过 attached/detached USB 设备将 intent 传入我的 android 平板电脑。我开始 activity 并尝试 附加 USB,然后弹出错误 "application .... stopped working."。当我在连接 USB 电缆的情况下启动应用程序时出现同样的事情,然后我尝试断开 USB.

提示:本例仅供测试。我需要写一个service,它会通过USB自动从设备接收数据并将它们上传到服务器(这部分已经可以运行)。现在我处理如何自动启动service,最好的会在USB设备连接的那一刻出现。

思考1:问题可能是device_filter方法不对?系统向 Receiver 发送 intent,他想处理它,但没有找到 device_filter 而不是失败?我尝试路径:TestUSB.xml.device_filter.xml 或 TestUSB.Resources.xml.device_filter.xml 但没有成功。

考虑 2:配置不正确 AndroidManifest.xml 并且缺少某些权限?

考虑3:还是平板有问题/OS?目前我有一个不同的硬件来测试它。

我使用平板电脑 alps 874v3 android 4.4.2,USB 设备是我们带有 FTDI 芯片的特殊硬件。

我使用 Visual studio 2010 和 Xamarin 在 .net 中编写 Android 应用程序

[Activity(Label = "TestUSB", MainLauncher= true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        int count = 0;
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);
            Button button = FindViewById<Button>(Resource.Id.MyButton);            
            button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };
        }
    }
    public class UsbBroadcastReceiver : BroadcastReceiver
    {
        public UsbBroadcastReceiver()
        {
        }
        public override void OnReceive(Context context, Intent intent)
        { 
            InvokeAbortBroadcast();            
        }
    }

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="TestUSB.TestUSB" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
        <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="19" />
        <application android:label="TestUSB" android:icon="@drawable/Icon" android:launchMode="singleTask">
            <receiver android:enabled="true" android:exported="true" android:name=".UsbBroadcastReceiver" android:launchMode="singleTask">
                <uses-feature android:name="android.hardware.usb.host" android:required="false" />
          <uses-permission android:name="android.permission.USB_PERMISSION" />
          <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" />
            </receiver>
        </application>
</manifest>

device_filter.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <!--<usb-device vendor-id="0403" product-id="6001" /> FTDI FT232R UART in hexa-->
  <usb-device vendor-id="1027" product-id="24577" /><!--FTDI FT232R UART in decimal-->
</resources>

**编辑:** 我又借了一个新的 phone Huawei 试了一下 there.It 像个平板电脑

实际日志

 D/ActivityManager(  654): AP_PROF:AppLaunch_LaunchTime:TestUSB.TestUSB/md537e255c671aa66f9ada9a57df4bd0038.MainActivity:1104:3576760
    D/ActivityManager(  654): ACT-IDLE_NOW_MSG from windowsVisible() for idle: ActivityRecord{41fd3280 u0 TestUSB.TestUSB/md537e255c671aa66f9ada9a57df4bd0038.MainActivity t33}
    W/UsbSettingsManager(  654): no meta-data for ResolveInfo{4266c658 TestUSB.TestUSB/md537e255c671aa66f9ada9a57df4bd0038.MainActivity m=0x108000}


W/System.err( 7880): java.lang.RuntimeException: Unable to instantiate receiver 
    TestUSB.TestUSB.UsbBroadcastReceiver: java.lang.ClassNotFoundException: 
    Didn't find class "TestUSB.TestUSB.UsbBroadcastReceiver" on path:
     DexPathList[[zip file "/data/app/TestUSB.TestUSB-1.apk"],nativeLibraryDirectories=[/data/app-lib/TestUSB.TestUSB-1,
    /vendor/lib, /system/lib]]

AndroidManifest.xml 由 VS+Xamarin 生成:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="TestUSB.TestUSB" android:versionCode="1" android:versionName="1.0">
  <uses-sdk android:minSdkVersion="11" />
  <application android:label="TestUSB" android:icon="@drawable/icon" android:name="mono.android.app.Application" android:debuggable="true">
    <receiver android:enabled="true" android:exported="true" android:name=".UsbBroadcastReceiver" android:launchMode="singleTask">
      <uses-feature android:name="android.hardware.usb.host" android:required="false" />
      <uses-permission android:name="android.permission.USB_PERMISSION" />
      <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" />
      <!--<intent-filter>
        <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
      </intent-filter>
      <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"  android:resource="@xml/accessory_filter" />-->
    </receiver>
    <activity android:icon="@drawable/icon" android:label="TestUSB" android:name="md537e255c671aa66f9ada9a57df4bd0038.MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
        <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
      </intent-filter>
    </activity>
    <provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="TestUSB.TestUSB.mono.MonoRuntimeProvider.__mono_init__" />
    <receiver android:name="mono.android.Seppuku">
      <intent-filter>
        <action android:name="mono.android.intent.action.SEPPUKU" />
        <category android:name="mono.android.intent.category.SEPPUKU.TestUSB.TestUSB" />
      </intent-filter>
    </receiver>
  </application>
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>

考虑到这种抽象形式 Official Documentation:

The following list describes what you need to add to your application's manifest file before working with the USB accesory APIs. The manifest and resource file examples show how to declare these items:

Because not all Android-powered devices are guaranteed to support the USB accessory APIs, include a element that declares that your application uses the android.hardware.usb.accessory feature. If you are using the add-on library, add the element specifying com.android.future.usb.accessory for the library. Set the minimum SDK of the application to API Level 10 if you are using the add-on library or 12 if you are using the android.hardware.usb package.

并作为过滤器管理 USB Attach/Detach:

<activity ...>
...
<intent-filter>
    <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>

<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
    android:resource="@xml/accessory_filter" />

问题是系统错误地找到了接收器。 Xamarin 项目注册接收者/活动尚未在 AndroidManifest.xml 中,但 必须注册相关 class 作为属性。

[BroadcastReceiver(Enabled=true,Exported=true,Permission="android.permission.USB_PERMISSION")]
[UsesLibrary("android.hardware.usb.host", Required = true)]
[MetaData("android.hardware.usb.action.USB_DEVICE_ATTACHED", Resource = "@xml/device_filter")]
[MetaData("android.hardware.usb.action.USB_DEVICE_DETACHED", Resource = "@xml/device_filter")]
[IntentFilter(new string[] { "android.hardware.usb.action.USB_DEVICE_ATTACHED", "android.hardware.usb.action.USB_DEVICE_DETACHED" })]
public class UsbBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        if (intent != null) Log.Debug("testusb", string.Format("OnReceive - {0} ", intent.Action));            
    }
}