Search code examples
c#androidxamarinusbftdi

Why simply activity crash when USB is attaching


I created a simple activity to test the incoming of intent by attached/detached the USB device into my android tablet. I start activity and try to attached USB and at that moment pop up error "application .... stopped working." appears. The same thing appears when I start the application with USB cable connected and than I try disconnect the USB.

Hint: This example is only for the test. I need to write a service that will automatically receive data from the device via USB and upload them to the server (this part is already operational). Now I deal with how to automaticly start the service, and the best will come to me at the moment when USB device connects.

Consideration 1 : The problem may be the wrong way to device_filter? The system sends intent to Receiver and he wants to handle it, but do not find device_filter and than fall? I try path : TestUSB.xml.device_filter.xml or TestUSB.Resources.xml.device_filter.xml but without success.

Consideration 2 : Incorrectly configured AndroidManifest.xml and missing some privileges?

Consideration 3 : Or a problem in the tablet / OS? Currently I have a different hardware on which to test it.

I use a tablet alps 874v3 android 4.4.2 and USB device is our special hardware with FTDI chip.

I use Visual studio 2010 with Xamarin to write Android app in .net

[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>

**EDIT : ** I borrowed another new phone Huawei and tried there.It acts like a tablet

Actual LOG

 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 generated by 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>

Solution

  • The problem was that the system incorrectly found the receiver. The Xamarin projects registration receiver / activities have not be in AndroidManifest.xml, but must register for the relevant class as attributes.

    [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));            
        }
    }