Fail to Intercept Bluetooth headset media button events

Ram.ShRam.Sh ILUniversity ✭✭

using API 28 Im trying to catch bluetooth headset media buttons events (say the "next" button), on a c# Xamarin android app. i copied the code found here, but clicking the headset's button starts spotify on a phone that has it installed, and google's "play music" app on a phone that doesnt. either way my "OnReceive" event never gets fired. please see the commented-out code for all variations i already tried, to no avail.

from other sources and discussions I've also tried to set highest priority as 999, 1000 and 2147483647 to the receiver

my manifest's tag (tried also ".BroadcastReceiver" and full package name):

<receiver android:name="BroadcastReceiver">
    <intent-filter android:priority="2147483647">
        <action android:name="android.intent.action.MEDIA_BUTTON" />
    </intent-filter>
</receiver>

and these permissions:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />

my MainActivity class:

[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {
        [Obsolete]
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            SetContentView(Resource.Layout.activity_main);

            Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);

            var am = (AudioManager)this.GetSystemService(AudioService);
            var componentName = new ComponentName(PackageName, new MyMediaButtonBroadcastReceiver().ComponentName);
            am.RegisterMediaButtonEventReceiver(componentName);
        }

        public override bool OnCreateOptionsMenu(IMenu menu)
        {
            MenuInflater.Inflate(Resource.Menu.menu_main, menu);
            return true;
        }

        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            int id = item.ItemId;
            if (id == Resource.Id.action_settings)
            {
                return true;
            }

            return base.OnOptionsItemSelected(item);
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

[BroadcastReceiver] //(Enabled = true, Exported = false)
    [IntentFilter(new[] { "android.intent.action.MEDIA_BUTTON"})] // , BluetoothHeadset.ActionAudioStateChanged, BluetoothHeadset.ActionVendorSpecificHeadsetEvent
    public class MyMediaButtonBroadcastReceiver : BroadcastReceiver
    {
        public string ComponentName { get { return Class.Name; } }

        public override void OnReceive(Context context, Intent intent)
        {
            if (intent.Action != Intent.ActionMediaButton)
                return;

            var keyEvent = (KeyEvent)intent.GetParcelableExtra(Intent.ExtraKeyEvent);

            switch (keyEvent.KeyCode)
            {
                case Keycode.MediaPlay:
                    break;
                case Keycode.MediaPlayPause:
                    break;
                case Keycode.MediaNext:
                    break;
                case Keycode.MediaPrevious:
                    break;
            }
        }
    }

got no errors, but nothing else happens, either.

Can anyone please help me?

Best Answer

Answers

  • Ram.ShRam.Sh ILUniversity ✭✭

    I've also tried a different approach using MediaSession based on this post:

    public class cb : MediaSession.Callback
    {
        public override bool OnMediaButtonEvent(Intent mediaButtonIntent)
        {
            //do stuff
        }
    }
    
    override void OnCreate(Bundle bundle)
    {
        var s = new MediaSession(ApplicationContext, "asdf");
        s.SetCallback(new cb());
    
        s.SetFlags(MediaSessionFlags.HandlesMediaButtons | MediaSessionFlags.HandlesTransportControls);
        s.Active = true;
    }
    

    however, as before, got no errors, but nothing else happens, either....

  • Ram.ShRam.Sh ILUniversity ✭✭

    @LeonLu - many thanks for you reply!

    unfortunately this also being captured by Spotify and the Callback event never fired when the BL device sends ActionNext

    are there any special settings I need to add to the project? I have the following permission:

     this.RequestPermissions(new[]
                {
                    Manifest.Permission.AccessCoarseLocation,
                    Manifest.Permission.BluetoothPrivileged,
                    Manifest.Permission.MediaContentControl,
                    Manifest.Permission.BluetoothAdmin,
                    Manifest.Permission.Bluetooth                
                }, 0);
    
    
  • Ram.ShRam.Sh ILUniversity ✭✭

    OK! got it to work!! the audiotrack was the problem!

Sign In or Register to comment.