Add audio settings

Add some settings to control how audio is being played.
This commit is contained in:
OxygenCobalt 2020-12-05 09:42:09 -07:00
parent 276c099f84
commit c44003907a
7 changed files with 117 additions and 35 deletions

View file

@ -63,6 +63,10 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
private lateinit var mediaSession: MediaSessionCompat
private lateinit var systemReceiver: SystemEventReceiver
private val audioAttributes = AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MUSIC)
.build()
private lateinit var notificationManager: NotificationManager
private lateinit var notification: NotificationCompat.Builder
@ -95,11 +99,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
// Set up AudioFocus/AudioAttributes
player.setAudioAttributes(
AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MUSIC)
.build(),
true
audioAttributes, settingsManager.doAudioFocus
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@ -323,6 +323,13 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
startForegroundOrNotify("Notif action update")
}
override fun onAudioFocusUpdate(doAudioFocus: Boolean) {
player.setAudioAttributes(
audioAttributes,
doAudioFocus
)
}
// --- OTHER FUNCTIONS ---
private fun restorePlayer() {
@ -392,8 +399,9 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
}
private fun startForegroundOrNotify(reason: String) {
// Start the service in the foreground if haven't already.
if (playbackManager.hasPlayed) {
// Don't start the foreground if the playback hasn't started yet AND if the playback hasn't
// been restored
if (playbackManager.hasPlayed && playbackManager.isRestored) {
Log.d(this::class.simpleName, "Starting foreground/notifying because of $reason")
if (!isForeground) {
@ -501,7 +509,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
}
private fun resume() {
if (playbackManager.song != null) {
if (playbackManager.song != null && settingsManager.doPlugMgt) {
Log.d(this::class.simpleName, "Device connected, resuming...")
playbackManager.setPlayingStatus(true)
@ -509,7 +517,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
}
private fun pause() {
if (playbackManager.song != null) {
if (playbackManager.song != null && settingsManager.doPlugMgt) {
Log.d(this::class.simpleName, "Device disconnected, pausing...")
playbackManager.setPlayingStatus(false)

View file

@ -22,9 +22,7 @@ class SettingsManager private constructor(context: Context) :
// --- VALUES ---
val theme: Int
get() {
return sharedPrefs.getString(Keys.KEY_THEME, EntryNames.THEME_AUTO)!!.toThemeInt()
}
get() = sharedPrefs.getString(Keys.KEY_THEME, EntryNames.THEME_AUTO)!!.toThemeInt()
var accent: Pair<Int, Int>
get() {
@ -44,19 +42,13 @@ class SettingsManager private constructor(context: Context) :
}
val edgeEnabled: Boolean
get() {
return sharedPrefs.getBoolean(Keys.KEY_EDGE_TO_EDGE, false)
}
get() = sharedPrefs.getBoolean(Keys.KEY_EDGE_TO_EDGE, false)
val colorizeNotif: Boolean
get() {
return sharedPrefs.getBoolean(Keys.KEY_COLORIZE_NOTIFICATION, true)
}
get() = sharedPrefs.getBoolean(Keys.KEY_COLORIZE_NOTIFICATION, true)
val useAltNotifAction: Boolean
get() {
return sharedPrefs.getBoolean(Keys.KEY_USE_ALT_NOTIFICATION_ACTION, false)
}
get() = sharedPrefs.getBoolean(Keys.KEY_USE_ALT_NOTIFICATION_ACTION, false)
val libraryDisplayMode: DisplayMode
get() {
@ -68,6 +60,12 @@ class SettingsManager private constructor(context: Context) :
)
}
val doAudioFocus: Boolean
get() = sharedPrefs.getBoolean(Keys.KEY_AUDIO_FOCUS, true)
val doPlugMgt: Boolean
get() = sharedPrefs.getBoolean(Keys.KEY_PLUG_MANAGEMENT, true)
var librarySortMode: SortMode
get() {
return SortMode.fromInt(
@ -110,6 +108,10 @@ class SettingsManager private constructor(context: Context) :
Keys.KEY_LIBRARY_DISPLAY_MODE -> callbacks.forEach {
it.onLibDisplayModeUpdate(libraryDisplayMode)
}
Keys.KEY_AUDIO_FOCUS -> callbacks.forEach {
it.onAudioFocusUpdate(doAudioFocus)
}
}
}
@ -149,6 +151,9 @@ class SettingsManager private constructor(context: Context) :
const val KEY_COLORIZE_NOTIFICATION = "KEY_COLOR_NOTIF"
const val KEY_USE_ALT_NOTIFICATION_ACTION = "KEY_ALT_NOTIF_ACTION"
const val KEY_LIBRARY_DISPLAY_MODE = "KEY_LIBRARY_DISPLAY_MODE"
const val KEY_AUDIO_FOCUS = "KEY_AUDIO_FOCUS"
const val KEY_PLUG_MANAGEMENT = "KEY_PLUG_MGT"
const val KEY_LIBRARY_SORT_MODE = "KEY_LIBRARY_SORT_MODE"
}
@ -158,9 +163,15 @@ class SettingsManager private constructor(context: Context) :
const val THEME_DARK = "DARK"
}
/**
* An safe interface for receiving some preference updates. Use this instead of
* [SharedPreferences.OnSharedPreferenceChangeListener] if possible, as it doesn't require a
* context.
*/
interface Callback {
fun onColorizeNotifUpdate(doColorize: Boolean) {}
fun onNotifActionUpdate(useAltAction: Boolean) {}
fun onLibDisplayModeUpdate(displayMode: DisplayMode) {}
fun onAudioFocusUpdate(doAudioFocus: Boolean) {}
}
}

View file

@ -73,7 +73,7 @@ fun Spanned.render(): Spanned {
}
/**
* Handle the new transparent system bars on light mode. Adapted from Music Player GO
* Handle transparent system bars. Adapted from Music Player GO
* (https://github.com/enricocid/Music-Player-GO)
*/
@TargetApi(Build.VERSION_CODES.O_MR1)

View file

@ -1,7 +1,9 @@
package org.oxycblt.auxio.ui
import android.content.Context
import android.content.res.Resources
import android.text.Spanned
import android.util.Log
import android.util.TypedValue
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
@ -14,7 +16,9 @@ import java.util.Locale
// Functions for managing colors/accents.
// Pairs of the base accent and its theme
/**
* An array of the base accents and their respective themes.
*/
val ACCENTS = arrayOf(
Pair(R.color.red, R.style.Theme_Red), // 0
Pair(R.color.pink, R.style.Theme_Pink), // 1
@ -37,8 +41,10 @@ val ACCENTS = arrayOf(
Pair(R.color.blue_grey, R.style.Theme_BlueGrey) // 18
)
// The names for each colors. These are translatable, so make sure to use these instead of getting
// the color name directly.
/**
* An array of strings for each accent, use these instead of [Resources.getResourceName] so that
* the accent names are translated.
*/
private val ACCENT_NAMES = arrayOf(
R.string.color_label_red, R.string.color_label_pink,
R.string.color_label_purple, R.string.color_label_deep_purple,
@ -52,6 +58,9 @@ private val ACCENT_NAMES = arrayOf(
R.string.color_label_blue_grey
)
/**
* The programmatically accessible accent, reflects the currently set accent.
*/
lateinit var accent: Pair<Int, Int>
/**
@ -86,7 +95,9 @@ fun getInactiveAlpha(@ColorRes color: Int): Int {
fun Int.toColor(context: Context): Int {
return try {
ContextCompat.getColor(context, this)
} catch (e: Exception) {
} catch (e: Resources.NotFoundException) {
Log.e(this::class.simpleName, "Attempted color load failed.")
// Default to the emergency color [Black] if the loading fails.
ContextCompat.getColor(context, android.R.color.black)
}
@ -127,7 +138,7 @@ fun getAccentItemSummary(context: Context, newAccent: Pair<Int, Int>): String {
}
/**
* Get the name [in bold]] and the hex value of a theme.
* Get the name (in bold) and the hex value of a theme.
*/
fun getDetailedAccentSummary(context: Context, newAccent: Pair<Int, Int>): Spanned {
val name = getAccentItemSummary(context, newAccent)

View file

@ -43,6 +43,7 @@
<string name="setting_theme_day">Light</string>
<string name="setting_theme_night">Dark</string>
<string name="setting_accent">Accent</string>
<string name="setting_accent_unknown">Unknown Accent</string>
<string name="setting_edge">Edge-To-Edge</string>
<string name="setting_edge_desc_on">Edge-to-edge is enabled</string>
<string name="setting_edge_desc_off">Edge-to-edge is disabled</string>
@ -54,6 +55,13 @@
<string name="setting_use_alt_action">Use alternate notification action</string>
<string name="setting_use_alt_loop">Prefer repeat mode action</string>
<string name="setting_use_alt_shuffle">Prefer shuffle action</string>
<string name="setting_playback">Audio</string>
<string name="setting_playback_audio_focus">Audio focus</string>
<string name="setting_playback_focus_desc_on">Audio focus is enabled</string>
<string name="setting_playback_focus_desc_off">Audio focus is disabled</string>
<string name="setting_playback_plug_mgt">Headset plug management</string>
<string name="setting_playback_plug_mgt_desc_on">Headset plug management is enabled</string>
<string name="setting_playback_plug_mgt_desc_off">Headset plug management is disabled</string>
<!-- Debug Namespace | Debug labels -->
<string name="debug_state_saved">State saved</string>
@ -98,7 +106,7 @@
<string name="color_label_deep_purple">Deep Purple</string>
<string name="color_label_indigo">Indigo</string>
<string name="color_label_blue">Blue</string>
<string name="color_label_light_blue">Light blue</string>
<string name="color_label_light_blue">Light Blue</string>
<string name="color_label_cyan">Cyan</string>
<string name="color_label_teal">Teal</string>
<string name="color_label_green">Green</string>

View file

@ -17,7 +17,7 @@
app:key="KEY_ACCENT"
android:title="@string/setting_accent"
android:icon="@drawable/ic_accent"
app:summary="@string/setting_accent" />
app:summary="@string/setting_accent_unknown" />
<SwitchPreferenceCompat
app:key="KEY_EDGE"
@ -26,7 +26,7 @@
app:summaryOff="@string/setting_edge_desc_off"
app:iconSpaceReserved="false"
app:allowDividerBelow="false"
android:defaultValue="false" />
app:defaultValue="false" />
</PreferenceCategory>
<PreferenceCategory
@ -48,7 +48,7 @@
app:summaryOn="@string/setting_color_desc_on"
app:summaryOff="@string/setting_color_desc_off"
app:iconSpaceReserved="false"
android:defaultValue="true" />
app:defaultValue="true" />
<SwitchPreferenceCompat
app:key="KEY_ALT_NOTIF_ACTION"
@ -56,7 +56,29 @@
app:iconSpaceReserved="false"
app:summaryOn="@string/setting_use_alt_shuffle"
app:summaryOff="@string/setting_use_alt_loop"
android:defaultValue="false" />
app:allowDividerBelow="false"
app:defaultValue="false" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/setting_playback"
android:layout="@layout/item_header">
<SwitchPreferenceCompat
app:key="KEY_AUDIO_FOCUS"
android:title="@string/setting_playback_audio_focus"
app:iconSpaceReserved="false"
app:defaultValue="true"
app:summaryOn="@string/setting_playback_focus_desc_on"
app:summaryOff="@string/setting_playback_focus_desc_off" />
<SwitchPreferenceCompat
app:key="KEY_PLUG_MGT"
android:title="@string/setting_playback_plug_mgt"
app:iconSpaceReserved="false"
app:defaultValue="true"
app:summaryOn="@string/setting_playback_plug_mgt_desc_on"
app:summaryOff="@string/setting_playback_plug_mgt_desc_off" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -17,7 +17,7 @@
app:key="KEY_ACCENT"
android:title="@string/setting_accent"
android:icon="@drawable/ic_accent"
app:summary="@string/setting_accent" />
app:summary="@string/setting_accent_unknown" />
</PreferenceCategory>
<PreferenceCategory
@ -39,7 +39,7 @@
app:summaryOn="@string/setting_color_desc_on"
app:summaryOff="@string/setting_color_desc_off"
app:iconSpaceReserved="false"
android:defaultValue="true" />
app:defaultValue="true" />
<SwitchPreferenceCompat
app:key="KEY_ALT_NOTIF_ACTION"
@ -47,7 +47,29 @@
app:iconSpaceReserved="false"
app:summaryOn="@string/setting_use_alt_shuffle"
app:summaryOff="@string/setting_use_alt_loop"
android:defaultValue="false" />
app:allowDividerBelow="false"
app:defaultValue="false" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/setting_playback"
android:layout="@layout/item_header">
<SwitchPreferenceCompat
app:key="KEY_AUDIO_FOCUS"
android:title="@string/setting_playback_audio_focus"
app:iconSpaceReserved="false"
app:defaultValue="true"
app:summaryOn="@string/setting_playback_focus_desc_on"
app:summaryOff="@string/setting_playback_focus_desc_off" />
<SwitchPreferenceCompat
app:key="KEY_PLUG_MGT"
android:title="@string/setting_playback_plug_mgt"
app:iconSpaceReserved="false"
app:defaultValue="true"
app:summaryOn="@string/setting_playback_plug_mgt_desc_on"
app:summaryOff="@string/setting_playback_plug_mgt_desc_off" />
</PreferenceCategory>
</PreferenceScreen>