From 5ba964d130fd51e56a8db66239c4d51d45315bdf Mon Sep 17 00:00:00 2001 From: carlos-aurelio Date: Fri, 21 Dec 2018 16:29:14 -0200 Subject: [PATCH] Support player control through headset hook button Allow controlling the player and playlist by pressing the headset hook button one or more times in a short interval: 1: play/pause 2: skip to next track 3: skip to beginning of current track/previous track Signed-off-by: Carlos Aurelio --- .../receiver/MediaButtonsReceiver.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/app/src/main/java/org/helllabs/android/xmp/service/receiver/MediaButtonsReceiver.java b/app/src/main/java/org/helllabs/android/xmp/service/receiver/MediaButtonsReceiver.java index 10c50661..0d4dd6ec 100644 --- a/app/src/main/java/org/helllabs/android/xmp/service/receiver/MediaButtonsReceiver.java +++ b/app/src/main/java/org/helllabs/android/xmp/service/receiver/MediaButtonsReceiver.java @@ -7,12 +7,53 @@ import android.content.Intent; import android.view.KeyEvent; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; public class MediaButtonsReceiver extends BroadcastReceiver { private static final String TAG = "MediaButtonsReceiver"; public static final int NO_KEY = -1; private static int keyCode = NO_KEY; + private static long smartKeyPressMaxDelayMs = 500; protected boolean ordered = true; + protected static final Semaphore smartButtonSem = new Semaphore(0); + + protected static Thread smartKeyThread = new Thread(new Runnable() { + public void run() { + Log.i(TAG, "Started smart button thread"); + try { + while (true) { + smartButtonSem.acquire(); + int pressCount = 1; + Log.i(TAG, "First smart button press, waiting next presses..."); + while (smartButtonSem.tryAcquire(smartKeyPressMaxDelayMs, TimeUnit.MILLISECONDS)) { + pressCount++; + Log.i(TAG, "Smart button press #" + pressCount + ", waiting next presses..."); + } + Log.i(TAG, "Total smart button key presses: " + pressCount); + switch (pressCount) { + case 1: //play/pause + keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE; + break; + case 2: // next + keyCode = KeyEvent.KEYCODE_MEDIA_NEXT; + break; + default: // previous + keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS; + break; + } + } + } catch (InterruptedException ex) { + Log.e(TAG, ex.getMessage()); + } + } + }); + + public MediaButtonsReceiver() { + if (!smartKeyThread.isAlive()) { + smartKeyThread.start(); + } + } @Override public void onReceive(final Context context, final Intent intent) { @@ -36,6 +77,10 @@ public void onReceive(final Context context, final Intent intent) { Log.i(TAG, "Key code " + code); keyCode = code; break; + case KeyEvent.KEYCODE_HEADSETHOOK: + Log.i(TAG, "Smart key pressed"); + smartButtonSem.release(); + break; default: Log.i(TAG, "Unhandled key code " + code); }