playback: replace headset focus with headset autoplay
Turn the headset focus setting into the headset autoplay setting. The way auxio handles headsets is...odd. Sometimes the MediaSession handles it and Auxio could not care less, and sometimes Auxio actually needs to handle it. As a result, the idea of being able to disable headset focus is more or less moot because it will only apply to some devices and not others. On the other end, the way Auxio automatically begins playback once a headset is plugged in is also quite weird. It only works on wired headsets, and when it does, it overrides all other apps that might also be playing audio. It's not to say that it's a bad feature, but it's also one that I don't want to make the defualt. Auxio should still play along within the confines of Android's expectations, after all. Replacing the existing "Headset focus" setting with a new "Headset autoplay" setting solves both of these issues, as it prevents a mis-guided disabling of the setting that doesn't actually disable the feature and it relegates the quirky autoplay behavior to an setting not enabled by default.
This commit is contained in:
parent
6d003c308b
commit
1b791074ec
29 changed files with 140 additions and 166 deletions
|
@ -19,6 +19,7 @@ from the system theme was used [#80]
|
||||||
|
|
||||||
#### What's Changed
|
#### What's Changed
|
||||||
- All cover art is now cropped to a 1:1 aspect ratio
|
- All cover art is now cropped to a 1:1 aspect ratio
|
||||||
|
- Headset focus has been replaced with headset autoplay. It can no longer be disabled.
|
||||||
|
|
||||||
#### Dev/Meta
|
#### Dev/Meta
|
||||||
- Enabled elevation drop shadows below Android P for consistency
|
- Enabled elevation drop shadows below Android P for consistency
|
||||||
|
|
|
@ -103,7 +103,7 @@ dependencies {
|
||||||
implementation 'io.coil-kt:coil:2.0.0-alpha09'
|
implementation 'io.coil-kt:coil:2.0.0-alpha09'
|
||||||
|
|
||||||
// Material
|
// Material
|
||||||
implementation 'com.google.android.material:material:1.6.0-alpha02'
|
implementation 'com.google.android.material:material:1.6.0-alpha03'
|
||||||
|
|
||||||
// --- DEBUG ---
|
// --- DEBUG ---
|
||||||
|
|
||||||
|
@ -115,7 +115,6 @@ task ktlint(type: JavaExec, group: "verification") {
|
||||||
description = "Check Kotlin code style."
|
description = "Check Kotlin code style."
|
||||||
mainClass.set("com.pinterest.ktlint.Main")
|
mainClass.set("com.pinterest.ktlint.Main")
|
||||||
classpath = configurations.ktlint
|
classpath = configurations.ktlint
|
||||||
|
|
||||||
args "src/**/*.kt"
|
args "src/**/*.kt"
|
||||||
}
|
}
|
||||||
check.dependsOn ktlint
|
check.dependsOn ktlint
|
||||||
|
@ -124,6 +123,5 @@ task ktlintFormat(type: JavaExec, group: "formatting") {
|
||||||
description = "Fix Kotlin code style deviations."
|
description = "Fix Kotlin code style deviations."
|
||||||
mainClass.set("com.pinterest.ktlint.Main")
|
mainClass.set("com.pinterest.ktlint.Main")
|
||||||
classpath = configurations.ktlint
|
classpath = configurations.ktlint
|
||||||
|
|
||||||
args "-F", "src/**/*.kt"
|
args "-F", "src/**/*.kt"
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.Navigation.findNavController
|
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
|
|
|
@ -51,6 +51,7 @@ class PlaybackNotification private constructor(
|
||||||
setCategory(NotificationCompat.CATEGORY_SERVICE)
|
setCategory(NotificationCompat.CATEGORY_SERVICE)
|
||||||
setShowWhen(false)
|
setShowWhen(false)
|
||||||
setSilent(true)
|
setSilent(true)
|
||||||
|
setBadgeIconType(NotificationCompat.BADGE_ICON_NONE)
|
||||||
setContentIntent(context.newMainIntent())
|
setContentIntent(context.newMainIntent())
|
||||||
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
|
|
||||||
|
|
|
@ -444,34 +444,38 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [BroadcastReceiver] for receiving general playback events from the system.
|
* A [BroadcastReceiver] for receiving general playback events from the system.
|
||||||
* TODO: Don't fire when the service initially starts?
|
|
||||||
*/
|
*/
|
||||||
private inner class PlaybackReceiver : BroadcastReceiver() {
|
private inner class PlaybackReceiver : BroadcastReceiver() {
|
||||||
private var handledInitialHeadsetPlug = false
|
private var initialHeadsetPlugEventHandled = false
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
when (intent.action) {
|
when (intent.action) {
|
||||||
// --- SYSTEM EVENTS ---
|
// --- SYSTEM EVENTS ---
|
||||||
|
|
||||||
|
// Technically the MediaSession seems to handle bluetooth events on their
|
||||||
|
// own, but keep this around as a fallback in the case that the former fails
|
||||||
|
// for whatever reason.
|
||||||
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED -> {
|
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED -> {
|
||||||
when (intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1)) {
|
when (intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1)) {
|
||||||
AudioManager.SCO_AUDIO_STATE_CONNECTED -> resumeFromPlug()
|
|
||||||
AudioManager.SCO_AUDIO_STATE_DISCONNECTED -> pauseFromPlug()
|
AudioManager.SCO_AUDIO_STATE_DISCONNECTED -> pauseFromPlug()
|
||||||
|
AudioManager.SCO_AUDIO_STATE_CONNECTED -> maybeResumeFromPlug()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioManager.ACTION_AUDIO_BECOMING_NOISY -> pauseFromPlug()
|
// MediaSession does not handle wired headsets for some reason, so also include
|
||||||
|
// this. Gotta love Android having two actions for more or less the same thing.
|
||||||
AudioManager.ACTION_HEADSET_PLUG -> {
|
AudioManager.ACTION_HEADSET_PLUG -> {
|
||||||
if (handledInitialHeadsetPlug) {
|
|
||||||
when (intent.getIntExtra("state", -1)) {
|
when (intent.getIntExtra("state", -1)) {
|
||||||
0 -> pauseFromPlug()
|
0 -> pauseFromPlug()
|
||||||
1 -> resumeFromPlug()
|
1 -> maybeResumeFromPlug()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handledInitialHeadsetPlug = true
|
initialHeadsetPlugEventHandled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I have never seen this ever happen but it might be useful
|
||||||
|
AudioManager.ACTION_AUDIO_BECOMING_NOISY -> pauseFromPlug()
|
||||||
|
|
||||||
// --- AUXIO EVENTS ---
|
// --- AUXIO EVENTS ---
|
||||||
ACTION_PLAY_PAUSE -> playbackManager.setPlaying(
|
ACTION_PLAY_PAUSE -> playbackManager.setPlaying(
|
||||||
!playbackManager.isPlaying
|
!playbackManager.isPlaying
|
||||||
|
@ -496,27 +500,37 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac
|
||||||
WidgetProvider.ACTION_WIDGET_UPDATE -> widgets.update()
|
WidgetProvider.ACTION_WIDGET_UPDATE -> widgets.update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resume from a headset plug event, as long as its allowed.
|
* Resume from a headset plug event in the case that the quirk is enabled.
|
||||||
|
* This functionality remains a quirk for two reasons:
|
||||||
|
* 1. Automatically resuming more or less overrides all other audio streams, which
|
||||||
|
* is not that friendly
|
||||||
|
* 2. There is a bug where playback will always start when this service starts, mostly
|
||||||
|
* due to AudioManager.ACTION_HEADSET_PLUG always firing on startup. This is fixed, but
|
||||||
|
* I fear that it may not work on OEM skins that for whatever reason don't make this
|
||||||
|
* action fire.
|
||||||
*/
|
*/
|
||||||
private fun resumeFromPlug() {
|
private fun maybeResumeFromPlug() {
|
||||||
if (playbackManager.song != null && settingsManager.doPlugMgt) {
|
if (playbackManager.song != null &&
|
||||||
|
settingsManager.headsetAutoplay &&
|
||||||
|
initialHeadsetPlugEventHandled
|
||||||
|
) {
|
||||||
logD("Device connected, resuming")
|
logD("Device connected, resuming")
|
||||||
playbackManager.setPlaying(true)
|
playbackManager.setPlaying(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pause from a headset plug, as long as its allowed.
|
* Pause from a headset plug.
|
||||||
*/
|
*/
|
||||||
private fun pauseFromPlug() {
|
private fun pauseFromPlug() {
|
||||||
if (playbackManager.song != null && settingsManager.doPlugMgt) {
|
if (playbackManager.song != null) {
|
||||||
logD("Device disconnected, pausing")
|
logD("Device disconnected, pausing")
|
||||||
playbackManager.setPlaying(false)
|
playbackManager.setPlaying(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val POS_POLL_INTERVAL = 500L
|
private const val POS_POLL_INTERVAL = 500L
|
||||||
|
|
|
@ -37,27 +37,27 @@ import org.oxycblt.auxio.ui.Sort
|
||||||
class SettingsManager private constructor(context: Context) :
|
class SettingsManager private constructor(context: Context) :
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
private val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context)
|
private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
sharedPrefs.registerOnSharedPreferenceChangeListener(this)
|
prefs.registerOnSharedPreferenceChangeListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- VALUES ---
|
// --- VALUES ---
|
||||||
|
|
||||||
/** The current theme */
|
/** The current theme */
|
||||||
val theme: Int
|
val theme: Int
|
||||||
get() = sharedPrefs.getInt(KEY_THEME, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
get() = prefs.getInt(KEY_THEME, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||||
|
|
||||||
/** Whether the dark theme should be black or not */
|
/** Whether the dark theme should be black or not */
|
||||||
val useBlackTheme: Boolean
|
val useBlackTheme: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_BLACK_THEME, false)
|
get() = prefs.getBoolean(KEY_BLACK_THEME, false)
|
||||||
|
|
||||||
/** The current accent. */
|
/** The current accent. */
|
||||||
var accent: Accent
|
var accent: Accent
|
||||||
get() = handleAccentCompat(sharedPrefs)
|
get() = handleAccentCompat(prefs)
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_ACCENT, value.index)
|
putInt(KEY_ACCENT, value.index)
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -68,14 +68,14 @@ class SettingsManager private constructor(context: Context) :
|
||||||
* False if loop, true if shuffle.
|
* False if loop, true if shuffle.
|
||||||
*/
|
*/
|
||||||
val useAltNotifAction: Boolean
|
val useAltNotifAction: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_USE_ALT_NOTIFICATION_ACTION, false)
|
get() = prefs.getBoolean(KEY_USE_ALT_NOTIFICATION_ACTION, false)
|
||||||
|
|
||||||
/** The current library tabs preferred by the user. */
|
/** The current library tabs preferred by the user. */
|
||||||
var libTabs: Array<Tab>
|
var libTabs: Array<Tab>
|
||||||
get() = Tab.fromSequence(sharedPrefs.getInt(KEY_LIB_TABS, Tab.SEQUENCE_DEFAULT))
|
get() = Tab.fromSequence(prefs.getInt(KEY_LIB_TABS, Tab.SEQUENCE_DEFAULT))
|
||||||
?: Tab.fromSequence(Tab.SEQUENCE_DEFAULT)!!
|
?: Tab.fromSequence(Tab.SEQUENCE_DEFAULT)!!
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_LIB_TABS, Tab.toSequence(value))
|
putInt(KEY_LIB_TABS, Tab.toSequence(value))
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -83,51 +83,51 @@ class SettingsManager private constructor(context: Context) :
|
||||||
|
|
||||||
/** Whether to load embedded covers */
|
/** Whether to load embedded covers */
|
||||||
val showCovers: Boolean
|
val showCovers: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_SHOW_COVERS, true)
|
get() = prefs.getBoolean(KEY_SHOW_COVERS, true)
|
||||||
|
|
||||||
/** Whether to ignore MediaStore covers */
|
/** Whether to ignore MediaStore covers */
|
||||||
val useQualityCovers: Boolean
|
val useQualityCovers: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_QUALITY_COVERS, false)
|
get() = prefs.getBoolean(KEY_QUALITY_COVERS, false)
|
||||||
|
|
||||||
/** Whether to round album covers */
|
/** Whether to round album covers */
|
||||||
val roundCovers: Boolean
|
val roundCovers: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_ROUND_COVERS, false)
|
get() = prefs.getBoolean(KEY_ROUND_COVERS, false)
|
||||||
|
|
||||||
/** Whether to do Audio focus. */
|
/** Whether to do Audio focus. */
|
||||||
val doAudioFocus: Boolean
|
val doAudioFocus: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_AUDIO_FOCUS, true)
|
get() = prefs.getBoolean(KEY_AUDIO_FOCUS, true)
|
||||||
|
|
||||||
/** Whether to resume/stop playback when a headset is connected/disconnected. */
|
/** Whether to resume playback when a headset is connected (may not work well in all cases) */
|
||||||
val doPlugMgt: Boolean
|
val headsetAutoplay: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_PLUG_MANAGEMENT, true)
|
get() = prefs.getBoolean(KEY_HEADSET_AUTOPLAY, false)
|
||||||
|
|
||||||
/** The current ReplayGain configuration */
|
/** The current ReplayGain configuration */
|
||||||
val replayGainMode: ReplayGainMode
|
val replayGainMode: ReplayGainMode
|
||||||
get() = ReplayGainMode.fromInt(sharedPrefs.getInt(KEY_REPLAY_GAIN, Int.MIN_VALUE))
|
get() = ReplayGainMode.fromInt(prefs.getInt(KEY_REPLAY_GAIN, Int.MIN_VALUE))
|
||||||
?: ReplayGainMode.OFF
|
?: ReplayGainMode.OFF
|
||||||
|
|
||||||
/** What queue to create when a song is selected (ex. From All Songs or Search) */
|
/** What queue to create when a song is selected (ex. From All Songs or Search) */
|
||||||
val songPlaybackMode: PlaybackMode
|
val songPlaybackMode: PlaybackMode
|
||||||
get() = PlaybackMode.fromInt(sharedPrefs.getInt(KEY_SONG_PLAYBACK_MODE, Int.MIN_VALUE))
|
get() = PlaybackMode.fromInt(prefs.getInt(KEY_SONG_PLAYBACK_MODE, Int.MIN_VALUE))
|
||||||
?: PlaybackMode.ALL_SONGS
|
?: PlaybackMode.ALL_SONGS
|
||||||
|
|
||||||
/** Whether shuffle should stay on when a new song is selected. */
|
/** Whether shuffle should stay on when a new song is selected. */
|
||||||
val keepShuffle: Boolean
|
val keepShuffle: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_KEEP_SHUFFLE, true)
|
get() = prefs.getBoolean(KEY_KEEP_SHUFFLE, true)
|
||||||
|
|
||||||
/** Whether to rewind when the back button is pressed. */
|
/** Whether to rewind when the back button is pressed. */
|
||||||
val rewindWithPrev: Boolean
|
val rewindWithPrev: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_PREV_REWIND, true)
|
get() = prefs.getBoolean(KEY_PREV_REWIND, true)
|
||||||
|
|
||||||
/** Whether [org.oxycblt.auxio.playback.state.LoopMode.TRACK] should pause when the track repeats */
|
/** Whether [org.oxycblt.auxio.playback.state.LoopMode.TRACK] should pause when the track repeats */
|
||||||
val pauseOnLoop: Boolean
|
val pauseOnLoop: Boolean
|
||||||
get() = sharedPrefs.getBoolean(KEY_LOOP_PAUSE, false)
|
get() = prefs.getBoolean(KEY_LOOP_PAUSE, false)
|
||||||
|
|
||||||
/** The current filter mode of the search tab */
|
/** The current filter mode of the search tab */
|
||||||
var searchFilterMode: DisplayMode?
|
var searchFilterMode: DisplayMode?
|
||||||
get() = DisplayMode.fromFilterInt(sharedPrefs.getInt(KEY_SEARCH_FILTER_MODE, Int.MIN_VALUE))
|
get() = DisplayMode.fromFilterInt(prefs.getInt(KEY_SEARCH_FILTER_MODE, Int.MIN_VALUE))
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_SEARCH_FILTER_MODE, DisplayMode.toFilterInt(value))
|
putInt(KEY_SEARCH_FILTER_MODE, DisplayMode.toFilterInt(value))
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -135,10 +135,10 @@ class SettingsManager private constructor(context: Context) :
|
||||||
|
|
||||||
/** The song sort mode on HomeFragment **/
|
/** The song sort mode on HomeFragment **/
|
||||||
var libSongSort: Sort
|
var libSongSort: Sort
|
||||||
get() = Sort.fromInt(sharedPrefs.getInt(KEY_LIB_SONGS_SORT, Int.MIN_VALUE))
|
get() = Sort.fromInt(prefs.getInt(KEY_LIB_SONGS_SORT, Int.MIN_VALUE))
|
||||||
?: Sort.ByName(true)
|
?: Sort.ByName(true)
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_LIB_SONGS_SORT, value.toInt())
|
putInt(KEY_LIB_SONGS_SORT, value.toInt())
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -146,10 +146,10 @@ class SettingsManager private constructor(context: Context) :
|
||||||
|
|
||||||
/** The album sort mode on HomeFragment **/
|
/** The album sort mode on HomeFragment **/
|
||||||
var libAlbumSort: Sort
|
var libAlbumSort: Sort
|
||||||
get() = Sort.fromInt(sharedPrefs.getInt(KEY_LIB_ALBUMS_SORT, Int.MIN_VALUE))
|
get() = Sort.fromInt(prefs.getInt(KEY_LIB_ALBUMS_SORT, Int.MIN_VALUE))
|
||||||
?: Sort.ByName(true)
|
?: Sort.ByName(true)
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_LIB_ALBUMS_SORT, value.toInt())
|
putInt(KEY_LIB_ALBUMS_SORT, value.toInt())
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -157,10 +157,10 @@ class SettingsManager private constructor(context: Context) :
|
||||||
|
|
||||||
/** The artist sort mode on HomeFragment **/
|
/** The artist sort mode on HomeFragment **/
|
||||||
var libArtistSort: Sort
|
var libArtistSort: Sort
|
||||||
get() = Sort.fromInt(sharedPrefs.getInt(KEY_LIB_ARTISTS_SORT, Int.MIN_VALUE))
|
get() = Sort.fromInt(prefs.getInt(KEY_LIB_ARTISTS_SORT, Int.MIN_VALUE))
|
||||||
?: Sort.ByName(true)
|
?: Sort.ByName(true)
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_LIB_ARTISTS_SORT, value.toInt())
|
putInt(KEY_LIB_ARTISTS_SORT, value.toInt())
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -168,10 +168,10 @@ class SettingsManager private constructor(context: Context) :
|
||||||
|
|
||||||
/** The genre sort mode on HomeFragment **/
|
/** The genre sort mode on HomeFragment **/
|
||||||
var libGenreSort: Sort
|
var libGenreSort: Sort
|
||||||
get() = Sort.fromInt(sharedPrefs.getInt(KEY_LIB_GENRES_SORT, Int.MIN_VALUE))
|
get() = Sort.fromInt(prefs.getInt(KEY_LIB_GENRES_SORT, Int.MIN_VALUE))
|
||||||
?: Sort.ByName(true)
|
?: Sort.ByName(true)
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_LIB_GENRES_SORT, value.toInt())
|
putInt(KEY_LIB_GENRES_SORT, value.toInt())
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -179,10 +179,10 @@ class SettingsManager private constructor(context: Context) :
|
||||||
|
|
||||||
/** The detail album sort mode **/
|
/** The detail album sort mode **/
|
||||||
var detailAlbumSort: Sort
|
var detailAlbumSort: Sort
|
||||||
get() = Sort.fromInt(sharedPrefs.getInt(KEY_DETAIL_ALBUM_SORT, Int.MIN_VALUE))
|
get() = Sort.fromInt(prefs.getInt(KEY_DETAIL_ALBUM_SORT, Int.MIN_VALUE))
|
||||||
?: Sort.ByName(true)
|
?: Sort.ByName(true)
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_DETAIL_ALBUM_SORT, value.toInt())
|
putInt(KEY_DETAIL_ALBUM_SORT, value.toInt())
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -190,10 +190,10 @@ class SettingsManager private constructor(context: Context) :
|
||||||
|
|
||||||
/** The detail artist sort mode **/
|
/** The detail artist sort mode **/
|
||||||
var detailArtistSort: Sort
|
var detailArtistSort: Sort
|
||||||
get() = Sort.fromInt(sharedPrefs.getInt(KEY_DETAIL_ARTIST_SORT, Int.MIN_VALUE))
|
get() = Sort.fromInt(prefs.getInt(KEY_DETAIL_ARTIST_SORT, Int.MIN_VALUE))
|
||||||
?: Sort.ByYear(false)
|
?: Sort.ByYear(false)
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_DETAIL_ARTIST_SORT, value.toInt())
|
putInt(KEY_DETAIL_ARTIST_SORT, value.toInt())
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -201,10 +201,10 @@ class SettingsManager private constructor(context: Context) :
|
||||||
|
|
||||||
/** The detail genre sort mode **/
|
/** The detail genre sort mode **/
|
||||||
var detailGenreSort: Sort
|
var detailGenreSort: Sort
|
||||||
get() = Sort.fromInt(sharedPrefs.getInt(KEY_DETAIL_GENRE_SORT, Int.MIN_VALUE))
|
get() = Sort.fromInt(prefs.getInt(KEY_DETAIL_GENRE_SORT, Int.MIN_VALUE))
|
||||||
?: Sort.ByName(true)
|
?: Sort.ByName(true)
|
||||||
set(value) {
|
set(value) {
|
||||||
sharedPrefs.edit {
|
prefs.edit {
|
||||||
putInt(KEY_DETAIL_GENRE_SORT, value.toInt())
|
putInt(KEY_DETAIL_GENRE_SORT, value.toInt())
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ class SettingsManager private constructor(context: Context) :
|
||||||
const val KEY_USE_ALT_NOTIFICATION_ACTION = "KEY_ALT_NOTIF_ACTION"
|
const val KEY_USE_ALT_NOTIFICATION_ACTION = "KEY_ALT_NOTIF_ACTION"
|
||||||
|
|
||||||
const val KEY_AUDIO_FOCUS = "KEY_AUDIO_FOCUS"
|
const val KEY_AUDIO_FOCUS = "KEY_AUDIO_FOCUS"
|
||||||
const val KEY_PLUG_MANAGEMENT = "KEY_PLUG_MGT"
|
const val KEY_HEADSET_AUTOPLAY = "auxio_headset_autoplay"
|
||||||
const val KEY_REPLAY_GAIN = "auxio_replay_gain"
|
const val KEY_REPLAY_GAIN = "auxio_replay_gain"
|
||||||
|
|
||||||
const val KEY_SONG_PLAYBACK_MODE = "KEY_SONG_PLAY_MODE2"
|
const val KEY_SONG_PLAYBACK_MODE = "KEY_SONG_PLAY_MODE2"
|
||||||
|
|
|
@ -37,12 +37,3 @@ fun assertBackgroundThread() {
|
||||||
"This operation must be ran on a background thread"
|
"This operation must be ran on a background thread"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Assert that we are on a foreground thread.
|
|
||||||
*/
|
|
||||||
fun assertMainThread() {
|
|
||||||
check(Looper.myLooper() == Looper.getMainLooper()) {
|
|
||||||
"This operation must be ran on the main thread"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<layout>
|
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:parentTag="android.widget.FrameLayout">
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
|
||||||
android:id="@+id/shuffle_fab"
|
|
||||||
style="@style/Widget.Auxio.FloatingActionButton.Adaptive"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="@dimen/spacing_medium"
|
|
||||||
android:contentDescription="@string/desc_shuffle_all"
|
|
||||||
android:src="@drawable/ic_shuffle"
|
|
||||||
app:icon="@drawable/ic_shuffle" />
|
|
||||||
|
|
||||||
</merge>
|
|
||||||
</layout>
|
|
|
@ -83,10 +83,8 @@
|
||||||
<string name="set_audio">صوتيات</string>
|
<string name="set_audio">صوتيات</string>
|
||||||
<string name="set_focus">تركيز الصوت</string>
|
<string name="set_focus">تركيز الصوت</string>
|
||||||
<string name="set_focus_desc">ايقاف مؤقت عند تشغيل صوت آخر (كالمكالمات)</string>
|
<string name="set_focus_desc">ايقاف مؤقت عند تشغيل صوت آخر (كالمكالمات)</string>
|
||||||
<string name="set_plug_mgt">تركيز السماعة</string>
|
|
||||||
<string name="set_plug_mgt_desc">تشغيل/ايقاف مؤقت عند حدوث تغيير في اتصال السماعة</string>
|
|
||||||
<string name="set_replay_gain">صخب الصوت (تجريبي)</string>
|
<string name="set_replay_gain">صخب الصوت (تجريبي)</string>
|
||||||
<string name="set_replay_gain_off">اطفاء</string>
|
<string name="set_off">اطفاء</string>
|
||||||
<string name="set_replay_gain_track">تفضيل المقطع</string>
|
<string name="set_replay_gain_track">تفضيل المقطع</string>
|
||||||
<string name="set_replay_gain_album">تفضيل الالبوم</string>
|
<string name="set_replay_gain_album">تفضيل الالبوم</string>
|
||||||
<string name="set_replay_gain_dynamic">ديناميكي</string>
|
<string name="set_replay_gain_dynamic">ديناميكي</string>
|
||||||
|
|
|
@ -67,8 +67,6 @@
|
||||||
<string name="set_audio">"Zvuk"</string>
|
<string name="set_audio">"Zvuk"</string>
|
||||||
<string name="set_focus">"Zaměření zvuku"</string>
|
<string name="set_focus">"Zaměření zvuku"</string>
|
||||||
<string name="set_focus_desc">Pozastavit při přehrávání jiného zvuku (např. hovor)</string>
|
<string name="set_focus_desc">Pozastavit při přehrávání jiného zvuku (např. hovor)</string>
|
||||||
<string name="set_plug_mgt">"Zaměření sluchátek"</string>
|
|
||||||
<string name="set_plug_mgt_desc">"Přehrát/pozastavit při změně připojení sluchátek"</string>
|
|
||||||
<string name="set_behavior">"Chování"</string>
|
<string name="set_behavior">"Chování"</string>
|
||||||
<string name="set_song_mode">"Když je vybrána skladba"</string>
|
<string name="set_song_mode">"Když je vybrána skladba"</string>
|
||||||
<string name="set_keep_shuffle">"Zapamatovat si náhodné přehrávání"</string>
|
<string name="set_keep_shuffle">"Zapamatovat si náhodné přehrávání"</string>
|
||||||
|
|
|
@ -71,10 +71,8 @@
|
||||||
<string name="set_audio">Audio</string>
|
<string name="set_audio">Audio</string>
|
||||||
<string name="set_focus">Audiofokus</string>
|
<string name="set_focus">Audiofokus</string>
|
||||||
<string name="set_focus_desc">Pausieren wenn andere Töne abspielt wird [Bsp. Anrufe]</string>
|
<string name="set_focus_desc">Pausieren wenn andere Töne abspielt wird [Bsp. Anrufe]</string>
|
||||||
<string name="set_plug_mgt">Kopfhörerfokus</string>
|
|
||||||
<string name="set_plug_mgt_desc">Abspielen/Pausieren wenn sich die Kopfhörerverbindung ändert</string>
|
|
||||||
<string name="set_replay_gain">ReplayGain (Experimentell)</string>
|
<string name="set_replay_gain">ReplayGain (Experimentell)</string>
|
||||||
<string name="set_replay_gain_off">Aus</string>
|
<string name="set_off">Aus</string>
|
||||||
<string name="set_replay_gain_track">Titel bevorzugen</string>
|
<string name="set_replay_gain_track">Titel bevorzugen</string>
|
||||||
<string name="set_replay_gain_album">Album bevorzugen</string>
|
<string name="set_replay_gain_album">Album bevorzugen</string>
|
||||||
|
|
||||||
|
@ -151,7 +149,7 @@
|
||||||
<item quantity="other">%d Alben</item>
|
<item quantity="other">%d Alben</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="info_app_desc">Ein einfacher, rationaler Musikplayer für Android.</string>
|
<string name="info_app_desc">Ein einfacher, rationaler Musikplayer für Android.</string>
|
||||||
<string name="info_widget_desc">Spielende Musik anzeigen und kontrollieren</string>
|
<string name="info_widget_desc">Musikwiedergabe anzeigen und kontrollieren</string>
|
||||||
<string name="lbl_sort_artist">Künstler</string>
|
<string name="lbl_sort_artist">Künstler</string>
|
||||||
<string name="lbl_sort_album">Album</string>
|
<string name="lbl_sort_album">Album</string>
|
||||||
<string name="lbl_sort_year">Jahr</string>
|
<string name="lbl_sort_year">Jahr</string>
|
||||||
|
@ -173,5 +171,4 @@
|
||||||
<string name="desc_clear_queue_item">Lied in der Warteschlange löschen</string>
|
<string name="desc_clear_queue_item">Lied in der Warteschlange löschen</string>
|
||||||
<string name="desc_tab_handle">Tab versetzen</string>
|
<string name="desc_tab_handle">Tab versetzen</string>
|
||||||
<string name="def_artist">Unbekannter Künstler</string>
|
<string name="def_artist">Unbekannter Künstler</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -83,10 +83,8 @@
|
||||||
<string name="set_audio">Sonido</string>
|
<string name="set_audio">Sonido</string>
|
||||||
<string name="set_focus">Enfoque de sonido</string>
|
<string name="set_focus">Enfoque de sonido</string>
|
||||||
<string name="set_focus_desc">Pausar cuando se reproduce otro sonido (Ej: llamadas)</string>
|
<string name="set_focus_desc">Pausar cuando se reproduce otro sonido (Ej: llamadas)</string>
|
||||||
<string name="set_plug_mgt">Enfoque de auriculares</string>
|
|
||||||
<string name="set_plug_mgt_desc">Reproducir/Pausar dependiendo de la conexión de auriculares</string>
|
|
||||||
<string name="set_replay_gain">ReplayGain (Experimental)</string>
|
<string name="set_replay_gain">ReplayGain (Experimental)</string>
|
||||||
<string name="set_replay_gain_off">Desactivado</string>
|
<string name="set_off">Desactivado</string>
|
||||||
<string name="set_replay_gain_track">Por pista</string>
|
<string name="set_replay_gain_track">Por pista</string>
|
||||||
<string name="set_replay_gain_album">Por álbum</string>
|
<string name="set_replay_gain_album">Por álbum</string>
|
||||||
<string name="set_replay_gain_dynamic">Dinámico</string>
|
<string name="set_replay_gain_dynamic">Dinámico</string>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
|
|
||||||
<string name="set_audio">Audio</string>
|
<string name="set_audio">Audio</string>
|
||||||
<string name="set_focus">Audio Focus</string>
|
<string name="set_focus">Audio Focus</string>
|
||||||
<string name="set_plug_mgt">Branchement du casque</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">Comportement</string>
|
<string name="set_behavior">Comportement</string>
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
|
|
||||||
<string name="set_audio">ऑडियो</string>
|
<string name="set_audio">ऑडियो</string>
|
||||||
<string name="set_focus">ऑडियो फोकस</string>
|
<string name="set_focus">ऑडियो फोकस</string>
|
||||||
<string name="set_plug_mgt">हेडसेट प्लग</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">चाल चलन</string>
|
<string name="set_behavior">चाल चलन</string>
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
|
|
||||||
<string name="set_audio">Hang</string>
|
<string name="set_audio">Hang</string>
|
||||||
<string name="set_focus">Hangfókusz</string>
|
<string name="set_focus">Hangfókusz</string>
|
||||||
<string name="set_plug_mgt">Fejhallgató csatlakozó</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">Működés</string>
|
<string name="set_behavior">Működés</string>
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
|
|
||||||
<string name="set_audio">Audio</string>
|
<string name="set_audio">Audio</string>
|
||||||
<string name="set_focus">Focus audio</string>
|
<string name="set_focus">Focus audio</string>
|
||||||
<string name="set_plug_mgt">Inserimento cuffie</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">Comportamento</string>
|
<string name="set_behavior">Comportamento</string>
|
||||||
<string name="set_keep_shuffle">Ricorda casuale</string>
|
<string name="set_keep_shuffle">Ricorda casuale</string>
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
|
|
||||||
<string name="set_audio">오디오</string>
|
<string name="set_audio">오디오</string>
|
||||||
<string name="set_focus">오디오 포커스</string>
|
<string name="set_focus">오디오 포커스</string>
|
||||||
<string name="set_plug_mgt">헤드셋 연결</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">동작</string>
|
<string name="set_behavior">동작</string>
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,6 @@
|
||||||
<string name="set_audio">Audio</string>
|
<string name="set_audio">Audio</string>
|
||||||
<string name="set_focus">Audiofocus</string>
|
<string name="set_focus">Audiofocus</string>
|
||||||
<string name="set_focus_desc">Pauze wanneer andere audio speelt (ex. Gesprekken)</string>
|
<string name="set_focus_desc">Pauze wanneer andere audio speelt (ex. Gesprekken)</string>
|
||||||
<string name="set_plug_mgt">Headset-pluggen</string>
|
|
||||||
<string name="set_plug_mgt_desc">Afspelen/Pauzeren wanneer de headsetaansluiting verandert</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">Gedrag</string>
|
<string name="set_behavior">Gedrag</string>
|
||||||
<string name="set_song_mode">Wanneer een liedje is geselecteerd</string>
|
<string name="set_song_mode">Wanneer een liedje is geselecteerd</string>
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
|
|
||||||
<string name="set_audio">Dźwięk</string>
|
<string name="set_audio">Dźwięk</string>
|
||||||
<string name="set_focus">Wyciszanie otoczenia</string>
|
<string name="set_focus">Wyciszanie otoczenia</string>
|
||||||
<string name="set_plug_mgt">Podłączanie słuchawek</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">Zachowanie</string>
|
<string name="set_behavior">Zachowanie</string>
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
|
|
||||||
<string name="set_audio">Áudio</string>
|
<string name="set_audio">Áudio</string>
|
||||||
<string name="set_focus">Foco do áudio</string>
|
<string name="set_focus">Foco do áudio</string>
|
||||||
<string name="set_plug_mgt">Entrada do fone de ouvido</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">Comportamento</string>
|
<string name="set_behavior">Comportamento</string>
|
||||||
<string name="set_keep_shuffle">Memorizar aleatorização</string>
|
<string name="set_keep_shuffle">Memorizar aleatorização</string>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
|
|
||||||
<string name="set_audio">Áudio</string>
|
<string name="set_audio">Áudio</string>
|
||||||
<string name="set_focus">Foco de áudio</string>
|
<string name="set_focus">Foco de áudio</string>
|
||||||
<string name="set_plug_mgt">Entrada do fone de ouvido</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">Comportamento</string>
|
<string name="set_behavior">Comportamento</string>
|
||||||
<string name="set_keep_shuffle">Memorizar aleatorização</string>
|
<string name="set_keep_shuffle">Memorizar aleatorização</string>
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
|
|
||||||
<string name="set_audio">Audio</string>
|
<string name="set_audio">Audio</string>
|
||||||
<string name="set_focus">Concentrare audio</string>
|
<string name="set_focus">Concentrare audio</string>
|
||||||
<string name="set_plug_mgt">Conexiune cu cască</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">Comportament</string>
|
<string name="set_behavior">Comportament</string>
|
||||||
|
|
||||||
|
|
|
@ -83,10 +83,8 @@
|
||||||
<string name="set_audio">Звук</string>
|
<string name="set_audio">Звук</string>
|
||||||
<string name="set_focus">Аудио-фокус</string>
|
<string name="set_focus">Аудио-фокус</string>
|
||||||
<string name="set_focus_desc">Ставить на паузу при звонках</string>
|
<string name="set_focus_desc">Ставить на паузу при звонках</string>
|
||||||
<string name="set_plug_mgt">Гарнитурный фокус</string>
|
|
||||||
<string name="set_plug_mgt_desc">Ставить на паузу при отключении гарнитуры</string>
|
|
||||||
<string name="set_replay_gain">ReplayGain (экспериментально)</string>
|
<string name="set_replay_gain">ReplayGain (экспериментально)</string>
|
||||||
<string name="set_replay_gain_off">Выкл.</string>
|
<string name="set_off">Выкл.</string>
|
||||||
<string name="set_replay_gain_track">По треку</string>
|
<string name="set_replay_gain_track">По треку</string>
|
||||||
<string name="set_replay_gain_album">По альбому</string>
|
<string name="set_replay_gain_album">По альбому</string>
|
||||||
<string name="set_replay_gain_dynamic">Динамический</string>
|
<string name="set_replay_gain_dynamic">Динамический</string>
|
||||||
|
|
|
@ -83,10 +83,8 @@
|
||||||
<string name="set_audio">音频</string>
|
<string name="set_audio">音频</string>
|
||||||
<string name="set_focus">音频焦点</string>
|
<string name="set_focus">音频焦点</string>
|
||||||
<string name="set_focus_desc">有其它音频播放(比如电话)时暂停</string>
|
<string name="set_focus_desc">有其它音频播放(比如电话)时暂停</string>
|
||||||
<string name="set_plug_mgt">设备焦点</string>
|
|
||||||
<string name="set_plug_mgt_desc">设备连接状态改变时播放/暂停</string>
|
|
||||||
<string name="set_replay_gain">回放增益</string>
|
<string name="set_replay_gain">回放增益</string>
|
||||||
<string name="set_replay_gain_off">关</string>
|
<string name="set_off">关</string>
|
||||||
<string name="set_replay_gain_track">偏好曲目</string>
|
<string name="set_replay_gain_track">偏好曲目</string>
|
||||||
<string name="set_replay_gain_album">偏好专辑</string>
|
<string name="set_replay_gain_album">偏好专辑</string>
|
||||||
<string name="set_replay_gain_dynamic">动态</string>
|
<string name="set_replay_gain_dynamic">动态</string>
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
|
|
||||||
<string name="set_audio">音訊</string>
|
<string name="set_audio">音訊</string>
|
||||||
<string name="set_focus">音頻焦點</string>
|
<string name="set_focus">音頻焦點</string>
|
||||||
<string name="set_plug_mgt">耳機插頭</string>
|
|
||||||
|
|
||||||
<string name="set_behavior">行為</string>
|
<string name="set_behavior">行為</string>
|
||||||
<string name="set_keep_shuffle">記住隨機播放</string>
|
<string name="set_keep_shuffle">記住隨機播放</string>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<array name="entries_replay_gain">
|
<array name="entries_replay_gain">
|
||||||
<item>@string/set_replay_gain_off</item>
|
<item>@string/set_off</item>
|
||||||
<item>@string/set_replay_gain_track</item>
|
<item>@string/set_replay_gain_track</item>
|
||||||
<item>@string/set_replay_gain_album</item>
|
<item>@string/set_replay_gain_album</item>
|
||||||
<item>@string/set_replay_gain_dynamic</item>
|
<item>@string/set_replay_gain_dynamic</item>
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||||
|
|
||||||
<!-- Info namespace | App labels -->
|
<!-- Info namespace | App labels -->
|
||||||
<string name="info_app_desc">A simple, rational music player for android.</string>
|
<string name="info_app_desc">A simple, rational music player for android.</string>
|
||||||
<string name="info_channel_name">Music Playback</string>
|
<string name="info_channel_name">Music Playback</string>
|
||||||
<string name="info_widget_desc">View and control playing music</string>
|
<string name="info_widget_desc">View and control music playback</string>
|
||||||
|
|
||||||
<!-- Label Namespace | Static Labels -->
|
<!-- Label Namespace | Static Labels -->
|
||||||
<string name="lbl_retry">Retry</string>
|
<string name="lbl_retry">Retry</string>
|
||||||
|
@ -83,10 +82,9 @@
|
||||||
<string name="set_audio">Audio</string>
|
<string name="set_audio">Audio</string>
|
||||||
<string name="set_focus">Audio focus</string>
|
<string name="set_focus">Audio focus</string>
|
||||||
<string name="set_focus_desc">Pause when other audio plays (ex. Calls)</string>
|
<string name="set_focus_desc">Pause when other audio plays (ex. Calls)</string>
|
||||||
<string name="set_plug_mgt">Headset focus</string>
|
<string name="set_headset_autoplay">Headset autoplay</string>
|
||||||
<string name="set_plug_mgt_desc">Play/Pause when the headset connection changes</string>
|
<string name="set_headset_autoplay_desc">Always start playing when a headset is connected (may not work on all devices)</string>
|
||||||
<string name="set_replay_gain">ReplayGain (Experimental)</string>
|
<string name="set_replay_gain">ReplayGain (Experimental)</string>
|
||||||
<string name="set_replay_gain_off">Off</string>
|
|
||||||
<string name="set_replay_gain_track">Prefer track</string>
|
<string name="set_replay_gain_track">Prefer track</string>
|
||||||
<string name="set_replay_gain_album">Prefer album</string>
|
<string name="set_replay_gain_album">Prefer album</string>
|
||||||
<string name="set_replay_gain_dynamic">Dynamic</string>
|
<string name="set_replay_gain_dynamic">Dynamic</string>
|
||||||
|
@ -108,6 +106,8 @@
|
||||||
<string name="set_excluded">Excluded folders</string>
|
<string name="set_excluded">Excluded folders</string>
|
||||||
<string name="set_excluded_desc">The content of excluded folders is hidden from your library</string>
|
<string name="set_excluded_desc">The content of excluded folders is hidden from your library</string>
|
||||||
|
|
||||||
|
<string name="set_off">Off</string>
|
||||||
|
|
||||||
<!-- Error Namespace | Error Labels -->
|
<!-- Error Namespace | Error Labels -->
|
||||||
<string name="err_no_music">No music found</string>
|
<string name="err_no_music">No music found</string>
|
||||||
<string name="err_load_failed">Music loading failed</string>
|
<string name="err_load_failed">Music loading failed</string>
|
||||||
|
|
|
@ -87,11 +87,11 @@
|
||||||
app:title="@string/set_focus" />
|
app:title="@string/set_focus" />
|
||||||
|
|
||||||
<org.oxycblt.auxio.settings.pref.M3SwitchPreference
|
<org.oxycblt.auxio.settings.pref.M3SwitchPreference
|
||||||
app:defaultValue="true"
|
app:defaultValue="false"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="KEY_PLUG_MGT"
|
app:key="auxio_headset_autoplay"
|
||||||
app:summary="@string/set_plug_mgt_desc"
|
app:summary="@string/set_headset_autoplay_desc"
|
||||||
app:title="@string/set_plug_mgt" />
|
app:title="@string/set_headset_autoplay" />
|
||||||
|
|
||||||
<org.oxycblt.auxio.settings.pref.IntListPreference
|
<org.oxycblt.auxio.settings.pref.IntListPreference
|
||||||
app:defaultValue="@integer/replay_gain_off"
|
app:defaultValue="@integer/replay_gain_off"
|
||||||
|
|
70
prebuild.py
70
prebuild.py
|
@ -1,15 +1,24 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# This script automatically installs exoplayer with the necessary components.
|
|
||||||
# This is written in version-agnostic python 3, because I'd rather not have to
|
# This script automatically assembles any required ExoPlayer extensions or components as
|
||||||
# deal with the insanity of bash.
|
# an AAR blob. This method is not only faster than depending on ExoPlayer outright as we
|
||||||
|
# only need to build our components once, it's also easier to use with Android Studio, which
|
||||||
|
# tends to get bogged down when we include a massive source repository as part of the gradle
|
||||||
|
# project. This script may change from time to time depending on the components or extensions
|
||||||
|
# that I leverage. It's recommended to re-run it after every release to ensure consistent
|
||||||
|
# behavior.
|
||||||
|
|
||||||
|
# As for why I wrote this in Python and not Bash, it's because Bash really does not have
|
||||||
|
# the capabilities for a nice, seamless pre-build process.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# WARNING: THE EXOPLAYER VERSION MUST BE KEPT IN LOCK-STEP WITH THE FLAC EXTENSION.
|
# WARNING: THE EXOPLAYER VERSION MUST BE KEPT IN LOCK-STEP WITH THE FLAC EXTENSION AND
|
||||||
# IF NOT, VERY UNFRIENDLY BUILD FAILURES AND CRASHES MAY ENSUE.
|
# THE GRADLE DEPENDENCY. IF NOT, VERY UNFRIENDLY BUILD FAILURES AND CRASHES MAY ENSUE.
|
||||||
EXO_VERSION = "2.17.0"
|
EXO_VERSION = "2.17.0"
|
||||||
FLAC_VERSION = "1.3.2"
|
FLAC_VERSION = "1.3.2"
|
||||||
|
|
||||||
|
@ -19,32 +28,38 @@ INFO="\033[1;94m"
|
||||||
OK="\033[1;92m"
|
OK="\033[1;92m"
|
||||||
NC="\033[0m"
|
NC="\033[0m"
|
||||||
|
|
||||||
system = platform.system()
|
|
||||||
|
|
||||||
# We do some shell scripting later on, so we can't support windows.
|
# We do some shell scripting later on, so we can't support windows.
|
||||||
|
system = platform.system()
|
||||||
if system not in ["Linux", "Darwin"]:
|
if system not in ["Linux", "Darwin"]:
|
||||||
print("fatal: unsupported platform " + system)
|
print("fatal: unsupported platform " + system)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def sh(cmd):
|
def sh(cmd):
|
||||||
|
print(INFO + "execute: " + NC + cmd)
|
||||||
code = subprocess.call(["sh", "-c", "set -e; " + cmd])
|
code = subprocess.call(["sh", "-c", "set -e; " + cmd])
|
||||||
|
|
||||||
if code != 0:
|
if code != 0:
|
||||||
print(FATAL + "fatal:" + NC + " command failed with exit code " + str(code))
|
print(FATAL + "fatal:" + NC + " command failed with exit code " + str(code))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
start_path = os.path.join(os.path.abspath(os.curdir))
|
start_path = os.path.join(os.path.abspath(os.curdir))
|
||||||
libs_path = os.path.join(start_path, "app", "libs")
|
libs_path = os.path.join(start_path, "app", "libs")
|
||||||
exoplayer_path = os.path.join(start_path, "app", "build", "srclibs", "exoplayer")
|
|
||||||
|
|
||||||
if os.path.exists(libs_path):
|
if os.path.exists(libs_path):
|
||||||
reinstall = input(INFO + "info:" + NC + " exoplayer is already installed. would you like to reinstall it? [y/n] ")
|
reinstall = input(INFO + "info:" + NC + " exoplayer is already installed. " +
|
||||||
|
"would you like to reinstall it? [y/n] ")
|
||||||
if not re.match("[yY][eE][sS]|[yY]", reinstall):
|
if not re.match("[yY][eE][sS]|[yY]", reinstall):
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
ndk_path = os.getenv("NDK_PATH")
|
exoplayer_path = os.path.join(start_path, "app", "build", "srclibs", "exoplayer")
|
||||||
|
|
||||||
|
# Ensure that there is always an SDK environment variable.
|
||||||
|
# Technically there is also an sdk.dir field in local.properties, but that does
|
||||||
|
# not work when you clone a project without a local.properties.
|
||||||
|
if os.getenv("ANDROID_HOME") is None and os.getenv("ANDROID_SDK_ROOT") is None:
|
||||||
|
print(FATAL + "fatal:" + NC + " sdk location not found. please define " +
|
||||||
|
"ANDROID_HOME/ANDROID_SDK_ROOT before continuing.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
ndk_path = os.getenv("NDK_PATH")
|
||||||
if ndk_path is None or not os.path.isfile(os.path.join(ndk_path, "ndk-build")):
|
if ndk_path is None or not os.path.isfile(os.path.join(ndk_path, "ndk-build")):
|
||||||
# We don't have a proper path. Do some digging on the Android SDK directory
|
# We don't have a proper path. Do some digging on the Android SDK directory
|
||||||
# to see if we can find it.
|
# to see if we can find it.
|
||||||
|
@ -54,14 +69,13 @@ if ndk_path is None or not os.path.isfile(os.path.join(ndk_path, "ndk-build")):
|
||||||
ndk_root = os.path.join(os.getenv("HOME"), "Library", "Android", "sdk", "ndk")
|
ndk_root = os.path.join(os.getenv("HOME"), "Library", "Android", "sdk", "ndk")
|
||||||
|
|
||||||
candidates = []
|
candidates = []
|
||||||
|
|
||||||
for entry in os.scandir(ndk_root):
|
for entry in os.scandir(ndk_root):
|
||||||
if entry.is_dir():
|
if entry.is_dir():
|
||||||
candidates.append(entry.path)
|
candidates.append(entry.path)
|
||||||
|
|
||||||
if len(candidates) > 0:
|
if len(candidates) > 0:
|
||||||
print(WARN + "warn:" + NC + " NDK_PATH was not set or invalid. multiple candidates were found however:")
|
print(WARN + "warn:" + NC + " NDK_PATH was not set or invalid. multiple " +
|
||||||
|
"candidates were found however:")
|
||||||
for i, candidate in enumerate(candidates):
|
for i, candidate in enumerate(candidates):
|
||||||
print("[" + str(i) + "] " + candidate)
|
print("[" + str(i) + "] " + candidate)
|
||||||
|
|
||||||
|
@ -70,9 +84,12 @@ if ndk_path is None or not os.path.isfile(os.path.join(ndk_path, "ndk-build")):
|
||||||
except:
|
except:
|
||||||
ndk_path = candidates[0]
|
ndk_path = candidates[0]
|
||||||
else:
|
else:
|
||||||
print(FATAL + "fatal:" + NC + " the android ndk was not installed at a recognized location.")
|
print(FATAL + "fatal:" + NC + " the android ndk was not installed at a " +
|
||||||
|
"recognized location.")
|
||||||
system.exit(1)
|
system.exit(1)
|
||||||
|
|
||||||
|
ndk_build_path = os.path.join(ndk_path, "ndk-build")
|
||||||
|
|
||||||
# Now try to install ExoPlayer.
|
# Now try to install ExoPlayer.
|
||||||
sh("rm -rf " + exoplayer_path)
|
sh("rm -rf " + exoplayer_path)
|
||||||
sh("rm -rf " + libs_path)
|
sh("rm -rf " + libs_path)
|
||||||
|
@ -82,18 +99,15 @@ sh("git clone https://github.com/google/ExoPlayer.git " + exoplayer_path)
|
||||||
os.chdir(exoplayer_path)
|
os.chdir(exoplayer_path)
|
||||||
sh("git checkout r" + EXO_VERSION)
|
sh("git checkout r" + EXO_VERSION)
|
||||||
|
|
||||||
print(INFO + "info:" + NC + " installing flac extension...")
|
print(INFO + "info:" + NC + " assembling flac extension...")
|
||||||
|
flac_ext_aar_path = os.path.join(exoplayer_path, "extensions", "flac",
|
||||||
|
"buildout", "outputs", "aar", "extension-flac-release.aar")
|
||||||
flac_ext_jni_path = os.path.join("extensions", "flac", "src", "main", "jni")
|
flac_ext_jni_path = os.path.join("extensions", "flac", "src", "main", "jni")
|
||||||
ndk_build_path = os.path.join(ndk_path, "ndk-build")
|
|
||||||
os.chdir(flac_ext_jni_path)
|
|
||||||
sh('curl "https://ftp.osuosl.org/pub/xiph/releases/flac/flac-' + FLAC_VERSION + '.tar.xz" | tar xJ && mv "flac-' + FLAC_VERSION + '" flac')
|
|
||||||
sh(ndk_build_path + " APP_ABI=all -j4")
|
|
||||||
|
|
||||||
print(INFO + "info:" + NC + " assembling libraries")
|
os.chdir(flac_ext_jni_path)
|
||||||
flac_ext_aar_path = os.path.join(
|
sh('curl "https://ftp.osuosl.org/pub/xiph/releases/flac/flac-' + FLAC_VERSION +
|
||||||
exoplayer_path, "extensions", "flac", "buildout",
|
'.tar.xz" | tar xJ && mv "flac-' + FLAC_VERSION + '" flac')
|
||||||
"outputs", "aar", "extension-flac-release.aar"
|
sh(ndk_build_path + " APP_ABI=all -j4")
|
||||||
)
|
|
||||||
|
|
||||||
os.chdir(exoplayer_path)
|
os.chdir(exoplayer_path)
|
||||||
sh("./gradlew extension-flac:bundleReleaseAar")
|
sh("./gradlew extension-flac:bundleReleaseAar")
|
||||||
|
@ -102,4 +116,4 @@ os.chdir(start_path)
|
||||||
sh("mkdir " + libs_path)
|
sh("mkdir " + libs_path)
|
||||||
sh("cp " + flac_ext_aar_path + " " + libs_path)
|
sh("cp " + flac_ext_aar_path + " " + libs_path)
|
||||||
|
|
||||||
print(OK + "success:" + NC + " completed pre-build.")
|
print(OK + "success:" + NC + " completed pre-build")
|
||||||
|
|
Loading…
Reference in a new issue