如何通过Spotify Android媒体通知API正确追踪播放位置?
Hey there, I've been dealing with the exact same issue lately—got Spotify's Android media notification metadata working and displaying correctly in my app, but hit a wall with the positionInMs extra. Like you said, it only comes through when there's a queue change, track switch, or playback state update. When a track is just playing steadily without any of those triggers, there's no way to get the current progress from the notification intent alone.
Here are a few solid workarounds I've tested that solve this:
1. Use MediaControllerCompat to Poll for Position
If you're already interacting with Spotify's media session, you can grab the MediaSessionCompat.Token tied to Spotify's player, then create a MediaControllerCompat to actively fetch the playback position on a timer. This gives you near-real-time updates without relying on intent extras.
Example code (Kotlin):
// First, get the Spotify media session token (you can retrieve this from the notification's media session info) val spotifyMediaSessionToken = // your token retrieval logic here val mediaController = MediaControllerCompat(context, spotifyMediaSessionToken) // Use a coroutine to poll every second CoroutineScope(Dispatchers.Main).launch { while (isActive) { val currentPosition = mediaController.playbackState?.position ?: 0L // Update your UI or store this position updatePlaybackPosition(currentPosition) delay(1000) } }
2. Calculate Position Locally Using Last Known Data
If you don't want to poll the system API constantly, you can calculate the current position using the last received positionInMs value, combined with the playback speed and elapsed time. This works great when playback is in a stable state:
private var lastKnownPositionMs = 0L private var lastUpdateTimestamp = System.currentTimeMillis() private var currentPlaybackSpeed = 1.0f // Call this when you receive the positionInMs extra from the intent fun onPositionReceived(positionMs: Long, playbackState: PlaybackStateCompat) { lastKnownPositionMs = positionMs lastUpdateTimestamp = System.currentTimeMillis() currentPlaybackSpeed = playbackState.playbackSpeed } // Calculate the current position at any time fun getCurrentPlaybackPosition(): Long { val playbackState = mediaController.playbackState ?: return lastKnownPositionMs if (playbackState.state != PlaybackStateCompat.STATE_PLAYING) { return lastKnownPositionMs } val elapsedTimeMs = System.currentTimeMillis() - lastUpdateTimestamp return lastKnownPositionMs + (elapsedTimeMs * currentPlaybackSpeed).toLong() }
This method is lightweight and avoids frequent system calls—perfect for apps where performance is a concern.
3. Use Spotify Player SDK's Direct Event Listener
If you're integrating directly with the Spotify Android Player SDK (not just relying on system notifications), you can use the Player.EventListener interface to get real-time position updates directly from the player:
spotifyPlayer.addPlayerEventListener(object : Player.EventListener { override fun onPlaybackPositionChanged(positionMs: Long) { // This callback fires constantly while playback is active, giving you the exact position updateUIWithPosition(positionMs) } // Implement other required listener methods as needed })
This is the most reliable method if you're using the full SDK, since it bypasses the system notification limitations entirely.
Hope one of these fixes works for you!
内容的提问来源于stack exchange,提问作者swellep

