mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
Merge pull request #9 from eddyizm/374-Spanish-translation
374 spanish translation
This commit is contained in:
commit
2a6d8509ff
6 changed files with 256 additions and 68 deletions
|
|
@ -11,7 +11,7 @@ android {
|
||||||
targetSdk 35
|
targetSdk 35
|
||||||
|
|
||||||
versionCode 26
|
versionCode 26
|
||||||
versionName '3.9.5'
|
versionName '3.9.6'
|
||||||
|
|
||||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ class MediaService : MediaLibraryService() {
|
||||||
|
|
||||||
private lateinit var player: ExoPlayer
|
private lateinit var player: ExoPlayer
|
||||||
private lateinit var mediaLibrarySession: MediaLibrarySession
|
private lateinit var mediaLibrarySession: MediaLibrarySession
|
||||||
private lateinit var customCommands: List<CommandButton>
|
private lateinit var shuffleCommands: List<CommandButton>
|
||||||
|
private lateinit var repeatCommands: List<CommandButton>
|
||||||
|
|
||||||
private var customLayout = ImmutableList.of<CommandButton>()
|
private var customLayout = ImmutableList.of<CommandButton>()
|
||||||
|
|
||||||
|
|
@ -41,6 +42,12 @@ class MediaService : MediaLibraryService() {
|
||||||
"android.media3.session.demo.SHUFFLE_ON"
|
"android.media3.session.demo.SHUFFLE_ON"
|
||||||
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
||||||
"android.media3.session.demo.SHUFFLE_OFF"
|
"android.media3.session.demo.SHUFFLE_OFF"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF =
|
||||||
|
"android.media3.session.demo.REPEAT_OFF"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE =
|
||||||
|
"android.media3.session.demo.REPEAT_ONE"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL =
|
||||||
|
"android.media3.session.demo.REPEAT_ALL"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
|
|
@ -72,7 +79,7 @@ class MediaService : MediaLibraryService() {
|
||||||
val connectionResult = super.onConnect(session, controller)
|
val connectionResult = super.onConnect(session, controller)
|
||||||
val availableSessionCommands = connectionResult.availableSessionCommands.buildUpon()
|
val availableSessionCommands = connectionResult.availableSessionCommands.buildUpon()
|
||||||
|
|
||||||
customCommands.forEach { commandButton ->
|
shuffleCommands.forEach { commandButton ->
|
||||||
// TODO: Aggiungere i comandi personalizzati
|
// TODO: Aggiungere i comandi personalizzati
|
||||||
// commandButton.sessionCommand?.let { availableSessionCommands.add(it) }
|
// commandButton.sessionCommand?.let { availableSessionCommands.add(it) }
|
||||||
}
|
}
|
||||||
|
|
@ -89,21 +96,39 @@ class MediaService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
|
||||||
|
val shuffle = shuffleCommands[if (player.shuffleModeEnabled) 1 else 0]
|
||||||
|
val repeat = when (player.repeatMode) {
|
||||||
|
Player.REPEAT_MODE_ONE -> repeatCommands[1]
|
||||||
|
Player.REPEAT_MODE_ALL -> repeatCommands[2]
|
||||||
|
else -> repeatCommands[0]
|
||||||
|
}
|
||||||
|
return ImmutableList.of(shuffle, repeat)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCustomCommand(
|
override fun onCustomCommand(
|
||||||
session: MediaSession,
|
session: MediaSession,
|
||||||
controller: ControllerInfo,
|
controller: ControllerInfo,
|
||||||
customCommand: SessionCommand,
|
customCommand: SessionCommand,
|
||||||
args: Bundle
|
args: Bundle
|
||||||
): ListenableFuture<SessionResult> {
|
): ListenableFuture<SessionResult> {
|
||||||
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
|
when (customCommand.customAction) {
|
||||||
player.shuffleModeEnabled = true
|
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> player.shuffleModeEnabled = true
|
||||||
customLayout = ImmutableList.of(customCommands[1])
|
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> player.shuffleModeEnabled = false
|
||||||
session.setCustomLayout(customLayout)
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF,
|
||||||
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
|
||||||
player.shuffleModeEnabled = false
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
|
||||||
customLayout = ImmutableList.of(customCommands[0])
|
val nextMode = when (player.repeatMode) {
|
||||||
session.setCustomLayout(customLayout)
|
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
|
||||||
|
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
|
||||||
|
else -> Player.REPEAT_MODE_OFF
|
||||||
}
|
}
|
||||||
|
player.repeatMode = nextMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customLayout = librarySessionCallback.buildCustomLayout(player)
|
||||||
|
session.setCustomLayout(customLayout)
|
||||||
|
|
||||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||||
}
|
}
|
||||||
|
|
@ -125,8 +150,7 @@ class MediaService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeCustomCommands() {
|
private fun initializeCustomCommands() {
|
||||||
customCommands =
|
shuffleCommands = listOf(
|
||||||
listOf(
|
|
||||||
getShuffleCommandButton(
|
getShuffleCommandButton(
|
||||||
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY)
|
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY)
|
||||||
),
|
),
|
||||||
|
|
@ -135,7 +159,19 @@ class MediaService : MediaLibraryService() {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
customLayout = ImmutableList.of(customCommands[0])
|
repeatCommands = listOf(
|
||||||
|
getRepeatCommandButton(
|
||||||
|
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY)
|
||||||
|
),
|
||||||
|
getRepeatCommandButton(
|
||||||
|
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY)
|
||||||
|
),
|
||||||
|
getRepeatCommandButton(
|
||||||
|
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
customLayout = ImmutableList.of(shuffleCommands[0], repeatCommands[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializePlayer() {
|
private fun initializePlayer() {
|
||||||
|
|
@ -147,6 +183,9 @@ class MediaService : MediaLibraryService() {
|
||||||
.setWakeMode(C.WAKE_MODE_NETWORK)
|
.setWakeMode(C.WAKE_MODE_NETWORK)
|
||||||
.setLoadControl(initializeLoadControl())
|
.setLoadControl(initializeLoadControl())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
|
||||||
|
player.repeatMode = Preferences.getRepeatMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeMediaLibrarySession() {
|
private fun initializeMediaLibrarySession() {
|
||||||
|
|
@ -224,6 +263,18 @@ class MediaService : MediaLibraryService() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
||||||
|
Preferences.setShuffleModeEnabled(shuffleModeEnabled)
|
||||||
|
customLayout = librarySessionCallback.buildCustomLayout(player)
|
||||||
|
mediaLibrarySession.setCustomLayout(customLayout)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||||
|
Preferences.setRepeatMode(repeatMode)
|
||||||
|
customLayout = librarySessionCallback.buildCustomLayout(player)
|
||||||
|
mediaLibrarySession.setCustomLayout(customLayout)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,6 +302,25 @@ class MediaService : MediaLibraryService() {
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("PrivateResource")
|
||||||
|
private fun getRepeatCommandButton(sessionCommand: SessionCommand): CommandButton {
|
||||||
|
val icon = when (sessionCommand.customAction) {
|
||||||
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> R.drawable.exo_icon_repeat_one
|
||||||
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL -> R.drawable.exo_icon_repeat_all
|
||||||
|
else -> R.drawable.exo_icon_repeat_off
|
||||||
|
}
|
||||||
|
val description = when (sessionCommand.customAction) {
|
||||||
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> R.string.exo_controls_repeat_one_description
|
||||||
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL -> R.string.exo_controls_repeat_all_description
|
||||||
|
else -> R.string.exo_controls_repeat_off_description
|
||||||
|
}
|
||||||
|
return CommandButton.Builder()
|
||||||
|
.setDisplayName(getString(description))
|
||||||
|
.setSessionCommand(sessionCommand)
|
||||||
|
.setIconResId(icon)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
private fun ignoreFuture(customLayout: ListenableFuture<SessionResult>) {
|
private fun ignoreFuture(customLayout: ListenableFuture<SessionResult>) {
|
||||||
/* Do nothing. */
|
/* Do nothing. */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.session.CommandButton
|
import androidx.media3.session.CommandButton
|
||||||
import androidx.media3.session.LibraryResult
|
import androidx.media3.session.LibraryResult
|
||||||
|
|
@ -27,7 +28,7 @@ open class MediaLibrarySessionCallback(
|
||||||
MediaBrowserTree.initialize(automotiveRepository)
|
MediaBrowserTree.initialize(automotiveRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val customLayoutCommandButtons: List<CommandButton> = listOf(
|
private val shuffleCommandButtons: List<CommandButton> = listOf(
|
||||||
CommandButton.Builder()
|
CommandButton.Builder()
|
||||||
.setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description))
|
.setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description))
|
||||||
.setSessionCommand(
|
.setSessionCommand(
|
||||||
|
|
@ -45,15 +46,46 @@ open class MediaLibrarySessionCallback(
|
||||||
).setIconResId(R.drawable.exo_icon_shuffle_on).build()
|
).setIconResId(R.drawable.exo_icon_shuffle_on).build()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val repeatCommandButtons: List<CommandButton> = listOf(
|
||||||
|
CommandButton.Builder()
|
||||||
|
.setDisplayName(context.getString(R.string.exo_controls_repeat_off_description))
|
||||||
|
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY))
|
||||||
|
.setIconResId(R.drawable.exo_icon_repeat_off)
|
||||||
|
.build(),
|
||||||
|
CommandButton.Builder()
|
||||||
|
.setDisplayName(context.getString(R.string.exo_controls_repeat_one_description))
|
||||||
|
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY))
|
||||||
|
.setIconResId(R.drawable.exo_icon_repeat_one)
|
||||||
|
.build(),
|
||||||
|
CommandButton.Builder()
|
||||||
|
.setDisplayName(context.getString(R.string.exo_controls_repeat_all_description))
|
||||||
|
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY))
|
||||||
|
.setIconResId(R.drawable.exo_icon_repeat_all)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
private val customLayoutCommandButtons: List<CommandButton> =
|
||||||
|
shuffleCommandButtons + repeatCommandButtons
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
val mediaNotificationSessionCommands =
|
val mediaNotificationSessionCommands =
|
||||||
MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
|
MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
|
||||||
.also { builder ->
|
.also { builder ->
|
||||||
customLayoutCommandButtons.forEach { commandButton ->
|
(shuffleCommandButtons + repeatCommandButtons).forEach { commandButton ->
|
||||||
commandButton.sessionCommand?.let { builder.add(it) }
|
commandButton.sessionCommand?.let { builder.add(it) }
|
||||||
}
|
}
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
|
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
|
||||||
|
val shuffle = shuffleCommandButtons[if (player.shuffleModeEnabled) 1 else 0]
|
||||||
|
val repeat = when (player.repeatMode) {
|
||||||
|
Player.REPEAT_MODE_ONE -> repeatCommandButtons[1]
|
||||||
|
Player.REPEAT_MODE_ALL -> repeatCommandButtons[2]
|
||||||
|
else -> repeatCommandButtons[0]
|
||||||
|
}
|
||||||
|
return ImmutableList.of(shuffle, repeat)
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
override fun onConnect(
|
override fun onConnect(
|
||||||
session: MediaSession, controller: MediaSession.ControllerInfo
|
session: MediaSession, controller: MediaSession.ControllerInfo
|
||||||
|
|
@ -62,12 +94,11 @@ open class MediaLibrarySessionCallback(
|
||||||
controller
|
controller
|
||||||
) || session.isAutoCompanionController(controller)
|
) || session.isAutoCompanionController(controller)
|
||||||
) {
|
) {
|
||||||
val customLayout =
|
val customLayout = buildCustomLayout(session.player)
|
||||||
customLayoutCommandButtons[if (session.player.shuffleModeEnabled) 1 else 0]
|
|
||||||
|
|
||||||
return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
|
return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
|
||||||
.setAvailableSessionCommands(mediaNotificationSessionCommands)
|
.setAvailableSessionCommands(mediaNotificationSessionCommands)
|
||||||
.setCustomLayout(ImmutableList.of(customLayout)).build()
|
.setCustomLayout(customLayout).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build()
|
return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build()
|
||||||
|
|
@ -80,25 +111,28 @@ open class MediaLibrarySessionCallback(
|
||||||
customCommand: SessionCommand,
|
customCommand: SessionCommand,
|
||||||
args: Bundle
|
args: Bundle
|
||||||
): ListenableFuture<SessionResult> {
|
): ListenableFuture<SessionResult> {
|
||||||
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
|
when (customCommand.customAction) {
|
||||||
session.player.shuffleModeEnabled = true
|
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> session.player.shuffleModeEnabled = true
|
||||||
session.setCustomLayout(
|
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> session.player.shuffleModeEnabled = false
|
||||||
session.mediaNotificationControllerInfo!!,
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF,
|
||||||
ImmutableList.of(customLayoutCommandButtons[1])
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
|
||||||
)
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
|
||||||
|
val nextMode = when (session.player.repeatMode) {
|
||||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
|
||||||
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
|
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
|
||||||
session.player.shuffleModeEnabled = false
|
else -> Player.REPEAT_MODE_OFF
|
||||||
session.setCustomLayout(
|
}
|
||||||
session.mediaNotificationControllerInfo!!,
|
session.player.repeatMode = nextMode
|
||||||
ImmutableList.of(customLayoutCommandButtons[0])
|
}
|
||||||
)
|
else -> return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
|
||||||
|
|
||||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
|
session.setCustomLayout(
|
||||||
|
session.mediaNotificationControllerInfo!!,
|
||||||
|
buildCustomLayout(session.player)
|
||||||
|
)
|
||||||
|
|
||||||
|
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onGetLibraryRoot(
|
override fun onGetLibraryRoot(
|
||||||
|
|
@ -158,5 +192,11 @@ open class MediaLibrarySessionCallback(
|
||||||
"android.media3.session.demo.SHUFFLE_ON"
|
"android.media3.session.demo.SHUFFLE_ON"
|
||||||
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
||||||
"android.media3.session.demo.SHUFFLE_OFF"
|
"android.media3.session.demo.SHUFFLE_OFF"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF =
|
||||||
|
"android.media3.session.demo.REPEAT_OFF"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE =
|
||||||
|
"android.media3.session.demo.REPEAT_ONE"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL =
|
||||||
|
"android.media3.session.demo.REPEAT_ALL"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,6 +33,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
private lateinit var player: ExoPlayer
|
private lateinit var player: ExoPlayer
|
||||||
private lateinit var castPlayer: CastPlayer
|
private lateinit var castPlayer: CastPlayer
|
||||||
private lateinit var mediaLibrarySession: MediaLibrarySession
|
private lateinit var mediaLibrarySession: MediaLibrarySession
|
||||||
|
private lateinit var librarySessionCallback: MediaLibrarySessionCallback
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
@ -79,6 +80,9 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
.setWakeMode(C.WAKE_MODE_NETWORK)
|
.setWakeMode(C.WAKE_MODE_NETWORK)
|
||||||
.setLoadControl(initializeLoadControl())
|
.setLoadControl(initializeLoadControl())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
|
||||||
|
player.repeatMode = Preferences.getRepeatMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeCastPlayer() {
|
private fun initializeCastPlayer() {
|
||||||
|
|
@ -97,13 +101,14 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
|
getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
librarySessionCallback = createLibrarySessionCallback()
|
||||||
mediaLibrarySession =
|
mediaLibrarySession =
|
||||||
MediaLibrarySession.Builder(this, player, createLibrarySessionCallback())
|
MediaLibrarySession.Builder(this, player, librarySessionCallback)
|
||||||
.setSessionActivity(sessionActivityPendingIntent)
|
.setSessionActivity(sessionActivityPendingIntent)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLibrarySessionCallback(): MediaLibrarySession.Callback {
|
private fun createLibrarySessionCallback(): MediaLibrarySessionCallback {
|
||||||
return MediaLibrarySessionCallback(this, automotiveRepository)
|
return MediaLibrarySessionCallback(this, automotiveRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,6 +171,20 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
||||||
|
Preferences.setShuffleModeEnabled(shuffleModeEnabled)
|
||||||
|
mediaLibrarySession.setCustomLayout(
|
||||||
|
librarySessionCallback.buildCustomLayout(player)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||||
|
Preferences.setRepeatMode(repeatMode)
|
||||||
|
mediaLibrarySession.setCustomLayout(
|
||||||
|
librarySessionCallback.buildCustomLayout(player)
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.session.CommandButton
|
import androidx.media3.session.CommandButton
|
||||||
import androidx.media3.session.LibraryResult
|
import androidx.media3.session.LibraryResult
|
||||||
|
|
@ -27,7 +28,7 @@ open class MediaLibrarySessionCallback(
|
||||||
MediaBrowserTree.initialize(automotiveRepository)
|
MediaBrowserTree.initialize(automotiveRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val customLayoutCommandButtons: List<CommandButton> = listOf(
|
private val shuffleCommandButtons: List<CommandButton> = listOf(
|
||||||
CommandButton.Builder()
|
CommandButton.Builder()
|
||||||
.setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description))
|
.setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description))
|
||||||
.setSessionCommand(
|
.setSessionCommand(
|
||||||
|
|
@ -45,15 +46,46 @@ open class MediaLibrarySessionCallback(
|
||||||
).setIconResId(R.drawable.exo_icon_shuffle_on).build()
|
).setIconResId(R.drawable.exo_icon_shuffle_on).build()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val repeatCommandButtons: List<CommandButton> = listOf(
|
||||||
|
CommandButton.Builder()
|
||||||
|
.setDisplayName(context.getString(R.string.exo_controls_repeat_off_description))
|
||||||
|
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY))
|
||||||
|
.setIconResId(R.drawable.exo_icon_repeat_off)
|
||||||
|
.build(),
|
||||||
|
CommandButton.Builder()
|
||||||
|
.setDisplayName(context.getString(R.string.exo_controls_repeat_one_description))
|
||||||
|
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY))
|
||||||
|
.setIconResId(R.drawable.exo_icon_repeat_one)
|
||||||
|
.build(),
|
||||||
|
CommandButton.Builder()
|
||||||
|
.setDisplayName(context.getString(R.string.exo_controls_repeat_all_description))
|
||||||
|
.setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY))
|
||||||
|
.setIconResId(R.drawable.exo_icon_repeat_all)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
private val customLayoutCommandButtons: List<CommandButton> =
|
||||||
|
shuffleCommandButtons + repeatCommandButtons
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
val mediaNotificationSessionCommands =
|
val mediaNotificationSessionCommands =
|
||||||
MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
|
MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
|
||||||
.also { builder ->
|
.also { builder ->
|
||||||
customLayoutCommandButtons.forEach { commandButton ->
|
(shuffleCommandButtons + repeatCommandButtons).forEach { commandButton ->
|
||||||
commandButton.sessionCommand?.let { builder.add(it) }
|
commandButton.sessionCommand?.let { builder.add(it) }
|
||||||
}
|
}
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
|
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
|
||||||
|
val shuffle = shuffleCommandButtons[if (player.shuffleModeEnabled) 1 else 0]
|
||||||
|
val repeat = when (player.repeatMode) {
|
||||||
|
Player.REPEAT_MODE_ONE -> repeatCommandButtons[1]
|
||||||
|
Player.REPEAT_MODE_ALL -> repeatCommandButtons[2]
|
||||||
|
else -> repeatCommandButtons[0]
|
||||||
|
}
|
||||||
|
return ImmutableList.of(shuffle, repeat)
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
override fun onConnect(
|
override fun onConnect(
|
||||||
session: MediaSession, controller: MediaSession.ControllerInfo
|
session: MediaSession, controller: MediaSession.ControllerInfo
|
||||||
|
|
@ -62,12 +94,11 @@ open class MediaLibrarySessionCallback(
|
||||||
controller
|
controller
|
||||||
) || session.isAutoCompanionController(controller)
|
) || session.isAutoCompanionController(controller)
|
||||||
) {
|
) {
|
||||||
val customLayout =
|
val customLayout = buildCustomLayout(session.player)
|
||||||
customLayoutCommandButtons[if (session.player.shuffleModeEnabled) 1 else 0]
|
|
||||||
|
|
||||||
return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
|
return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
|
||||||
.setAvailableSessionCommands(mediaNotificationSessionCommands)
|
.setAvailableSessionCommands(mediaNotificationSessionCommands)
|
||||||
.setCustomLayout(ImmutableList.of(customLayout)).build()
|
.setCustomLayout(customLayout).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build()
|
return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build()
|
||||||
|
|
@ -80,25 +111,28 @@ open class MediaLibrarySessionCallback(
|
||||||
customCommand: SessionCommand,
|
customCommand: SessionCommand,
|
||||||
args: Bundle
|
args: Bundle
|
||||||
): ListenableFuture<SessionResult> {
|
): ListenableFuture<SessionResult> {
|
||||||
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
|
when (customCommand.customAction) {
|
||||||
session.player.shuffleModeEnabled = true
|
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> session.player.shuffleModeEnabled = true
|
||||||
session.setCustomLayout(
|
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> session.player.shuffleModeEnabled = false
|
||||||
session.mediaNotificationControllerInfo!!,
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF,
|
||||||
ImmutableList.of(customLayoutCommandButtons[1])
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
|
||||||
)
|
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
|
||||||
|
val nextMode = when (session.player.repeatMode) {
|
||||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
|
||||||
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
|
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
|
||||||
session.player.shuffleModeEnabled = false
|
else -> Player.REPEAT_MODE_OFF
|
||||||
session.setCustomLayout(
|
}
|
||||||
session.mediaNotificationControllerInfo!!,
|
session.player.repeatMode = nextMode
|
||||||
ImmutableList.of(customLayoutCommandButtons[0])
|
}
|
||||||
)
|
else -> return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
|
||||||
|
|
||||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
|
session.setCustomLayout(
|
||||||
|
session.mediaNotificationControllerInfo!!,
|
||||||
|
buildCustomLayout(session.player)
|
||||||
|
)
|
||||||
|
|
||||||
|
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onGetLibraryRoot(
|
override fun onGetLibraryRoot(
|
||||||
|
|
@ -158,5 +192,11 @@ open class MediaLibrarySessionCallback(
|
||||||
"android.media3.session.demo.SHUFFLE_ON"
|
"android.media3.session.demo.SHUFFLE_ON"
|
||||||
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF =
|
||||||
"android.media3.session.demo.SHUFFLE_OFF"
|
"android.media3.session.demo.SHUFFLE_OFF"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF =
|
||||||
|
"android.media3.session.demo.REPEAT_OFF"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE =
|
||||||
|
"android.media3.session.demo.REPEAT_ONE"
|
||||||
|
private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL =
|
||||||
|
"android.media3.session.demo.REPEAT_ALL"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,6 +33,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
private lateinit var player: ExoPlayer
|
private lateinit var player: ExoPlayer
|
||||||
private lateinit var castPlayer: CastPlayer
|
private lateinit var castPlayer: CastPlayer
|
||||||
private lateinit var mediaLibrarySession: MediaLibrarySession
|
private lateinit var mediaLibrarySession: MediaLibrarySession
|
||||||
|
private lateinit var librarySessionCallback: MediaLibrarySessionCallback
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
@ -79,6 +80,9 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
.setWakeMode(C.WAKE_MODE_NETWORK)
|
.setWakeMode(C.WAKE_MODE_NETWORK)
|
||||||
.setLoadControl(initializeLoadControl())
|
.setLoadControl(initializeLoadControl())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
|
||||||
|
player.repeatMode = Preferences.getRepeatMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeCastPlayer() {
|
private fun initializeCastPlayer() {
|
||||||
|
|
@ -97,13 +101,14 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
|
getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
librarySessionCallback = createLibrarySessionCallback()
|
||||||
mediaLibrarySession =
|
mediaLibrarySession =
|
||||||
MediaLibrarySession.Builder(this, player, createLibrarySessionCallback())
|
MediaLibrarySession.Builder(this, player, librarySessionCallback)
|
||||||
.setSessionActivity(sessionActivityPendingIntent)
|
.setSessionActivity(sessionActivityPendingIntent)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLibrarySessionCallback(): MediaLibrarySession.Callback {
|
private fun createLibrarySessionCallback(): MediaLibrarySessionCallback {
|
||||||
return MediaLibrarySessionCallback(this, automotiveRepository)
|
return MediaLibrarySessionCallback(this, automotiveRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,6 +171,20 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
||||||
|
Preferences.setShuffleModeEnabled(shuffleModeEnabled)
|
||||||
|
mediaLibrarySession.setCustomLayout(
|
||||||
|
librarySessionCallback.buildCustomLayout(player)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||||
|
Preferences.setRepeatMode(repeatMode)
|
||||||
|
mediaLibrarySession.setCustomLayout(
|
||||||
|
librarySessionCallback.buildCustomLayout(player)
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue