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";