@@ -47,6 +47,9 @@ public class AudioService extends MediaBrowserServiceCompat implements AudioMana
47
47
private static final int NOTIFICATION_ID = 1124 ;
48
48
private static final int REQUEST_CONTENT_INTENT = 1000 ;
49
49
private static final String MEDIA_ROOT_ID = "root" ;
50
+ // See the comment in onMediaButtonEvent to understand how the BYPASS keycodes work.
51
+ // We hijack KEYCODE_MUTE and KEYCODE_MEDIA_RECORD since the media session subsystem
52
+ // consideres these keycodes relevant to media playback and will pass them on to us.
50
53
public static final int KEYCODE_BYPASS_PLAY = KeyEvent .KEYCODE_MUTE ;
51
54
public static final int KEYCODE_BYPASS_PAUSE = KeyEvent .KEYCODE_MEDIA_RECORD ;
52
55
public static final int MAX_COMPACT_ACTIONS = 3 ;
@@ -565,7 +568,7 @@ private void acquireWakeLock() {
565
568
@ Override
566
569
public boolean onMediaButtonEvent (Intent mediaButtonEvent ) {
567
570
if (listener == null ) return false ;
568
- KeyEvent event = (KeyEvent )mediaButtonEvent .getExtras ().get (Intent .EXTRA_KEY_EVENT );
571
+ final KeyEvent event = (KeyEvent )mediaButtonEvent .getExtras ().get (Intent .EXTRA_KEY_EVENT );
569
572
if (event .getAction () == KeyEvent .ACTION_DOWN ) {
570
573
switch (event .getKeyCode ()) {
571
574
case KEYCODE_BYPASS_PLAY :
@@ -589,23 +592,30 @@ public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
589
592
case KeyEvent .KEYCODE_MEDIA_REWIND :
590
593
onRewind ();
591
594
break ;
592
- // The remaining cases are for media button clicks.
593
- // Unfortunately Android reroutes media button clicks to PLAY/PAUSE
594
- // events making them indistinguishable from from play/pause button presses.
595
- // We do our best to distinguish...
595
+ // Android unfortunately reroutes media button clicks to
596
+ // KEYCODE_MEDIA_PLAY/PAUSE instead of the expected KEYCODE_HEADSETHOOK
597
+ // or KEYCODE_MEDIA_PLAY_PAUSE. As a result, we can't genuinely tell if
598
+ // onMediaButtonEvent was called because a media button was actually
599
+ // pressed or because a PLAY/PAUSE action was pressed instead! To get
600
+ // around this, we make PLAY and PAUSE actions use different keycodes:
601
+ // KEYCODE_BYPASS_PLAY/PAUSE. Now if we get KEYCODE_MEDIA_PLAY/PUASE
602
+ // we know it is actually a media button press.
596
603
case KeyEvent .KEYCODE_MEDIA_PLAY :
597
- // If you press the media button while in the pause state, it resumes.
598
- MediaControllerCompat controller = mediaSession .getController ();
599
- if (resumeOnClick && controller .getPlaybackState ().getState () == PlaybackStateCompat .STATE_PAUSED ) {
600
- onPlay ();
601
- break ;
602
- }
603
- // Otherwise fall through and pass it to onClick
604
604
case KeyEvent .KEYCODE_MEDIA_PAUSE :
605
605
// These are the "genuine" media button click events
606
606
case KeyEvent .KEYCODE_MEDIA_PLAY_PAUSE :
607
607
case KeyEvent .KEYCODE_HEADSETHOOK :
608
- listener .onClick (mediaControl (event ));
608
+ MediaControllerCompat controller = mediaSession .getController ();
609
+ // If you press the media button while in the pause state, we reactivate the media session.
610
+ if (resumeOnClick && controller .getPlaybackState ().getState () == PlaybackStateCompat .STATE_PAUSED ) {
611
+ play (new Runnable () {
612
+ public void run () {
613
+ listener .onClick (mediaControl (event ));
614
+ }
615
+ });
616
+ } else {
617
+ listener .onClick (mediaControl (event ));
618
+ }
609
619
break ;
610
620
}
611
621
}
0 commit comments