Skip to content

[EN] 4.Custom Notification

jrfeng edited this page Mar 8, 2021 · 13 revisions

You can create a custom Notification by extends the following types:

PlayerService.NotificationView is an abstract class, which is the base class of the all NotificationView. PlayerService.MediaNotificationView extends and implements the PlayerService.NotificationView, and provides a Notification based on the NotificationCompat.MediaStyle style.

About NotificationCompat.MediaStyle, See android training: Create a notification with media controls

Extends PlayerService.MediaNotificationView

You can override the following methods of PlayerService.MediaNotificationView to customize it:

Example:

public class MyMediaNotificationView extends PlayerService.MediaNotificationView {
    ...
    
    @NonNull
    @Override
    protected Bitmap getDefaultIcon() {
        return mMyDefaultIcon;
    }

    @Override
    protected int getSmallIconId() {
        return R.drawable.my_small_icon_id;
    }

    @Override
    protected void onBuildMediaStyle(NotificationCompat.MediaStyle mediaStyle) {
        // The following line is optional
        super.onBuildMediaStyle(mediaStyle);

        // Config NotificationCompat.MediaStyle
    }

    @Override
    protected void onBuildNotification(androidx.core.app.NotificationCompat.Builder builder) {
        // The following line is optional
        super.onBuildNotification(builder);

        // Config NotificationCompat.Builder
    }
}

Extends PlayerService.NotificationView

PlayerService.NotificationView is an abstract class, and subclasses need to implement the following abstract methods:

Example:

public class MyCustomNotificationView extends PlayerService.NotificationView {
    // ...

    @Override
    public Notification onCreateNotification() {
        // return a Notification instance, not null
    }

    @Override
    public int getNotificationId() {
        // return the id of Notification
        return 1;
    }
}

Note: When using NotificationCompat.Builder to create a Notification instance, its channelId should be set to PlayerService.NotificationView.CHANNEL_ID.

Example:

NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext(), PlayerService.NotificationView.CHANNEL_ID);

Add Notification Action

You can use buildCustomAction(String actionName, PlayerService.CustomAction customAction) to create a PendingIntent instance, and associate it to a Notification action.

Example:

public static class MediaNotificationView extends NotificationView {
    private static final String ACTION_SKIP_TO_PREVIOUS = "SKIP_TO_PREVIOUS";
    private static final String ACTION_PLAY_PAUSE = "PLAY_PAUSE";
    private static final String ACTION_SKIP_TO_NEXT = "SKIP_TO_NEXT";

    private PendingIntent mSkipToPrevious;
    private PendingIntent mPlayPause;
    private PendingIntent mSkipToNext;

    @Override
    protected void onInit(Context context) {
        // build skip to previous PendingIntent
        mSkipToPrevious = buildCustomAction(ACTION_SKIP_TO_PREVIOUS, new CustomAction() {
                @Override
                public void doAction(@NonNull Player player, @Nullable Bundle extras) {
                    player.skipToPrevious();
                }
            });

        // build play pause PendingIntent
        mPlayPause = buildCustomAction(ACTION_PLAY_PAUSE, new CustomAction() {
            @Override
            public void doAction(@NonNull Player player, @Nullable Bundle extras) {
                player.playPause();
            }
        });

        // build skip to next PendingIntent
        mSkipToNext = buildCustomAction(ACTION_SKIP_TO_NEXT, new CustomAction() {
            @Override
            public void doAction(@NonNull Player player, @Nullable Bundle extras) {
                player.skipToNext();
            }
        });
    }

    ...

    protected void onBuildNotification(NotificationCompat.Builder builder) {
        // add skipToPrevious action
        builder.addAction(R.drawable.snow_ic_skip_previous, "skip_to_previous", mSkipToPrevious);

        // add playPause action
        if (isPlayingState()) {
            builder.addAction(R.drawable.snow_ic_pause, "pause", mPlayPause);
        } else {
            builder.addAction(R.drawable.snow_ic_play, "play", mPlayPause);
        }

        // add skipToNext action
        builder.addAction(R.drawable.snow_ic_skip_next, "skip_to_next", mSkipToNext);
    }
}

Load Icon

PlayerService.NotificationView support icon loading, and you can configure it or implement your own icon loading logic.

You can use the following methods to configure icon loading function:

You can override onInit(Context), and configure these parameters in this method.

Custom Icon Loader

You can override the onCreateBetterIconLoader(Context context) and return a BetterIconLoader instance to implement your own icon loading logic.

// Create a custom icon loader
public class MyBetterIconLoader implements PlayerService.NotificationView.BetterIconLoader {
    @Override
    public void loadIcon(@NonNull MusicItem musicItem, int width, int height, @NonNull AsyncResult<Bitmap> result) {
        // ...loading icon
        // This method is executed in an asynchronous thread
        // When the icon is loaded successfully, the onSuccess(Bitmap) of the result parameter should be called to return it
        // When an error occurs during image loading, the onError(Throwable) of the result parameter should be called
    }
}

// Use custom icon loader
public class MyNotificationView extends PlayerService.MediaNotificationView {
    ...

    @NonNull
    @Override
    protected BetterIconLoader onCreateBetterIconLoader(@NonNull Context context) {
        return new MyBetterIconLoader();
    }
}

The default icon will be used when the icon fails to load. You can invoke the setDefaultIcon(Bitmap) to set the default icon.

Apply NotificationView

The custom NotificationView needs to be applied by inheriting PlayerService and overriding its onCreateNotificationView() method.

public class MyCustomPlayerService extends PlayerService {
    ...
    
    @Nullable
    @Override
    public NotificationView onCreateNotificationView() {
        // Return a instance of your custom NotificationView
        return MyCustomNotificationView();
    }
}

More details, see Custom PlayerService.

Hide Notification

If you want hide Notification, just override onCreateNotificationView() and return null:

public class MyCustomPlayerService extends PlayerService{
    ...
    
    @Nullable
    @Override
    public NotificationView onCreateNotificationView() {
        // return null will hide Notification
        return null;
    }
}

End