Merge branch 'media3' into dev
This commit is contained in:
commit
d5086fc3e6
14 changed files with 46 additions and 78 deletions
23
CHANGELOG.md
23
CHANGELOG.md
|
@ -1,6 +1,27 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## dev
|
## 3.5.0
|
||||||
|
|
||||||
|
#### What's New
|
||||||
|
- Android Auto support
|
||||||
|
- Full media browser implementation
|
||||||
|
|
||||||
|
#### What's Improved
|
||||||
|
- Album covers are now loaded on a per-song basis
|
||||||
|
- Correctly interpret MP4 sort tags
|
||||||
|
|
||||||
|
#### What's Fixed
|
||||||
|
- Fixed repeat mode not restoring on startup
|
||||||
|
|
||||||
|
#### What's Changed
|
||||||
|
- For the time being, the media notification will not follow Album Covers or 1:1 Covers settings
|
||||||
|
- Playback will close automatically after some time left idle
|
||||||
|
|
||||||
|
#### dev -> dev1 changes
|
||||||
|
- Re-added ability to open app from clicking on notification
|
||||||
|
- Removed tasker plugin
|
||||||
|
|
||||||
|
## 3.4.3
|
||||||
|
|
||||||
#### What's Improved
|
#### What's Improved
|
||||||
- Added back option disable ReplayGain for poorly tagged libraries
|
- Added back option disable ReplayGain for poorly tagged libraries
|
||||||
|
|
|
@ -21,8 +21,8 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId namespace
|
applicationId namespace
|
||||||
versionName "3.4.3"
|
versionName "3.5.0-dev"
|
||||||
versionCode 44
|
versionCode 45
|
||||||
|
|
||||||
minSdk 24
|
minSdk 24
|
||||||
targetSdk 34
|
targetSdk 34
|
||||||
|
|
|
@ -134,5 +134,6 @@
|
||||||
android:name="android.appwidget.provider"
|
android:name="android.appwidget.provider"
|
||||||
android:resource="@xml/widget_info" />
|
android:resource="@xml/widget_info" />
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
|
@ -28,6 +28,8 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.oxycblt.auxio.music.service.IndexerServiceFragment
|
import org.oxycblt.auxio.music.service.IndexerServiceFragment
|
||||||
import org.oxycblt.auxio.playback.service.MediaSessionServiceFragment
|
import org.oxycblt.auxio.playback.service.MediaSessionServiceFragment
|
||||||
|
import org.oxycblt.auxio.tasker.indicateServiceRunning
|
||||||
|
import org.oxycblt.auxio.tasker.indicateServiceStopped
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class AuxioService : MediaLibraryService(), ForegroundListener {
|
class AuxioService : MediaLibraryService(), ForegroundListener {
|
||||||
|
@ -40,6 +42,7 @@ class AuxioService : MediaLibraryService(), ForegroundListener {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
mediaSessionFragment.attach(this, this)
|
mediaSessionFragment.attach(this, this)
|
||||||
indexingFragment.attach(this)
|
indexingFragment.attach(this)
|
||||||
|
indicateServiceRunning()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent?): IBinder? {
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
|
@ -70,6 +73,7 @@ class AuxioService : MediaLibraryService(), ForegroundListener {
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
indicateServiceStopped()
|
||||||
indexingFragment.release()
|
indexingFragment.release()
|
||||||
mediaSessionFragment.release()
|
mediaSessionFragment.release()
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,12 +329,16 @@ class ExoPlaybackStateHolder(
|
||||||
|
|
||||||
val trueFrom = indices[from]
|
val trueFrom = indices[from]
|
||||||
val trueTo = indices[to]
|
val trueTo = indices[to]
|
||||||
|
// ExoPlayer does not actually update it's ShuffleOrder when moving items. Retain a
|
||||||
|
// semblance of "normalcy" by doing a weird no-op swap that actually moves the item.
|
||||||
when {
|
when {
|
||||||
trueFrom > trueTo -> {
|
trueFrom > trueTo -> {
|
||||||
player.moveMediaItem(trueFrom, trueTo)
|
player.moveMediaItem(trueFrom, trueTo)
|
||||||
|
player.moveMediaItem(trueTo + 1, trueFrom)
|
||||||
}
|
}
|
||||||
trueTo > trueFrom -> {
|
trueTo > trueFrom -> {
|
||||||
player.moveMediaItem(trueFrom, trueTo)
|
player.moveMediaItem(trueFrom, trueTo)
|
||||||
|
player.moveMediaItem(trueTo - 1, trueFrom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playbackManager.ack(this, ack)
|
playbackManager.ack(this, ack)
|
||||||
|
|
|
@ -52,6 +52,7 @@ import org.oxycblt.auxio.music.service.MediaItemBrowser
|
||||||
import org.oxycblt.auxio.playback.state.DeferredPlayback
|
import org.oxycblt.auxio.playback.state.DeferredPlayback
|
||||||
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
import org.oxycblt.auxio.util.newMainPendingIntent
|
||||||
|
|
||||||
class MediaSessionServiceFragment
|
class MediaSessionServiceFragment
|
||||||
@Inject
|
@Inject
|
||||||
|
@ -76,6 +77,11 @@ constructor(
|
||||||
.setNotificationId(IntegerTable.PLAYBACK_NOTIFICATION_CODE)
|
.setNotificationId(IntegerTable.PLAYBACK_NOTIFICATION_CODE)
|
||||||
.setChannelId(BuildConfig.APPLICATION_ID + ".channel.PLAYBACK")
|
.setChannelId(BuildConfig.APPLICATION_ID + ".channel.PLAYBACK")
|
||||||
.setChannelName(R.string.lbl_playback)
|
.setChannelName(R.string.lbl_playback)
|
||||||
|
.setPlayDrawableResourceId(R.drawable.ic_play_24)
|
||||||
|
.setPauseDrawableResourceId(R.drawable.ic_pause_24)
|
||||||
|
.setSkipNextDrawableResourceId(R.drawable.ic_skip_next_24)
|
||||||
|
.setSkipPrevDrawableResourceId(R.drawable.ic_skip_prev_24)
|
||||||
|
.setContentIntent(context.newMainPendingIntent())
|
||||||
.build()
|
.build()
|
||||||
.also { it.setSmallIcon(R.drawable.ic_auxio_24) }
|
.also { it.setSmallIcon(R.drawable.ic_auxio_24) }
|
||||||
private var foregroundListener: ForegroundListener? = null
|
private var foregroundListener: ForegroundListener? = null
|
||||||
|
|
|
@ -27,7 +27,6 @@ import android.os.Bundle
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.session.CommandButton
|
import androidx.media3.session.CommandButton
|
||||||
import androidx.media3.session.DefaultMediaNotificationProvider
|
|
||||||
import androidx.media3.session.SessionCommand
|
import androidx.media3.session.SessionCommand
|
||||||
import androidx.media3.session.SessionCommands
|
import androidx.media3.session.SessionCommands
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
@ -106,12 +105,6 @@ constructor(
|
||||||
.setSessionCommand(
|
.setSessionCommand(
|
||||||
SessionCommand(PlaybackActions.ACTION_INC_REPEAT_MODE, Bundle()))
|
SessionCommand(PlaybackActions.ACTION_INC_REPEAT_MODE, Bundle()))
|
||||||
.setEnabled(true)
|
.setEnabled(true)
|
||||||
.setExtras(
|
|
||||||
Bundle().apply {
|
|
||||||
putInt(
|
|
||||||
DefaultMediaNotificationProvider.COMMAND_KEY_COMPACT_VIEW_INDEX,
|
|
||||||
0)
|
|
||||||
})
|
|
||||||
.build())
|
.build())
|
||||||
}
|
}
|
||||||
ActionMode.SHUFFLE -> {
|
ActionMode.SHUFFLE -> {
|
||||||
|
@ -135,36 +128,6 @@ constructor(
|
||||||
.setDisplayName(context.getString(R.string.desc_skip_prev))
|
.setDisplayName(context.getString(R.string.desc_skip_prev))
|
||||||
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
|
.setPlayerCommand(Player.COMMAND_SEEK_TO_PREVIOUS)
|
||||||
.setEnabled(true)
|
.setEnabled(true)
|
||||||
.setExtras(
|
|
||||||
Bundle().apply {
|
|
||||||
putInt(DefaultMediaNotificationProvider.COMMAND_KEY_COMPACT_VIEW_INDEX, 1)
|
|
||||||
})
|
|
||||||
.build())
|
|
||||||
|
|
||||||
actions.add(
|
|
||||||
CommandButton.Builder()
|
|
||||||
.setIconResId(
|
|
||||||
if (playbackManager.progression.isPlaying) R.drawable.ic_pause_24
|
|
||||||
else R.drawable.ic_play_24)
|
|
||||||
.setDisplayName(context.getString(R.string.desc_play_pause))
|
|
||||||
.setPlayerCommand(Player.COMMAND_PLAY_PAUSE)
|
|
||||||
.setEnabled(true)
|
|
||||||
.setExtras(
|
|
||||||
Bundle().apply {
|
|
||||||
putInt(DefaultMediaNotificationProvider.COMMAND_KEY_COMPACT_VIEW_INDEX, 2)
|
|
||||||
})
|
|
||||||
.build())
|
|
||||||
|
|
||||||
actions.add(
|
|
||||||
CommandButton.Builder()
|
|
||||||
.setIconResId(R.drawable.ic_skip_next_24)
|
|
||||||
.setDisplayName(context.getString(R.string.desc_skip_next))
|
|
||||||
.setPlayerCommand(Player.COMMAND_SEEK_TO_NEXT)
|
|
||||||
.setEnabled(true)
|
|
||||||
.setExtras(
|
|
||||||
Bundle().apply {
|
|
||||||
putInt(DefaultMediaNotificationProvider.COMMAND_KEY_COMPACT_VIEW_INDEX, 3)
|
|
||||||
})
|
|
||||||
.build())
|
.build())
|
||||||
|
|
||||||
actions.add(
|
actions.add(
|
||||||
|
|
|
@ -68,9 +68,6 @@ class AboutFragment : ViewBindingFragment<FragmentAboutBinding>() {
|
||||||
binding.aboutLicenses.setOnClickListener { requireContext().openInBrowser(LINK_LICENSES) }
|
binding.aboutLicenses.setOnClickListener { requireContext().openInBrowser(LINK_LICENSES) }
|
||||||
binding.aboutProfile.setOnClickListener { requireContext().openInBrowser(LINK_PROFILE) }
|
binding.aboutProfile.setOnClickListener { requireContext().openInBrowser(LINK_PROFILE) }
|
||||||
binding.aboutDonate.setOnClickListener { requireContext().openInBrowser(LINK_DONATE) }
|
binding.aboutDonate.setOnClickListener { requireContext().openInBrowser(LINK_DONATE) }
|
||||||
binding.aboutSupporterYrliet.setOnClickListener {
|
|
||||||
requireContext().openInBrowser(LINK_YRLIET)
|
|
||||||
}
|
|
||||||
binding.aboutSupportersPromo.setOnClickListener {
|
binding.aboutSupportersPromo.setOnClickListener {
|
||||||
requireContext().openInBrowser(LINK_DONATE)
|
requireContext().openInBrowser(LINK_DONATE)
|
||||||
}
|
}
|
||||||
|
@ -100,6 +97,5 @@ class AboutFragment : ViewBindingFragment<FragmentAboutBinding>() {
|
||||||
const val LINK_LICENSES = "$LINK_WIKI/Licenses"
|
const val LINK_LICENSES = "$LINK_WIKI/Licenses"
|
||||||
const val LINK_PROFILE = "https://github.com/OxygenCobalt"
|
const val LINK_PROFILE = "https://github.com/OxygenCobalt"
|
||||||
const val LINK_DONATE = "https://github.com/sponsors/OxygenCobalt"
|
const val LINK_DONATE = "https://github.com/sponsors/OxygenCobalt"
|
||||||
const val LINK_YRLIET = "https://github.com/yrliet"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 Auxio Project
|
|
||||||
* Tasker.kt is part of Auxio.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oxycblt.auxio.tasker
|
|
5
app/src/main/res/drawable/ui_selection_bg.xml
Normal file
5
app/src/main/res/drawable/ui_selection_bg.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/sel_selection_bg" />
|
||||||
|
<item android:drawable="@drawable/ui_item_ripple" />
|
||||||
|
</layer-list>
|
|
@ -224,18 +224,6 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/about_supporter_yrliet"
|
|
||||||
style="@style/Widget.Auxio.TextView.Icon.Clickable"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/sup_yrliet"
|
|
||||||
app:drawableStartCompat="@drawable/ic_person_24"
|
|
||||||
app:drawableTint="?attr/colorControlNormal"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/about_licenses" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/about_supporters_promo"
|
android:id="@+id/about_supporters_promo"
|
||||||
style="@style/Widget.Auxio.TextView.Icon.Clickable"
|
style="@style/Widget.Auxio.TextView.Icon.Clickable"
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
android:id="@+id/interact_body"
|
android:id="@+id/interact_body"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/ui_item_ripple">
|
android:background="@drawable/ui_selection_bg">
|
||||||
|
|
||||||
<org.oxycblt.auxio.image.CoverView
|
<org.oxycblt.auxio.image.CoverView
|
||||||
android:id="@+id/song_album_cover"
|
android:id="@+id/song_album_cover"
|
||||||
|
|
|
@ -17,5 +17,4 @@
|
||||||
<string name="cdc_wav">Microsoft WAVE</string>
|
<string name="cdc_wav">Microsoft WAVE</string>
|
||||||
|
|
||||||
<!-- Supporter Namespace | Sponsor usernames -->
|
<!-- Supporter Namespace | Sponsor usernames -->
|
||||||
<string name="sup_yrliet">yrliet</string>
|
|
||||||
</resources>
|
</resources>
|
2
media
2
media
|
@ -1 +1 @@
|
||||||
Subproject commit 1d58171e16107d73ec3c842319663a8a06bfd23a
|
Subproject commit 00124cbac493c06a24e19b01893946bdaf8faf58
|
Loading…
Reference in a new issue