fix(android): call startForeground() immediately to prevent ForegroundServiceDidNotStartInTimeException (#4453)

* fix: call startForeground() immediately in onStartCommand() to prevent ForegroundServiceDidNotStartInTimeException

* fix: use string resources for notification text instead of hardcoded strings

* fix: add missing import

* fix: resolve CI issues

* fix: use getString() method to convert string resource IDs to actual strings
This commit is contained in:
Marcin Dziewulski
2025-03-12 13:42:02 +01:00
committed by GitHub
parent f9d3878ecc
commit b5103743e8
2 changed files with 32 additions and 1 deletions
@@ -20,6 +20,7 @@ import androidx.media3.session.MediaSessionService
import androidx.media3.session.MediaStyleNotificationHelper
import androidx.media3.session.SessionCommand
import com.brentvatne.common.toolbox.DebugLog
import com.brentvatne.react.R
import okhttp3.internal.immutableListOf
class PlaybackServiceBinder(val service: VideoPlaybackService) : Binder()
@@ -63,7 +64,9 @@ class VideoPlaybackService : MediaSessionService() {
mediaSessionsList[player] = mediaSession
addSession(mediaSession)
startForeground(mediaSession.player.hashCode(), buildNotification(mediaSession))
val notificationId = player.hashCode()
startForeground(notificationId, buildNotification(mediaSession))
}
fun unregisterPlayer(player: ExoPlayer) {
@@ -224,7 +227,30 @@ class VideoPlaybackService : MediaSessionService() {
mediaSessionsList.clear()
}
private fun createPlaceholderNotification(): Notification {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationManager.createNotificationChannel(
NotificationChannel(
NOTIFICATION_CHANEL_ID,
NOTIFICATION_CHANEL_ID,
NotificationManager.IMPORTANCE_LOW
)
)
}
return NotificationCompat.Builder(this, NOTIFICATION_CHANEL_ID)
.setSmallIcon(androidx.media3.session.R.drawable.media3_icon_circular_play)
.setContentTitle(getString(R.string.media_playback_notification_title))
.setContentText(getString(R.string.media_playback_notification_text))
.build()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(PLACEHOLDER_NOTIFICATION_ID, createPlaceholderNotification())
}
intent?.let {
val playerId = it.getIntExtra("PLAYER_ID", -1)
val actionCommand = it.getStringExtra("ACTION")
@@ -249,6 +275,7 @@ class VideoPlaybackService : MediaSessionService() {
companion object {
private const val SEEK_INTERVAL_MS = 10000L
private const val TAG = "VideoPlaybackService"
private const val PLACEHOLDER_NOTIFICATION_ID = 9999
const val NOTIFICATION_CHANEL_ID = "RNVIDEO_SESSION_NOTIFICATION"
+4
View File
@@ -22,4 +22,8 @@
<string name="playback_speed">Playback Speed</string>
<string name="select_playback_speed">Select Playback Speed</string>
<string name="media_playback_notification_title">Media playback</string>
<string name="media_playback_notification_text">Preparing playback</string>
</resources>