Search code examples
androidmedia-buttons

How to capture Media Buttons while screen is locked?


I am trying to figure out how apps like Spotify capture headsetbutton presses while the screen is off or locked. I am currently able to catch button presses with my class HeadSetActionButtonReciever, only while the app is in foreground. But I am not able to capture these clicks while app is in background. Can someone explain to me why that is and how it can be captured in background?

public class HeadsetActionButtonReceiver extends BroadcastReceiver {

public static Delegate delegate;

private static AudioManager mAudioManager;
private static ComponentName mRemoteControlResponder;

private static int doublePressSpeed = 300; // double keypressed in ms
private static Timer doublePressTimer;
private static int counter;

public interface Delegate {
    void onMediaButtonSingleClick();
    void onMediaButtonDoubleClick();
}

@Override
public void onReceive(Context context, Intent intent) {
    if (intent == null || delegate == null || !Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()))
        return;

    KeyEvent keyEvent = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT);
    if (keyEvent == null || keyEvent.getAction() != KeyEvent.ACTION_DOWN) return;

    counter++;
    if (doublePressTimer != null) {
        doublePressTimer.cancel();
    }
    doublePressTimer = new Timer();
    doublePressTimer.schedule(new TimerTask() {

        @Override
        public void run() {
            if (counter == 1) {
                delegate.onMediaButtonSingleClick();
            } else {
                delegate.onMediaButtonDoubleClick();
            }
            counter = 0;
        }
    }, doublePressSpeed);
}

public static void register(final Context context) {
    mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    mRemoteControlResponder = new ComponentName(context, HeadsetActionButtonReceiver.class);
    mAudioManager.registerMediaButtonEventReceiver(mRemoteControlResponder);
}

public static void unregister(final Context context) {
    mAudioManager.unregisterMediaButtonEventReceiver(mRemoteControlResponder);
    if (doublePressTimer != null) {
        doublePressTimer.cancel();
        doublePressTimer = null;
    }
}
}

Solution

  • The problem was that i did not have a MediaSession. Apps like Spotify use a MediaSession in order to capture clicks in background. The application looks for the last active mediaSession in background, if it is not active then it will try to restart it (if in background).

    Edit: The class that i included is not needed at all in order to capture media buttons if you have a MediaSession instead.