Skip to content

fix(android): resolve media button handling - #48

Merged
wyrindev merged 3 commits into
mainfrom
fix/android-media-button-and-audio-source
Sep 27, 2026
Merged

wyrindev merged 3 commits into
mainfrom
fix/android-media-button-and-audio-source

Conversation

@wyrindev

@wyrindev wyrindev commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Description

Fixes #38.

This PR addresses hardware and Bluetooth media button key event dispatching on Android and introduces audio source switching to the example application.

Changes

1. Android Media Button Handling

  • MediaButtonReceiver: Added an explicit BroadcastReceiver to handle ACTION_MEDIA_BUTTON intents and route KeyEvent directly to the active FlutterMediaSessionService instance in memory, avoiding ForegroundServiceStartNotAllowedException on Android 12+.
  • Unified Event Handling: Refactored handleMediaKeyEvent in FlutterMediaSessionService so key events from both MediaSession.Callback.onMediaButtonEvent and onStartCommand share consistent dispatch logic to Flutter.
  • AudioAttributes: Explicitly assigned USAGE_MEDIA and CONTENT_TYPE_MUSIC to forward player attributes for better system audio routing compatibility.
  • Cleaned Up Obsolete Reflection: Removed legacy setMediaButtonReceiver reflection calls on sessionCompat, aligning with standard Media3 automated session binding.

2. Example App Improvements

  • Audio Source Switcher: Added an audio source toggle in SettingsPanel (Official SoundHelix vs. Cloudflare CDN) to accommodate varied network latency across regions.
  • AGP 9.0+ & KGP Compatibility: Updated example/android/app/build.gradle.kts to dynamically support AGP 9.0+ built-in Kotlin while safely configuring jvmTarget = 17 for both KGP 1.x and 2.x.
  • .gitignore: Aligned root .gitignore with the standard Flutter repository template.

@wyrindev

Copy link
Copy Markdown
Owner Author

Hi @a-tunc

Apologies for the slow response—I've been quite busy with school lately.

I believe this should now be resolved in the latest branch. If you get a chance, could you give it a try with your headset and verify if media controls are functioning properly?

Thank you so much for your patience and for reporting this!

@a-tunc

a-tunc commented Sep 25, 2026

Copy link
Copy Markdown

Hi @wyrindev ,

I used this branch for testing:
android-media-button-and-audio-source

I tested it on an Android 11 device with a bluetooth headset.

Unfortunately media control buttons on the headset still do not work. What I mean is there is no response from the example app whichever button I press on the headphones.

Here is the output of logcat command and I added some comments to shed a light to what I did when.

adb logcat -c && adb logcat -v time FlutterMediaSession:D MediaSessionCompat:D MediaButtonReceiver:D *:S
--------- beginning of main
--------- beginning of system

/* I connected my headphones and started the app at this point */

09-25 12:02:07.857 D/FlutterMediaSession(15274): Successfully registered custom action 'repeat' with iconResId: 2131165285
09-25 12:02:07.857 D/FlutterMediaSession(15274): Successfully registered custom action 'shuffle' with iconResId: 2131165288

/* I started playing a tune using the example app */
/* I pressed pause button on headset. Nothing appeared here */
/* I pressed skip-to-next and skip-to-previous buttons on headset in that order. Nothing appeared here */

/* I pressed pause on the lock screen media controls. Below lines appeared */
09-25 12:02:48.571 I/FlutterMediaSession(15274): onMediaButtonEvent: action=0, keyCode=85
09-25 12:02:48.571 I/FlutterMediaSession(15274): handleMediaKeyEvent: action=0, keyCode=85
09-25 12:02:48.572 I/FlutterMediaSession(15274): sendAction: action=pause, args=null, eventSink=true

/* I uninstalled the app at this point */

09-25 12:03:19.156 W/MediaSessionCompat(18553): Couldn't find a unique registered media button receiver in the given context.

I hope this helps.

@wyrindev

Copy link
Copy Markdown
Owner Author

😳 Thanks for the report and logs. I'll look into this.

@wyrindev

Copy link
Copy Markdown
Owner Author

After investigating the audio routing dispatch mechanism (MediaSessionService / MediaSessionStack) and examining how production media apps (such as YouTube Music) maintain backwards compatibility, introduced a dedicated compatibility layer (MediaButtonRoutingCompat) for Android 11 and older.

Verified on Android 11 (API 30) and modern Android versions—media button events are routed.

@a-tunc

a-tunc commented Sep 26, 2026

Copy link
Copy Markdown

Tested on Android 11 device. I tested pause/play buttons as well as skip-to-previous and skip-to-next buttons. All of them work perfectly.!

Thank you for your time/effort to get this working.

@wyrindev
wyrindev merged commit bb3e1df into main Sep 27, 2026
6 checks passed
@wyrindev
wyrindev deleted the fix/android-media-button-and-audio-source branch September 27, 2026 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android implementation is capturing hardware media button actions

2 participants