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
|
||||
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -10,6 +12,8 @@ import android.net.NetworkRequest
|
||||
import android.os.Bundle
|
||||
import android.os.PowerManager
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import xyz.cottongin.radio247.R
|
||||
import com.google.common.util.concurrent.SettableFuture
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.MediaMetadata
|
||||
@@ -55,6 +59,8 @@ class ConnectionFailedException(cause: Throwable) : Exception("Connection failed
|
||||
class RadioPlaybackService : MediaLibraryService() {
|
||||
companion object {
|
||||
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_STOP = "xyz.cottongin.radio247.STOP"
|
||||
const val ACTION_PAUSE = "xyz.cottongin.radio247.PAUSE"
|
||||
@@ -118,6 +124,24 @@ class RadioPlaybackService : MediaLibraryService() {
|
||||
|
||||
override fun 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 {
|
||||
@@ -126,6 +150,7 @@ class RadioPlaybackService : MediaLibraryService() {
|
||||
ACTION_PLAY -> {
|
||||
val stationId = intent.getLongExtra(EXTRA_STATION_ID, -1L)
|
||||
if (stationId >= 0) {
|
||||
postPlaceholderForeground()
|
||||
launchPlay(stationId)
|
||||
} else {
|
||||
stopSelf()
|
||||
@@ -194,7 +219,6 @@ class RadioPlaybackService : MediaLibraryService() {
|
||||
}
|
||||
|
||||
acquireLocks()
|
||||
ensureMediaSession()
|
||||
playerAdapter?.updateStation(station)
|
||||
playerAdapter?.updatePlaybackState(PlaybackState.Connecting(station))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user