Is there a Xamarin equivalent to "android.hardware.usb.action.USB_STATE"?

I was looking to get a USB accessory attached, and notice that if your app is not on top when the USB is plugged in, it gets an OnResume with intent, which I'm going to delve into next (stay tuned :smile:).

But if your app is on top, it doesn't get any such OnResume trigger (which makes sense, I suppose). But then how do I know to reconnect to the USB device? I thought perhaps I could try:

Any ideas?

Tagged:

Best Answer

  • Accepted Answer

    The answer seems to be no at the moment. I found that when working with the USB state broadcast, that the one with intent.GetBooleanExtra("configured", false) == true (last of three triggered when I plug my OTG modified Due in) is the one that allows me to connect to the USB again. That way it reconnects even if the app is open when it is plugged in!

Answers

  • JonathanJohansenJonathanJohansen Member ✭✭
    edited October 2018

    Could I perhaps just use the literal "android.hardware.usb.action.USB_STATE"? I feel as though it might work, but smells hacky.

    I tested it with below BroadcastReceiver and it does indeed fire! But I'd still like to know from someone more knowledgeable if there's a better way. :wink:

    [BroadcastReceiver(Enabled = true)]
    [Android.App.IntentFilter(actions: new[] { "android.hardware.usb.action.USB_STATE" })]
    [Android.App.MetaData(Android.Hardware.Usb.UsbManager.ActionUsbAccessoryDetached, Resource = "@xml/usb_filter")]
    class BroadcastReceiverUsbState : BroadcastReceiver
    {
        public BroadcastReceiverUsbState() { }
    
        public override void OnReceive(Context context, Intent intent)
        {
            Android.Util.Log.Debug(GetType().ToString(), $"got state broadcast!");
            if (context is MainActivity)
            {
                MainActivity mainActivity = (MainActivity)context;
                mainActivity.usbIsDetached = true;
                Toast.MakeText(context, $"We got state broadcast: {intent.ToString()}", ToastLength.Long).Show();
            }
            else
            {
                Toast.MakeText(context, $"{context.GetType()} got state broadcast: {intent.ToString()}", ToastLength.Long).Show();
            }
        }
    }
    
  • BillyLiuBillyLiu Member, Xamarin Team Xamurai

    @JonathanJohansen
    What's the version of Android are you using?
    Have you registered your BroadcastReceiver? Starting in Android 8.0, it is not possible for an application to statically register for an implicit broadcast.

    Please check the following link:
    https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/broadcast-receivers#statically-registering-a-broadcast-receiver-with-an-intent-filter

  • Hi @BillyLiu, I'm compiling using Android 8.1 (Oreo), for API levels 15-27. I have read about the exceptions to static broadcast registrations, and USB is excluded from the 'ban'. What I've posted above works for me on an Android 7.0 PDA - I just thought there might be a more official way to get USB state updates.

  • JonathanJohansenJonathanJohansen Member ✭✭
    Accepted Answer

    The answer seems to be no at the moment. I found that when working with the USB state broadcast, that the one with intent.GetBooleanExtra("configured", false) == true (last of three triggered when I plug my OTG modified Due in) is the one that allows me to connect to the USB again. That way it reconnects even if the app is open when it is plugged in!

  • hexagodhexagod Member ✭✭✭
    edited November 2018

    @JonathanJohansen how are you using databinding like that in xamarin.android ... ? I thought curly brackets were only in xamarin.forms

  • @hexagod, you could perhaps be referring to string interpolation, as in $"{context.GetType()} got state broadcast: {intent.ToString()}", or to the Android resource selector like Resource = "@xml/usb_filter". I know I don't have databinding - I do miss it.

Sign In or Register to comment.