Doug Conran
Doug Conran

Reputation: 459

ACTION_MEDIA_BUTTON not working in BroadcastReceiver

This is a follow on question from an earlier one of mine here.

I am using android sdk 26 on a Samsung Galaxy S7 running Android v8 and am trying to use the play/pause button (HEADSETHOOK, keycode 79) on the earphones. Following suggestions from @Commonsware and @Pawel I registered the receiver from within the main activity and that is now working because it recognises when the earphones are plugged/unplugged from the phone. However, in spite of being able to capture the button press when using onKeyDown in the foreground activity, it is not being recognised by the BroadcastReceiver as an ACTION_MEDIA_BUTTON (or anything else as far as I can make out). All that happens is that the default app (Google Assistant) is called when I do a long press and nothing at all on a short press.

Here is my code (all contained within the one class):

public class MainActivity extends AppCompatActivity {

private BroadcastReceiver headsetBtnReceiver;
private AudioManager mAudioManager;
private ComponentName mReceiverComponent;

Intent playerService;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    headsetBtnReceiver = new RemoteReceiver();
    Log.e("Udp SVC", "Registering Receiver ");
    IntentFilter mediaFilter = new IntentFilter();
    mediaFilter.setPriority(2148675);
    mediaFilter.addAction(Intent.ACTION_HEADSET_PLUG);               //  <-- Working
    mediaFilter.addAction(Intent.ACTION_MEDIA_BUTTON);               //  <-- Not working
    mediaFilter.addAction(Intent.ACTION_SEARCH);                     //  <-- Not working
    mediaFilter.addAction(Intent.ACTION_SEARCH_LONG_PRESS);          //  <-- Not working
    registerReceiver(this.headsetBtnReceiver, mediaFilter);

    mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    mReceiverComponent = new ComponentName(getApplicationContext(), RemoteReceiver.class);
    mAudioManager.registerMediaButtonEventReceiver(mReceiverComponent);
}

@Override
public void onDestroy() {
    Log.e("UDP svc", "Destroying MainActivity");
    mAudioManager.unregisterMediaButtonEventReceiver(mReceiverComponent);
    unregisterReceiver(headsetBtnReceiver);
    finish();
    super.onDestroy();
}

public static class RemoteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction();

        Log.e("Udp SVC","Into BroadcastReceiver : "+intentAction.toString());

        if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
            final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

            if (event != null && event.getAction() == KeyEvent.KEYCODE_HEADSETHOOK) {
                Log.e("Udp SVC","BroadcastReceiver headsethook ");
                /***************
                 switch (event.getKeyCode()) {
                 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                 context.startService(new Intent(context, PlayerService.class));
                 break;
                 }
                 **********/
            }
        }
    }
}

}

  1. What (if anything) am I doing wrong?
  2. What is the Intent constant for HEADSETHOOK (keycode 79)?
  3. If there is no such constant is it possible to add a specific keycode to the IntentFilter?

  4. Help!!

Upvotes: 2

Views: 1004

Answers (1)

Vitch612
Vitch612

Reputation: 29

add to build.gradle dependencies
implementation 'androidx.core:core:1.3.1'
implementation 'androidx.media:media:1.2.0'

then in your activity of foreground service:

    MediaSessionCompat mediaSession = new MediaSessionCompat(this, getPackageName());
    mediaSession.setActive(true);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        mediaSession.setCallback(new MediaSessionCompat.Callback() {
            @Override
            public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
                // do somethign with intent here
                return super.onMediaButtonEvent(mediaButtonIntent);
            }
        });
    }

And of course don't ask why google changes all their APIs each time they release a new version of Android. They want to follow their "best practices" while they don't have a clue how to design an API let alone an operating system.

Upvotes: 2

Related Questions