diff --git a/demos/session/src/main/java/androidx/media3/demo/session/PlaybackService.kt b/demos/session/src/main/java/androidx/media3/demo/session/PlaybackService.kt index 16ca1a25a5..b5ba86ab22 100644 --- a/demos/session/src/main/java/androidx/media3/demo/session/PlaybackService.kt +++ b/demos/session/src/main/java/androidx/media3/demo/session/PlaybackService.kt @@ -15,22 +15,22 @@ */ package androidx.media3.demo.session -import android.app.PendingIntent.FLAG_IMMUTABLE -import android.app.PendingIntent.FLAG_UPDATE_CURRENT +import android.app.Notification.BigTextStyle +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent.* import android.app.TaskStackBuilder import android.content.Intent import android.os.Build import android.os.Bundle +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat import androidx.media3.common.AudioAttributes import androidx.media3.common.MediaItem +import androidx.media3.common.util.Util import androidx.media3.exoplayer.ExoPlayer -import androidx.media3.session.CommandButton -import androidx.media3.session.LibraryResult -import androidx.media3.session.MediaLibraryService -import androidx.media3.session.MediaSession +import androidx.media3.session.* import androidx.media3.session.MediaSession.ControllerInfo -import androidx.media3.session.SessionCommand -import androidx.media3.session.SessionResult import com.google.common.collect.ImmutableList import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture @@ -51,6 +51,8 @@ class PlaybackService : MediaLibraryService() { "android.media3.session.demo.SHUFFLE_ON" private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF = "android.media3.session.demo.SHUFFLE_OFF" + private const val NOTIFICATION_ID = 123 + private const val CHANNEL_ID = "demo_session_notification_channel_id" } override fun onCreate() { @@ -66,6 +68,7 @@ class PlaybackService : MediaLibraryService() { ) customLayout = ImmutableList.of(customCommands[0]) initializeSessionAndPlayer() + setListener(MediaSessionServiceListener()) } override fun onGetSession(controllerInfo: ControllerInfo): MediaLibrarySession { @@ -81,6 +84,7 @@ class PlaybackService : MediaLibraryService() { override fun onDestroy() { player.release() mediaLibrarySession.release() + clearListener() super.onDestroy() } @@ -259,4 +263,54 @@ class PlaybackService : MediaLibraryService() { private fun ignoreFuture(customLayout: ListenableFuture) { /* Do nothing. */ } + + private inner class MediaSessionServiceListener : Listener { + + /** + * This method is only required to be implemented on Android 12 or above when an attempt is made + * by a media controller to resume playback when the {@link MediaSessionService} is in the + * background. + */ + override fun onForegroundServiceStartNotAllowedException() { + createNotificationAndNotify() + } + } + + private fun createNotificationAndNotify() { + var notificationManagerCompat = NotificationManagerCompat.from(this) + ensureNotificationChannel(notificationManagerCompat) + var pendingIntent = + TaskStackBuilder.create(this).run { + addNextIntent(Intent(this@PlaybackService, MainActivity::class.java)) + + val immutableFlag = if (Build.VERSION.SDK_INT >= 23) FLAG_IMMUTABLE else 0 + getPendingIntent(0, immutableFlag or FLAG_UPDATE_CURRENT) + } + + var builder = + NotificationCompat.Builder(this, CHANNEL_ID) + .setContentIntent(pendingIntent) + .setSmallIcon(R.drawable.media3_notification_small_icon) + .setContentTitle(getString(R.string.notification_content_title)) + .setStyle( + NotificationCompat.BigTextStyle().bigText(getString(R.string.notification_content_text)) + ) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setAutoCancel(true) + notificationManagerCompat.notify(NOTIFICATION_ID, builder.build()) + } + + private fun ensureNotificationChannel(notificationManagerCompat: NotificationManagerCompat) { + if (Util.SDK_INT < 26 || notificationManagerCompat.getNotificationChannel(CHANNEL_ID) != null) { + return + } + + val channel = + NotificationChannel( + CHANNEL_ID, + getString(R.string.notification_channel_name), + NotificationManager.IMPORTANCE_DEFAULT + ) + notificationManagerCompat.createNotificationChannel(channel) + } } diff --git a/demos/session/src/main/res/values/strings.xml b/demos/session/src/main/res/values/strings.xml index 727772e190..0add882c72 100644 --- a/demos/session/src/main/res/values/strings.xml +++ b/demos/session/src/main/res/values/strings.xml @@ -24,4 +24,9 @@ "! No media in the play list !\nPlease try to add more from browser" + Playback cannot be resumed + Press on the play button on the media notification if it + is still present, otherwise please open the app to start the playback and re-connect the session + to the controller + Playback cannot be resumed