Allow remapping hardware buttons (#4881)
This commit is contained in:
parent
4ff6ff4fb7
commit
1297a16850
|
@ -2,6 +2,7 @@ package de.danoeh.antennapod.preferences;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.view.KeyEvent;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
import de.danoeh.antennapod.BuildConfig;
|
import de.danoeh.antennapod.BuildConfig;
|
||||||
|
@ -92,5 +93,16 @@ public class PreferenceUpgrader {
|
||||||
if (oldVersion < 1080100) {
|
if (oldVersion < 1080100) {
|
||||||
prefs.edit().putString(UserPreferences.PREF_VIDEO_BEHAVIOR, "pip").apply();
|
prefs.edit().putString(UserPreferences.PREF_VIDEO_BEHAVIOR, "pip").apply();
|
||||||
}
|
}
|
||||||
|
if (oldVersion < 2010300) {
|
||||||
|
// Migrate hardware button preferences
|
||||||
|
if (prefs.getBoolean("prefHardwareForwardButtonSkips", false)) {
|
||||||
|
prefs.edit().putString(UserPreferences.PREF_HARDWARE_FORWARD_BUTTON,
|
||||||
|
String.valueOf(KeyEvent.KEYCODE_MEDIA_NEXT)).apply();
|
||||||
|
}
|
||||||
|
if (prefs.getBoolean("prefHardwarePreviousButtonRestarts", false)) {
|
||||||
|
prefs.edit().putString(UserPreferences.PREF_HARDWARE_PREVIOUS_BUTTON,
|
||||||
|
String.valueOf(KeyEvent.KEYCODE_MEDIA_PREVIOUS)).apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,18 +44,6 @@
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/playback_control">
|
<PreferenceCategory android:title="@string/playback_control">
|
||||||
<SwitchPreferenceCompat
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:enabled="true"
|
|
||||||
android:key="prefHardwareForwardButtonSkips"
|
|
||||||
android:summary="@string/pref_hardwareForwardButtonSkips_sum"
|
|
||||||
android:title="@string/pref_hardwareForwardButtonSkips_title"/>
|
|
||||||
<SwitchPreferenceCompat
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:enabled="true"
|
|
||||||
android:key="prefHardwarePreviousButtonRestarts"
|
|
||||||
android:summary="@string/pref_hardwarePreviousButtonRestarts_sum"
|
|
||||||
android:title="@string/pref_hardwarePreviousButtonRestarts_title"/>
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="prefPlaybackFastForwardDeltaLauncher"
|
android:key="prefPlaybackFastForwardDeltaLauncher"
|
||||||
android:summary="@string/pref_fast_forward_sum"
|
android:summary="@string/pref_fast_forward_sum"
|
||||||
|
@ -80,6 +68,23 @@
|
||||||
android:title="@string/pref_stream_over_download_title"/>
|
android:title="@string/pref_stream_over_download_title"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="@string/reassign_hardware_buttons">
|
||||||
|
<ListPreference
|
||||||
|
android:defaultValue="@string/keycode_media_fast_forward"
|
||||||
|
android:entries="@array/button_action_options"
|
||||||
|
android:entryValues="@array/button_action_values"
|
||||||
|
android:key="prefHardwareForwardButton"
|
||||||
|
android:title="@string/pref_hardware_forward_button_title"
|
||||||
|
android:summary="@string/pref_hardware_forward_button_summary"/>
|
||||||
|
<ListPreference
|
||||||
|
android:defaultValue="@string/keycode_media_rewind"
|
||||||
|
android:entries="@array/button_action_options"
|
||||||
|
android:entryValues="@array/button_action_values"
|
||||||
|
android:key="prefHardwarePreviousButton"
|
||||||
|
android:title="@string/pref_hardware_previous_button_title"
|
||||||
|
android:summary="@string/pref_hardware_previous_button_summary"/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/queue_label">
|
<PreferenceCategory android:title="@string/queue_label">
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.content.res.Configuration;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -76,8 +77,8 @@ public class UserPreferences {
|
||||||
public static final String PREF_PAUSE_ON_HEADSET_DISCONNECT = "prefPauseOnHeadsetDisconnect";
|
public static final String PREF_PAUSE_ON_HEADSET_DISCONNECT = "prefPauseOnHeadsetDisconnect";
|
||||||
public static final String PREF_UNPAUSE_ON_HEADSET_RECONNECT = "prefUnpauseOnHeadsetReconnect";
|
public static final String PREF_UNPAUSE_ON_HEADSET_RECONNECT = "prefUnpauseOnHeadsetReconnect";
|
||||||
private static final String PREF_UNPAUSE_ON_BLUETOOTH_RECONNECT = "prefUnpauseOnBluetoothReconnect";
|
private static final String PREF_UNPAUSE_ON_BLUETOOTH_RECONNECT = "prefUnpauseOnBluetoothReconnect";
|
||||||
private static final String PREF_HARDWARE_FOWARD_BUTTON_SKIPS = "prefHardwareForwardButtonSkips";
|
public static final String PREF_HARDWARE_FORWARD_BUTTON = "prefHardwareForwardButton";
|
||||||
private static final String PREF_HARDWARE_PREVIOUS_BUTTON_RESTARTS = "prefHardwarePreviousButtonRestarts";
|
public static final String PREF_HARDWARE_PREVIOUS_BUTTON = "prefHardwarePreviousButton";
|
||||||
public static final String PREF_FOLLOW_QUEUE = "prefFollowQueue";
|
public static final String PREF_FOLLOW_QUEUE = "prefFollowQueue";
|
||||||
public static final String PREF_SKIP_KEEPS_EPISODE = "prefSkipKeepsEpisode";
|
public static final String PREF_SKIP_KEEPS_EPISODE = "prefSkipKeepsEpisode";
|
||||||
private static final String PREF_FAVORITE_KEEPS_EPISODE = "prefFavoriteKeepsEpisode";
|
private static final String PREF_FAVORITE_KEEPS_EPISODE = "prefFavoriteKeepsEpisode";
|
||||||
|
@ -373,12 +374,14 @@ public class UserPreferences {
|
||||||
return prefs.getBoolean(PREF_UNPAUSE_ON_BLUETOOTH_RECONNECT, false);
|
return prefs.getBoolean(PREF_UNPAUSE_ON_BLUETOOTH_RECONNECT, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean shouldHardwareButtonSkip() {
|
public static int getHardwareForwardButton() {
|
||||||
return prefs.getBoolean(PREF_HARDWARE_FOWARD_BUTTON_SKIPS, false);
|
return Integer.parseInt(prefs.getString(PREF_HARDWARE_FORWARD_BUTTON,
|
||||||
|
String.valueOf(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean shouldHardwarePreviousButtonRestart() {
|
public static int getHardwarePreviousButton() {
|
||||||
return prefs.getBoolean(PREF_HARDWARE_PREVIOUS_BUTTON_RESTARTS, false);
|
return Integer.parseInt(prefs.getString(PREF_HARDWARE_PREVIOUS_BUTTON,
|
||||||
|
String.valueOf(KeyEvent.KEYCODE_MEDIA_REWIND)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -668,18 +668,14 @@ public class PlaybackService extends MediaBrowserServiceCompat {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case KeyEvent.KEYCODE_MEDIA_NEXT:
|
case KeyEvent.KEYCODE_MEDIA_NEXT:
|
||||||
if (getStatus() != PlayerStatus.PLAYING && getStatus() != PlayerStatus.PAUSED) {
|
if (!notificationButton) {
|
||||||
return false;
|
// Handle remapped button as notification button which is not remapped again.
|
||||||
} else if (notificationButton || UserPreferences.shouldHardwareButtonSkip()) {
|
return handleKeycode(UserPreferences.getHardwareForwardButton(), true);
|
||||||
// assume the skip command comes from a notification or the lockscreen
|
} else if (getStatus() == PlayerStatus.PLAYING || getStatus() == PlayerStatus.PAUSED) {
|
||||||
// a >| skip button should actually skip
|
|
||||||
mediaPlayer.skip();
|
mediaPlayer.skip();
|
||||||
} else {
|
|
||||||
// assume skip command comes from a (bluetooth) media button
|
|
||||||
// user actually wants to fast-forward
|
|
||||||
seekDelta(UserPreferences.getFastForwardSecs() * 1000);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
|
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
|
||||||
if (getStatus() == PlayerStatus.PLAYING || getStatus() == PlayerStatus.PAUSED) {
|
if (getStatus() == PlayerStatus.PLAYING || getStatus() == PlayerStatus.PAUSED) {
|
||||||
mediaPlayer.seekDelta(UserPreferences.getFastForwardSecs() * 1000);
|
mediaPlayer.seekDelta(UserPreferences.getFastForwardSecs() * 1000);
|
||||||
|
@ -687,23 +683,20 @@ public class PlaybackService extends MediaBrowserServiceCompat {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
|
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
|
||||||
if (getStatus() != PlayerStatus.PLAYING && getStatus() != PlayerStatus.PAUSED) {
|
if (!notificationButton) {
|
||||||
return false;
|
// Handle remapped button as notification button which is not remapped again.
|
||||||
} else if (UserPreferences.shouldHardwarePreviousButtonRestart()) {
|
return handleKeycode(UserPreferences.getHardwarePreviousButton(), true);
|
||||||
// user wants to restart current episode
|
} else if (getStatus() == PlayerStatus.PLAYING || getStatus() == PlayerStatus.PAUSED) {
|
||||||
mediaPlayer.seekTo(0);
|
mediaPlayer.seekTo(0);
|
||||||
} else {
|
|
||||||
// user wants to rewind current episode
|
|
||||||
mediaPlayer.seekDelta(-UserPreferences.getRewindSecs() * 1000);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
case KeyEvent.KEYCODE_MEDIA_REWIND:
|
case KeyEvent.KEYCODE_MEDIA_REWIND:
|
||||||
if (getStatus() == PlayerStatus.PLAYING || getStatus() == PlayerStatus.PAUSED) {
|
if (getStatus() == PlayerStatus.PLAYING || getStatus() == PlayerStatus.PAUSED) {
|
||||||
mediaPlayer.seekDelta(-UserPreferences.getRewindSecs() * 1000);
|
mediaPlayer.seekDelta(-UserPreferences.getRewindSecs() * 1000);
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
case KeyEvent.KEYCODE_MEDIA_STOP:
|
case KeyEvent.KEYCODE_MEDIA_STOP:
|
||||||
if (status == PlayerStatus.PLAYING) {
|
if (status == PlayerStatus.PLAYING) {
|
||||||
mediaPlayer.pause(true, true);
|
mediaPlayer.pause(true, true);
|
||||||
|
@ -1911,7 +1904,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
|
||||||
Log.d(TAG, "onSkipToNext()");
|
Log.d(TAG, "onSkipToNext()");
|
||||||
UiModeManager uiModeManager = (UiModeManager) getApplicationContext()
|
UiModeManager uiModeManager = (UiModeManager) getApplicationContext()
|
||||||
.getSystemService(Context.UI_MODE_SERVICE);
|
.getSystemService(Context.UI_MODE_SERVICE);
|
||||||
if (UserPreferences.shouldHardwareButtonSkip()
|
if (UserPreferences.getHardwareForwardButton() == KeyEvent.KEYCODE_MEDIA_NEXT
|
||||||
|| uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
|
|| uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
|
||||||
mediaPlayer.skip();
|
mediaPlayer.skip();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -105,6 +105,20 @@
|
||||||
<item>@string/episode_cleanup_never</item>
|
<item>@string/episode_cleanup_never</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="button_action_options">
|
||||||
|
<item>@string/button_action_fast_forward</item>
|
||||||
|
<item>@string/button_action_rewind</item>
|
||||||
|
<item>@string/button_action_skip_episode</item>
|
||||||
|
<item>@string/button_action_restart_episode</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="button_action_values">
|
||||||
|
<item>@string/keycode_media_fast_forward</item>
|
||||||
|
<item>@string/keycode_media_rewind</item>
|
||||||
|
<item>@string/keycode_media_next</item>
|
||||||
|
<item>@string/keycode_media_previous</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="enqueue_location_options">
|
<string-array name="enqueue_location_options">
|
||||||
<item>@string/enqueue_location_back</item>
|
<item>@string/enqueue_location_back</item>
|
||||||
<item>@string/enqueue_location_front</item>
|
<item>@string/enqueue_location_front</item>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<resources
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:ignore="MissingTranslation">
|
||||||
|
|
||||||
|
<string name="keycode_media_next">87</string>
|
||||||
|
<string name="keycode_media_previous">88</string>
|
||||||
|
<string name="keycode_media_rewind">89</string>
|
||||||
|
<string name="keycode_media_fast_forward">90</string>
|
||||||
|
</resources>
|
|
@ -381,6 +381,7 @@
|
||||||
<string name="external_elements">External elements</string>
|
<string name="external_elements">External elements</string>
|
||||||
<string name="interruptions">Interruptions</string>
|
<string name="interruptions">Interruptions</string>
|
||||||
<string name="playback_control">Playback control</string>
|
<string name="playback_control">Playback control</string>
|
||||||
|
<string name="reassign_hardware_buttons">Reassign hardware buttons</string>
|
||||||
<string name="preference_search_hint">Search…</string>
|
<string name="preference_search_hint">Search…</string>
|
||||||
<string name="preference_search_no_results">No results</string>
|
<string name="preference_search_no_results">No results</string>
|
||||||
<string name="preference_search_clear_history">Clear history</string>
|
<string name="preference_search_clear_history">Clear history</string>
|
||||||
|
@ -390,10 +391,14 @@
|
||||||
<string name="pref_pauseOnDisconnect_sum">Pause playback when headphones or bluetooth are disconnected</string>
|
<string name="pref_pauseOnDisconnect_sum">Pause playback when headphones or bluetooth are disconnected</string>
|
||||||
<string name="pref_unpauseOnHeadsetReconnect_sum">Resume playback when the headphones are reconnected</string>
|
<string name="pref_unpauseOnHeadsetReconnect_sum">Resume playback when the headphones are reconnected</string>
|
||||||
<string name="pref_unpauseOnBluetoothReconnect_sum">Resume playback when bluetooth reconnects</string>
|
<string name="pref_unpauseOnBluetoothReconnect_sum">Resume playback when bluetooth reconnects</string>
|
||||||
<string name="pref_hardwareForwardButtonSkips_title">Forward Button Skips</string>
|
<string name="pref_hardware_forward_button_title">Forward Button</string>
|
||||||
<string name="pref_hardwareForwardButtonSkips_sum">When pressing a forward button on a bluetooth-connected device skip to the next episode instead of fast-forwarding</string>
|
<string name="pref_hardware_forward_button_summary">Customize the forward button behavior</string>
|
||||||
<string name="pref_hardwarePreviousButtonRestarts_title">Previous button restarts</string>
|
<string name="pref_hardware_previous_button_title">Previous Button</string>
|
||||||
<string name="pref_hardwarePreviousButtonRestarts_sum">When pressing a hardware previous button restart playing the current episode instead of rewinding</string>
|
<string name="pref_hardware_previous_button_summary">Customize the previous button behavior</string>
|
||||||
|
<string name="button_action_fast_forward">Fast Forward</string>
|
||||||
|
<string name="button_action_rewind">Rewind</string>
|
||||||
|
<string name="button_action_skip_episode">Skip Episode</string>
|
||||||
|
<string name="button_action_restart_episode">Restart Episode</string>
|
||||||
<string name="pref_followQueue_sum">Jump to next queue item when playback completes</string>
|
<string name="pref_followQueue_sum">Jump to next queue item when playback completes</string>
|
||||||
<string name="pref_auto_delete_sum">Delete episode when playback completes</string>
|
<string name="pref_auto_delete_sum">Delete episode when playback completes</string>
|
||||||
<string name="pref_auto_delete_title">Auto Delete</string>
|
<string name="pref_auto_delete_title">Auto Delete</string>
|
||||||
|
|
Loading…
Reference in New Issue