无法设置锁屏专辑图:MediaSession实现问题求助
Hey there! It’s great that you’ve already got background playback, lockscreen controls, and notifications working—let’s get that missing album art sorted out. Here are the key steps and fixes to address the issue:
1. Ensure MediaSession Metadata Includes Album Art Properly
The lockscreen media UI pulls album art directly from your MediaSession’s metadata. You need to explicitly set either the album art bitmap or URI using MediaMetadataCompat.Builder:
Key Code Addition:
// Replace your existing metadata setup with this Bitmap albumArtBitmap = loadYourAlbumArt(); // Implement this method to load your art MediaMetadataCompat metadata = new MediaMetadataCompat.Builder() .putString(MediaMetadataCompat.METADATA_KEY_TITLE, currentTrack.getTitle()) .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, currentTrack.getArtist()) // Add these two lines for album art (covers different Android versions) .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArtBitmap) .putBitmap(MediaMetadataCompat.METADATA_KEY_ART, albumArtBitmap) .build(); mediaSession.setMetadata(metadata);
- Verify that
albumArtBitmapis notnull—add a fallback default bitmap if loading fails (e.g., a placeholder image from your resources).
2. Link MediaSession to Your Notification’s MediaStyle
Lockscreen media controls and art are tightly tied to your foreground service notification. Make sure you’re using MediaStyle and linking it to your MediaSession token:
// In your notification setup NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "YOUR_CHANNEL_ID") .setSmallIcon(R.drawable.ic_player_notification) .setContentTitle(currentTrack.getTitle()) .setContentText(currentTrack.getArtist()) .setLargeIcon(albumArtBitmap) // Matches lockscreen art .setStyle(new androidx.media.app.NotificationCompat.MediaStyle() .setMediaSession(mediaSession.getSessionToken()) // Critical link .setShowActionsInCompactView(0, 1)) // Show play/pause in compact view .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); // Ensures art shows on lockscreen startForeground(NOTIFICATION_ID, notificationBuilder.build());
3. Validate Playback State and MediaSession Flags
The lockscreen UI may not show art if your MediaSession isn’t marked as active or playback state isn’t set correctly:
// Set playback state (call this when play/pause changes) PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder() .setState(isPlaying ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED, currentPosition, 1.0f) .setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE) .build(); mediaSession.setPlaybackState(playbackState); // Activate the session and set required flags mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); mediaSession.setActive(true);
4. Quick Troubleshooting Checks
- Notification Channel: Ensure you’ve created a valid notification channel (required for Android O+), otherwise your foreground notification won’t appear.
- Bitmap Loading: If loading art from a file/network, do this on a background thread to avoid blocking the main thread and ensure the bitmap is fully loaded before setting metadata.
- Permissions: If loading art from external storage, make sure you’ve requested
READ_EXTERNAL_STORAGEpermission (orREAD_MEDIA_IMAGESfor Android 13+).
Here’s the full, updated initMediaSession method incorporating all these fixes:
private void initMediaSession() throws RemoteException { if (mediaSessionManager != null) return; mediaSessionManager = (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE); mediaSession = new MediaSessionCompat(this, "AudioPlayerSession"); // Set up control callbacks mediaSession.setCallback(new MediaSessionCompat.Callback() { @Override public void onPlay() { // Handle play logic updatePlaybackState(true); } @Override public void onPause() { // Handle pause logic updatePlaybackState(false); } }); // Set session flags mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); // Load album art (replace with your actual loading logic) Bitmap albumArtBitmap = loadAlbumArt(); if (albumArtBitmap == null) { albumArtBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.default_album_art); } // Build metadata MediaMetadataCompat metadata = new MediaMetadataCompat.Builder() .putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Sample Track") .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "Sample Artist") .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArtBitmap) .putBitmap(MediaMetadataCompat.METADATA_KEY_ART, albumArtBitmap) .build(); mediaSession.setMetadata(metadata); // Initialize playback state updatePlaybackState(true); // Activate session mediaSession.setActive(true); // Build and show foreground notification NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "PlayerChannel") .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Sample Track") .setContentText("Sample Artist") .setLargeIcon(albumArtBitmap) .setStyle(new androidx.media.app.NotificationCompat.MediaStyle() .setMediaSession(mediaSession.getSessionToken()) .setShowActionsInCompactView(0)) .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent) // Replace with your intent .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); startForeground(1, notificationBuilder.build()); } private void updatePlaybackState(boolean isPlaying) { long currentPosition = 0; // Get current track position PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder() .setState(isPlaying ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED, currentPosition, 1.0f) .setActions(PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE) .build(); mediaSession.setPlaybackState(playbackState); } private Bitmap loadAlbumArt() { // Example: Load from local file try { return BitmapFactory.decodeFile("/storage/emulated/0/Music/albumart.jpg"); } catch (Exception e) { e.printStackTrace(); return null; } }
内容的提问来源于stack exchange,提问作者Rektirino

