diff --git a/res/raw/beep.wav b/res/raw/beep.wav
new file mode 100644
index 00000000..6ff49c07
Binary files /dev/null and b/res/raw/beep.wav differ
diff --git a/res/values/translatable.xml b/res/values/translatable.xml
index f5f613aa..9ac927b4 100644
--- a/res/values/translatable.xml
+++ b/res/values/translatable.xml
@@ -142,6 +142,8 @@ THE SOFTWARE.
Volume
Headset/Bluetooth Controls
This is also required for ICS lockscreen controls.
+ Headset Control Beep
+ Beep after skipping a track with a headset control double click.
External Output Only
Prevents music from being played through the internal speakers.
Pause When Unplugged
diff --git a/res/xml/preference_audio.xml b/res/xml/preference_audio.xml
index 5022c434..492227b5 100644
--- a/res/xml/preference_audio.xml
+++ b/res/xml/preference_audio.xml
@@ -34,6 +34,11 @@ THE SOFTWARE.
android:title="@string/media_button_title"
android:summary="@string/media_button_summary"
android:defaultValue="true" />
+
+ * Copyright (C) 2012 Christopher Eby
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,12 +22,14 @@
package org.kreed.vanilla;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.BroadcastReceiver;
import android.content.SharedPreferences;
+import android.media.AsyncPlayer;
import android.media.AudioManager;
+import android.net.Uri;
import android.os.Build;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
@@ -58,15 +60,48 @@ public class MediaButtonReceiver extends BroadcastReceiver {
* Time of the last play/pause click. Used to detect double-clicks.
*/
private static long sLastClickTime = 0;
+ /**
+ * Whether a beep should be played in response to double clicks be used.
+ * 1 for yes, 0 for no, -1 for uninitialized.
+ */
+ private static int sBeep = -1;
+ /**
+ * Lazy-loaded AsyncPlayer for beep sounds.
+ */
+ private static AsyncPlayer sBeepPlayer;
+ /**
+ * Lazy-loaded URI of the beep resource.
+ */
+ private static Uri sBeepSound;
/**
- * Reload the preference and enable/disable buttons as appropriate.
+ * Play a beep sound.
+ */
+ private static void beep(Context context)
+ {
+ if (sBeep == -1) {
+ SharedPreferences settings = PlaybackService.getSettings(context);
+ sBeep = settings.getBoolean(PrefKeys.MEDIA_BUTTON_BEEP, true) ? 1 : 0;
+ }
+
+ if (sBeep == 1) {
+ if (sBeepPlayer == null) {
+ sBeepPlayer = new AsyncPlayer("BeepPlayer");
+ sBeepSound = Uri.parse("android.resource://org.kreed.vanilla/raw/beep");
+ }
+ sBeepPlayer.play(context, sBeepSound, false, AudioManager.STREAM_MUSIC);
+ }
+ }
+
+ /**
+ * Reload the preferences and enable/disable buttons as appropriate.
*
* @param context A context to use.
*/
public static void reloadPreference(Context context)
{
sUseControls = -1;
+ sBeep = -1;
if (useHeadsetControls(context)) {
registerMediaButton(context);
} else {
@@ -138,10 +173,12 @@ public class MediaButtonReceiver extends BroadcastReceiver {
if (action == KeyEvent.ACTION_DOWN) {
long time = SystemClock.uptimeMillis();
- if (time - sLastClickTime < DOUBLE_CLICK_DELAY)
+ if (time - sLastClickTime < DOUBLE_CLICK_DELAY) {
+ beep(context);
act = PlaybackService.ACTION_NEXT_SONG_AUTOPLAY;
- else
+ } else {
act = PlaybackService.ACTION_TOGGLE_PLAYBACK;
+ }
sLastClickTime = time;
}
break;
diff --git a/src/org/kreed/vanilla/PlaybackService.java b/src/org/kreed/vanilla/PlaybackService.java
index 79d95a62..d297cda9 100644
--- a/src/org/kreed/vanilla/PlaybackService.java
+++ b/src/org/kreed/vanilla/PlaybackService.java
@@ -635,7 +635,7 @@ public final class PlaybackService extends Service
} else if (PrefKeys.VOLUME.equals(key)) {
mUserVolume = (float)Math.pow(settings.getInt(key, 100) / 100.0, 3);
updateVolume();
- } else if (PrefKeys.MEDIA_BUTTON.equals(key)) {
+ } else if (PrefKeys.MEDIA_BUTTON.equals(key) || PrefKeys.MEDIA_BUTTON_BEEP.equals(key)) {
MediaButtonReceiver.reloadPreference(this);
} else if (PrefKeys.USE_IDLE_TIMEOUT.equals(key) || PrefKeys.IDLE_TIMEOUT.equals(key)) {
mIdleTimeout = settings.getBoolean(PrefKeys.USE_IDLE_TIMEOUT, false) ? settings.getInt(PrefKeys.IDLE_TIMEOUT, 3600) : 0;
diff --git a/src/org/kreed/vanilla/PrefKeys.java b/src/org/kreed/vanilla/PrefKeys.java
index 08817c01..333e1147 100644
--- a/src/org/kreed/vanilla/PrefKeys.java
+++ b/src/org/kreed/vanilla/PrefKeys.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2012 Christopher Eby
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package org.kreed.vanilla;
@@ -21,6 +42,7 @@ public class PrefKeys {
public static final String IDLE_TIMEOUT = "idle_timeout";
public static final String LIBRARY_PAGE = "library_page";
public static final String MEDIA_BUTTON = "media_button";
+ public static final String MEDIA_BUTTON_BEEP = "media_button_beep";
public static final String NOTIFICATION_ACTION = "notification_action";
public static final String NOTIFICATION_INVERTED_COLOR = "notification_inverted_color";
public static final String NOTIFICATION_MODE = "notification_mode";