fix: post placeholder foreground notification immediately on play
startForegroundService() requires startForeground() within ~5 seconds. The async coroutine (DB queries, old job join) delayed the Media3 notification pipeline past this deadline. Now we: - Create the media session in onCreate() instead of lazily - Post a minimal "Connecting…" notification synchronously in onStartCommand before launching the async play coroutine - Media3 replaces it with the proper media notification once the adapter state updates to Playing Made-with: Cursor
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package xyz.cottongin.radio247.service
|
package xyz.cottongin.radio247.service
|
||||||
|
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -10,6 +12,8 @@ import android.net.NetworkRequest
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import xyz.cottongin.radio247.R
|
||||||
import com.google.common.util.concurrent.SettableFuture
|
import com.google.common.util.concurrent.SettableFuture
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.MediaMetadata
|
import androidx.media3.common.MediaMetadata
|
||||||
@@ -55,6 +59,8 @@ class ConnectionFailedException(cause: Throwable) : Exception("Connection failed
|
|||||||
class RadioPlaybackService : MediaLibraryService() {
|
class RadioPlaybackService : MediaLibraryService() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "RadioPlayback"
|
private const val TAG = "RadioPlayback"
|
||||||
|
private const val FOREGROUND_CHANNEL_ID = "radio_playback"
|
||||||
|
private const val FOREGROUND_NOTIFICATION_ID = 1
|
||||||
const val ACTION_PLAY = "xyz.cottongin.radio247.PLAY"
|
const val ACTION_PLAY = "xyz.cottongin.radio247.PLAY"
|
||||||
const val ACTION_STOP = "xyz.cottongin.radio247.STOP"
|
const val ACTION_STOP = "xyz.cottongin.radio247.STOP"
|
||||||
const val ACTION_PAUSE = "xyz.cottongin.radio247.PAUSE"
|
const val ACTION_PAUSE = "xyz.cottongin.radio247.PAUSE"
|
||||||
@@ -118,6 +124,24 @@ class RadioPlaybackService : MediaLibraryService() {
|
|||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
ensureForegroundChannel()
|
||||||
|
ensureMediaSession()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ensureForegroundChannel() {
|
||||||
|
val channel = NotificationChannel(
|
||||||
|
FOREGROUND_CHANNEL_ID, "Radio Playback", NotificationManager.IMPORTANCE_LOW
|
||||||
|
)
|
||||||
|
getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun postPlaceholderForeground() {
|
||||||
|
val notification = NotificationCompat.Builder(this, FOREGROUND_CHANNEL_ID)
|
||||||
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.setContentTitle("Connecting…")
|
||||||
|
.setSilent(true)
|
||||||
|
.build()
|
||||||
|
startForeground(FOREGROUND_NOTIFICATION_ID, notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
@@ -126,6 +150,7 @@ class RadioPlaybackService : MediaLibraryService() {
|
|||||||
ACTION_PLAY -> {
|
ACTION_PLAY -> {
|
||||||
val stationId = intent.getLongExtra(EXTRA_STATION_ID, -1L)
|
val stationId = intent.getLongExtra(EXTRA_STATION_ID, -1L)
|
||||||
if (stationId >= 0) {
|
if (stationId >= 0) {
|
||||||
|
postPlaceholderForeground()
|
||||||
launchPlay(stationId)
|
launchPlay(stationId)
|
||||||
} else {
|
} else {
|
||||||
stopSelf()
|
stopSelf()
|
||||||
@@ -194,7 +219,6 @@ class RadioPlaybackService : MediaLibraryService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
acquireLocks()
|
acquireLocks()
|
||||||
ensureMediaSession()
|
|
||||||
playerAdapter?.updateStation(station)
|
playerAdapter?.updateStation(station)
|
||||||
playerAdapter?.updatePlaybackState(PlaybackState.Connecting(station))
|
playerAdapter?.updatePlaybackState(PlaybackState.Connecting(station))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user