ISSUE Like/Shuffle/Repeat in HyperOS Control Center
Message:
Adding to this request with a technical breakdown for the Android development team. These extended playback controls (Like, Shuffle, Repeat) used to show up on MIUI, and still worked fine through HyperOS 1 and HyperOS 2 — they only disappeared later. Since the OS-side rendering didn't change, this points to a Spotify-side regression in how the Android media notification session is built, not a Xiaomi restriction or OS allow-listing.
HyperOS's player widget simply renders whatever actions the application's MediaStyle notification declares. The native Android API (NotificationCompat.MediaStyle or Media3's MediaLibraryService) natively supports up to 5 actions. However, Spotify only populates the 3 basic transport controls (Previous, Play/Pause, Next), leaving the 2 extra available slots empty.
Other major music apps (YouTube Music, Deezer) and open-source Android players — like N-Zik my app, an open-source YouTube Music client — expose these actions perfectly on the exact same HyperOS 3 builds because they fully utilize the standard Android APIs.
The Technical Proof (How to fix it):
If Spotify is using androidx.media3, the fix is trivial. You just need to ensure your MediaSession custom layout or your MediaNotificationProvider returns all 5 actions, and correctly maps the compact view indices.
// Example using Media3's DefaultMediaNotificationProvider
class SpotifyMediaNotificationProvider(context: Context) : DefaultMediaNotificationProvider(context) {
override fun getMediaButtons(
session: MediaSession,
playerCommands: Player.Commands,
customLayout: ImmutableList<CommandButton>,
showInCompactView: Boolean
): ImmutableList<CommandButton> {
val likeButton = CommandButton.Builder()
.setDisplayName("Like")
.setIconResId(R.drawable.ic_heart)
.setSessionCommand(SessionCommand("ACTION_LIKE", Bundle.EMPTY))
.build()
val shuffleButton = CommandButton.Builder()
.setDisplayName("Shuffle")
.setIconResId(R.drawable.ic_shuffle)
.setSessionCommand(SessionCommand("ACTION_SHUFFLE", Bundle.EMPTY))
.build()
if (showInCompactView) {
return ImmutableList.of(
getStandardAction(COMMAND_SEEK_TO_PREVIOUS),
getStandardAction(COMMAND_PLAY_PAUSE),
getStandardAction(COMMAND_SEEK_TO_NEXT)
)
}
return ImmutableList.of(
likeButton,
getStandardAction(COMMAND_SEEK_TO_PREVIOUS),
getStandardAction(COMMAND_PLAY_PAUSE),
getStandardAction(COMMAND_SEEK_TO_NEXT),
shuffleButton
)
}
}If Spotify is still using the legacy NotificationCompat.MediaStyle, the logic is the same: call .addAction() 5 times on the NotificationCompat.Builder to populate the slots, and use .setStyle(MediaStyle().setShowActionsInCompactView(1, 2, 3)) to keep standard Android lockscreens clean.
HyperOS will automatically pick up the extra .addAction() elements and display them. Please forward this to the Android engineering team!