You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改ExoPlayer中PlayerNotificationManager的操作图标及图标颜色?

Got it! Let's walk through how to customize the playback control icons (play/pause/stop) and their colors for ExoPlayer's PlayerNotificationManager. Here's a step-by-step breakdown:

Customizing Playback Control Icons in PlayerNotificationManager

Step 1: Prepare Custom Icon Resources

First, add your custom vector or raster icons to the res/drawable directory (e.g., ic_custom_play.xml, ic_custom_pause.xml, ic_custom_stop.xml). Make sure they're sized appropriately for notifications (24dp is standard for control icons).

Step 2: Implement a Custom MediaDescriptionAdapter

To replace the default play/pause/stop actions, override the getActions() method in MediaDescriptionAdapter—this lets you define your own notification actions with custom icons:

import android.app.Notification;
import android.content.Context;
import android.content.Intent;
import android.support.v4.media.session.MediaButtonReceiver;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.core.app.PendingIntentCompat;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
import android.support.v4.media.session.PlaybackStateCompat;

private class CustomMediaDescriptionAdapter implements PlayerNotificationManager.MediaDescriptionAdapter {

    private final Context context;

    public CustomMediaDescriptionAdapter(Context context) {
        this.context = context;
    }

    // Required core methods
    @Override
    public CharSequence getCurrentContentTitle(Player player) {
        return "Your Media Title"; // Replace with your dynamic title logic
    }

    @Override
    public PendingIntent createCurrentContentIntent(Player player) {
        // Replace with intent to open your app's playback screen
        Intent intent = new Intent(context, PlaybackActivity.class);
        return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
    }

    @Override
    public CharSequence getCurrentContentText(Player player) {
        return "Your Media Subtitle"; // Replace with your dynamic subtitle logic
    }

    // Override to use custom action icons
    @Override
    public Notification.Action[] getActions(Player player, PlayerNotificationManager.TimeBar timeBar) {
        // Build play/pause action with custom icon
        PendingIntent playPausePendingIntent = MediaButtonReceiver.buildMediaButtonPendingIntent(
                context,
                player.isPlaying() ? PlaybackStateCompat.ACTION_PAUSE : PlaybackStateCompat.ACTION_PLAY
        );
        NotificationCompat.Action playPauseAction = new NotificationCompat.Action.Builder(
                player.isPlaying() ? R.drawable.ic_custom_pause : R.drawable.ic_custom_play,
                player.isPlaying() ? "Pause" : "Play",
                playPausePendingIntent
        ).build();

        // Build stop action with custom icon
        PendingIntent stopPendingIntent = MediaButtonReceiver.buildMediaButtonPendingIntent(
                context,
                PlaybackStateCompat.ACTION_STOP
        );
        NotificationCompat.Action stopAction = new NotificationCompat.Action.Builder(
                R.drawable.ic_custom_stop,
                "Stop",
                stopPendingIntent
        ).build();

        // Return custom actions (order defines their position in the notification)
        return new Notification.Action[]{playPauseAction, stopAction};
    }
}

Step 3: Attach the Adapter to PlayerNotificationManager

When initializing your PlayerNotificationManager, set the custom adapter to apply your icons:

private static final int NOTIFICATION_ID = 1234;
private static final String CHANNEL_ID = "playback_control_channel";

// Initialize PlayerNotificationManager
PlayerNotificationManager playerNotificationManager = new PlayerNotificationManager.Builder(
        context,
        NOTIFICATION_ID,
        CHANNEL_ID
)
.setMediaDescriptionAdapter(new CustomMediaDescriptionAdapter(context))
.build();

// Attach your ExoPlayer instance
playerNotificationManager.setPlayer(exoPlayer);

Changing Icon Colors for PlayerNotificationManager

You have a few flexible options to adjust icon colors, depending on your needs:

If using vector drawables, apply a tint directly to each action icon using setIconTint() in the Action Builder. This gives you per-icon control:

// Inside the getActions() method, when building playPauseAction
NotificationCompat.Action playPauseAction = new NotificationCompat.Action.Builder(
        player.isPlaying() ? R.drawable.ic_custom_pause : R.drawable.ic_custom_play,
        player.isPlaying() ? "Pause" : "Play",
        playPausePendingIntent
)
.setIconTint(ContextCompat.getColorStateList(context, R.color.notification_icon_tint))
.build();

Create a color state list res/color/notification_icon_tint.xml to handle different states (e.g., enabled/disabled):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/white" android:state_enabled="true"/>
    <item android:color="@color/gray_600" android:state_enabled="false"/>
</selector>

Option 2: Global Notification Accent Color

Set a global color for the entire notification, which will tint all compatible icons (like media controls) and elements:

PlayerNotificationManager playerNotificationManager = new PlayerNotificationManager.Builder(
        context,
        NOTIFICATION_ID,
        CHANNEL_ID
)
.setMediaDescriptionAdapter(new CustomMediaDescriptionAdapter(context))
.setColor(ContextCompat.getColor(context, R.color.notification_accent))
.build();

Note: This affects the time bar and other notification accents alongside icons.

Option 3: Post-Notification Modification via Listener

For full control, use a NotificationListener to adjust the notification after it's built:

playerNotificationManager.setNotificationListener(new PlayerNotificationManager.NotificationListener() {
    @Override
    public void onNotificationPosted(int notificationId, Notification notification, boolean ongoing) {
        // Rebuild the notification with custom color adjustments
        NotificationCompat.Builder updatedBuilder = NotificationCompat.Builder.from(context, notification)
                .setColor(ContextCompat.getColor(context, R.color.notification_icon_tint));
        
        // Update the active notification
        NotificationManagerCompat.from(context).notify(notificationId, updatedBuilder.build());
    }

    @Override
    public void onNotificationCancelled(int notificationId, boolean dismissedByUser) {
        // Handle cleanup logic if needed
    }
});

Key Notes for Android 12+

For Android 12 and above, ensure your notification channel's color is set correctly if relying on inherited tinting:

NotificationChannel channel = new NotificationChannel(
        CHANNEL_ID,
        "Playback Controls",
        NotificationManager.IMPORTANCE_LOW
);
channel.setDescription("Media playback control notifications");
channel.setLightColor(ContextCompat.getColor(context, R.color.notification_accent));
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);

内容的提问来源于stack exchange,提问作者P A Gosai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:15:26