Skip to content

Commit

Permalink
WIP: Trying to set custom layout in the Media3 notification
Browse files Browse the repository at this point in the history
Signed-off-by: Gabriel Fontán <[email protected]>
  • Loading branch information
BobbyESP committed May 5, 2024
1 parent 24d881f commit bd46026
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import com.bobbyesp.mediaplayer.service.ConnectionHandler
import com.bobbyesp.mediaplayer.service.MediaLibrarySessionCallback
import com.bobbyesp.mediaplayer.service.MediaServiceHandler
import com.bobbyesp.mediaplayer.service.notifications.MediaNotificationManager
import com.bobbyesp.mediaplayer.service.notifications.customLayout.MediaSessionLayoutHandler
import com.bobbyesp.mediaplayer.service.notifications.customLayout.MediaSessionLayoutHandlerImpl
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand Down Expand Up @@ -90,4 +92,13 @@ object MediaPlayerModule {
@Provides
@Singleton
fun provideConnectionHandler(): ConnectionHandler = ConnectionHandler()

@Provides
@Singleton
fun provideMediaSessionLayoutHandler(
@ApplicationContext context: Context,
mediaLibrarySessionCallback: MediaLibrarySessionCallback,
mediaLibrarySession: MediaLibrarySession
): MediaSessionLayoutHandler =
MediaSessionLayoutHandlerImpl(context, mediaLibrarySession, mediaLibrarySessionCallback)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,40 @@ package com.bobbyesp.mediaplayer.service
import android.content.Intent
import android.os.Binder
import androidx.media3.common.Player
import androidx.media3.common.Player.REPEAT_MODE_ALL
import androidx.media3.common.Player.REPEAT_MODE_OFF
import androidx.media3.common.Player.REPEAT_MODE_ONE
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.CommandButton
import androidx.media3.session.MediaController
import androidx.media3.session.MediaLibraryService
import androidx.media3.session.MediaSession
import com.bobbyesp.mediaplayer.R
import com.bobbyesp.mediaplayer.service.MediaServiceHandler.Companion.CommandToggleRepeatMode
import com.bobbyesp.mediaplayer.service.MediaServiceHandler.Companion.CommandToggleShuffle
import com.bobbyesp.mediaplayer.service.notifications.MediaNotificationManager
import com.bobbyesp.mediaplayer.service.notifications.customLayout.MediaSessionLayoutHandler
import com.google.common.collect.ImmutableList
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

@UnstableApi
@AndroidEntryPoint
class MediaplayerService : MediaLibraryService(), MediaSessionLayoutHandler {
class MediaplayerService : MediaLibraryService(), MediaController.Listener {
@Inject
lateinit var mediaSession: MediaLibrarySession

@Inject
lateinit var notificationManager: MediaNotificationManager
lateinit var mediaServiceHandler: MediaServiceHandler

@Inject
lateinit var connectionHandler: ConnectionHandler
lateinit var notificationManager: MediaNotificationManager

@Inject
lateinit var mediaServiceHandler: MediaServiceHandler
lateinit var mediaSessionLayoutHandler: MediaSessionLayoutHandler

override fun updateNotificationLayout() {
val commandButtons = ImmutableList.of<CommandButton>(
CommandButton.Builder()
.setDisplayName(getString(if (mediaSession.player.shuffleModeEnabled) R.string.action_shuffle_on else R.string.action_shuffle_off))
.setIconResId(if (mediaSession.player.shuffleModeEnabled) R.drawable.shuffle_on else R.drawable.shuffle)
.setSessionCommand(CommandToggleShuffle).build(),
CommandButton.Builder()
.setDisplayName(
getString(
when (mediaSession.player.repeatMode) {
REPEAT_MODE_OFF -> R.string.repeat_mode_off
REPEAT_MODE_ONE -> R.string.repeat_mode_one
REPEAT_MODE_ALL -> R.string.repeat_mode_all
else -> throw IllegalStateException()
}
)
).setIconResId(
when (mediaSession.player.repeatMode) {
REPEAT_MODE_OFF -> R.drawable.repeat
REPEAT_MODE_ONE -> R.drawable.repeat_one_on
REPEAT_MODE_ALL -> R.drawable.repeat_on
else -> throw IllegalStateException()
}
).setSessionCommand(CommandToggleRepeatMode).build()
)
mediaSession.setCustomLayout(commandButtons)
}
@Inject
lateinit var connectionHandler: ConnectionHandler

@UnstableApi
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
connectionHandler.connect(mediaServiceHandler)
notificationManager.startNotificationService(
mediaSessionService = this, mediaSession = mediaSession
)
mediaServiceHandler.setMediaSessionInterface(this)
mediaServiceHandler.setMediaSessionInterface(mediaSessionLayoutHandler)
return super.onStartCommand(intent, flags, startId)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.bobbyesp.mediaplayer.service.notifications.customLayout

import android.content.Context
import androidx.core.content.ContextCompat.getString
import androidx.media3.common.Player.REPEAT_MODE_ALL
import androidx.media3.common.Player.REPEAT_MODE_OFF
import androidx.media3.common.Player.REPEAT_MODE_ONE
import androidx.media3.session.CommandButton
import androidx.media3.session.MediaLibraryService
import com.bobbyesp.mediaplayer.R
import com.bobbyesp.mediaplayer.service.MediaLibrarySessionCallback
import com.bobbyesp.mediaplayer.service.MediaServiceHandler.Companion.CommandToggleRepeatMode
import com.bobbyesp.mediaplayer.service.MediaServiceHandler.Companion.CommandToggleShuffle
import com.google.common.collect.ImmutableList
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

class MediaSessionLayoutHandlerImpl @Inject constructor(
@ApplicationContext private val context: Context,
private val mediaSession: MediaLibraryService.MediaLibrarySession,
private val mediaSessionCallback: MediaLibrarySessionCallback
) : MediaSessionLayoutHandler {

val commandButtons = ImmutableList.of<CommandButton>(
CommandButton.Builder()
.setDisplayName(
getString(
context,
if (mediaSession.player.shuffleModeEnabled) R.string.action_shuffle_on else R.string.action_shuffle_off
)
)
.setIconResId(if (mediaSession.player.shuffleModeEnabled) R.drawable.shuffle_on else R.drawable.shuffle)
.setSessionCommand(CommandToggleShuffle).build(),
CommandButton.Builder()
.setDisplayName(
getString(
context,
when (mediaSession.player.repeatMode) {
REPEAT_MODE_OFF -> R.string.repeat_mode_off
REPEAT_MODE_ONE -> R.string.repeat_mode_one
REPEAT_MODE_ALL -> R.string.repeat_mode_all
else -> throw IllegalStateException()
}
)
).setIconResId(
when (mediaSession.player.repeatMode) {
REPEAT_MODE_OFF -> R.drawable.repeat
REPEAT_MODE_ONE -> R.drawable.repeat_one_on
REPEAT_MODE_ALL -> R.drawable.repeat_on
else -> throw IllegalStateException()
}
).setSessionCommand(CommandToggleRepeatMode).build()
)

override fun updateNotificationLayout() {
mediaSession.setCustomLayout(commandButtons)
}
}
6 changes: 6 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<queries>
<intent>
<action android:name="android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL" />
</intent>
</queries>
<application
android:name=".App"
android:allowBackup="true"
Expand Down

0 comments on commit bd46026

Please sign in to comment.