playback: replace song options with equalizer
Replace the song options button in the playback menu with a button that opens the equalizer. I plan to re-introduce the song options in another location.
This commit is contained in:
parent
ee68e7ffe9
commit
d4884cc9ca
9 changed files with 70 additions and 27 deletions
|
@ -2,6 +2,9 @@
|
|||
|
||||
## dev
|
||||
|
||||
#### What's Improved
|
||||
- Added a way to access the system equalizer from the playback menu.
|
||||
|
||||
#### What's Changed
|
||||
- ReplayGain can now no longer be disabled. Remove ReplayGain tags from
|
||||
files if such functionality is not desired.
|
||||
|
|
|
@ -17,9 +17,13 @@
|
|||
|
||||
package org.oxycblt.auxio.playback
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.media.audiofx.AudioEffect
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.Fragment
|
||||
|
@ -34,6 +38,7 @@ import org.oxycblt.auxio.ui.NavigationViewModel
|
|||
import org.oxycblt.auxio.ui.fragment.ViewBindingFragment
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.collectImmediately
|
||||
import org.oxycblt.auxio.util.showToast
|
||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||
|
||||
/**
|
||||
|
@ -50,6 +55,14 @@ class PlaybackPanelFragment :
|
|||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||
private val navModel: NavigationViewModel by activityViewModels()
|
||||
|
||||
// AudioEffect expects you to use startActivityForResult with the panel intent. Use
|
||||
// the contract analogue for this since there is no built-in contract for AudioEffect.
|
||||
private val activityLauncher by lifecycleObject {
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateBinding(inflater: LayoutInflater) =
|
||||
FragmentPlaybackPanelBinding.inflate(inflater)
|
||||
|
||||
|
@ -110,18 +123,19 @@ class PlaybackPanelFragment :
|
|||
|
||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_go_artist -> {
|
||||
playbackModel.song.value?.let { navModel.exploreNavigateTo(it.album.artist) }
|
||||
true
|
||||
}
|
||||
R.id.action_go_album -> {
|
||||
playbackModel.song.value?.let { navModel.exploreNavigateTo(it.album) }
|
||||
true
|
||||
}
|
||||
R.id.action_song_detail -> {
|
||||
playbackModel.song.value?.let {
|
||||
navModel.mainNavigateTo(MainNavigationAction.SongDetails(it))
|
||||
R.id.action_open_equalizer -> {
|
||||
val equalizerIntent =
|
||||
Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL)
|
||||
.putExtra(
|
||||
AudioEffect.EXTRA_AUDIO_SESSION, playbackModel.currentAudioSessionId)
|
||||
.putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
|
||||
|
||||
try {
|
||||
activityLauncher.launch(equalizerIntent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
requireContext().showToast(R.string.err_no_app)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
|
|
|
@ -76,6 +76,9 @@ class PlaybackViewModel(application: Application) :
|
|||
val isShuffled: StateFlow<Boolean>
|
||||
get() = _isShuffled
|
||||
|
||||
val currentAudioSessionId: Int?
|
||||
get() = playbackManager.currentAudioSessionId
|
||||
|
||||
init {
|
||||
musicStore.addCallback(this)
|
||||
playbackManager.addCallback(this)
|
||||
|
@ -170,7 +173,7 @@ class PlaybackViewModel(application: Application) :
|
|||
}
|
||||
}
|
||||
|
||||
// --- POSITION FUNCTIONS ---
|
||||
// --- PLAYER FUNCTIONS ---
|
||||
|
||||
/** Update the position and push it to [PlaybackStateManager] */
|
||||
fun seekTo(positionSecs: Long) {
|
||||
|
|
|
@ -89,6 +89,10 @@ class PlaybackStateManager private constructor() {
|
|||
var isInitialized = false
|
||||
private set
|
||||
|
||||
/** The current audio session ID of the controller. Null if no controller present. */
|
||||
val currentAudioSessionId: Int?
|
||||
get() = controller?.audioSessionId
|
||||
|
||||
// --- CALLBACKS ---
|
||||
|
||||
private val callbacks = mutableListOf<Callback>()
|
||||
|
@ -509,6 +513,8 @@ class PlaybackStateManager private constructor() {
|
|||
|
||||
/** Represents a class capable of managing the internal player. */
|
||||
interface Controller {
|
||||
val audioSessionId: Int
|
||||
|
||||
/** Called when a new song should be loaded into the player. */
|
||||
fun loadSong(song: Song?)
|
||||
|
||||
|
|
|
@ -250,6 +250,9 @@ class PlaybackService :
|
|||
|
||||
// --- CONTROLLER OVERRIDES ---
|
||||
|
||||
override val audioSessionId: Int
|
||||
get() = player.audioSessionId
|
||||
|
||||
override fun loadSong(song: Song?) {
|
||||
if (song == null) {
|
||||
// Stop the foreground state if there's nothing to play.
|
||||
|
@ -265,8 +268,6 @@ class PlaybackService :
|
|||
return
|
||||
}
|
||||
|
||||
C.ENCODING_PCM_32BIT
|
||||
|
||||
logD("Loading ${song.rawName}")
|
||||
player.setMediaItem(MediaItem.fromUri(song.uri))
|
||||
player.prepare()
|
||||
|
@ -355,7 +356,7 @@ class PlaybackService :
|
|||
sendBroadcast(
|
||||
Intent(event)
|
||||
.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, packageName)
|
||||
.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, player.audioSessionId)
|
||||
.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, audioSessionId)
|
||||
.putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC))
|
||||
}
|
||||
|
||||
|
|
11
app/src/main/res/drawable/ic_equalizer.xml
Normal file
11
app/src/main/res/drawable/ic_equalizer.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M11,21V15H13V17H21V19H13V21ZM3,19V17H9V19ZM7,15V13H3V11H7V9H9V15ZM11,13V11H21V13ZM15,9V3H17V5H21V7H17V9ZM3,7V5H13V7Z"/>
|
||||
</vector>
|
11
app/src/main/res/drawable/ic_more_24.xml
Normal file
11
app/src/main/res/drawable/ic_more_24.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,20Q11.175,20 10.588,19.413Q10,18.825 10,18Q10,17.175 10.588,16.587Q11.175,16 12,16Q12.825,16 13.413,16.587Q14,17.175 14,18Q14,18.825 13.413,19.413Q12.825,20 12,20ZM12,14Q11.175,14 10.588,13.412Q10,12.825 10,12Q10,11.175 10.588,10.587Q11.175,10 12,10Q12.825,10 13.413,10.587Q14,11.175 14,12Q14,12.825 13.413,13.412Q12.825,14 12,14ZM12,8Q11.175,8 10.588,7.412Q10,6.825 10,6Q10,5.175 10.588,4.588Q11.175,4 12,4Q12.825,4 13.413,4.588Q14,5.175 14,6Q14,6.825 13.413,7.412Q12.825,8 12,8Z"/>
|
||||
</vector>
|
|
@ -2,15 +2,8 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_go_artist"
|
||||
android:title="@string/lbl_go_artist"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_go_album"
|
||||
android:title="@string/lbl_go_album"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_song_detail"
|
||||
android:title="@string/lbl_song_detail"
|
||||
app:showAsAction="never" />
|
||||
android:id="@+id/action_open_equalizer"
|
||||
android:title="@string/lbl_equalizer"
|
||||
android:icon="@drawable/ic_equalizer"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
|
@ -87,6 +87,7 @@
|
|||
<string name="lbl_sort_asc">Ascending</string>
|
||||
|
||||
<string name="lbl_playback">Now playing</string>
|
||||
<string name="lbl_equalizer">Equalizer</string>
|
||||
<string name="lbl_play">Play</string>
|
||||
<string name="lbl_shuffle">Shuffle</string>
|
||||
|
||||
|
@ -235,7 +236,7 @@
|
|||
<string name="err_no_music">No music found</string>
|
||||
<string name="err_index_failed">Music loading failed</string>
|
||||
<string name="err_no_perms">Auxio needs permission to read your music library</string>
|
||||
<string name="err_no_app">No app can open this link</string>
|
||||
<string name="err_no_app">No app found that can handle this task</string>
|
||||
<!-- No folders in the "Music Folders" setting -->
|
||||
<string name="err_no_dirs">No folders</string>
|
||||
<string name="err_bad_dir">This folder is not supported</string>
|
||||
|
|
Loading…
Reference in a new issue