-
-
Notifications
You must be signed in to change notification settings - Fork 45
[ZH] 4.自定义 Notification
可以通过继承以下类来创建一个自定义的 Notification:
其中,PlayerService.NotificationView
是个抽象类,它是通知栏控制器的基类。PlayerService.MediaNotificationView
继承并实现了 PlayerService.NotificationView
类,并提供了一个基于 NotificationCompat.MediaStyle
样式的通知栏控制器。
提示:关于 NotificationCompat.MediaStyle
样式,请参考 Android 官方文档:使用媒体控件创建通知。
可以覆盖 PlayerService.MediaNotificationView
的以下方法对其进行自定义:
-
getSmallIconId()
:返回自定义的smallIcon
的资源ID
-
onBuildMediaStyle(NotificationCompat.MediaStyle)
:对NotificationCompat.MediaStyle
进行配置。 -
onBuildNotification(NotificationCompat.Builder)
:对NotificationCompat.Builder
进行配置。
例:
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) {
// 下面这行代码是可选的
super.onBuildMediaStyle(mediaStyle);
// 配置 NotificationCompat.MediaStyle
}
@Override
protected void onBuildNotification(androidx.core.app.NotificationCompat.Builder builder) {
// 下面这行代码是可选的
super.onBuildNotification(builder);
// 配置 NotificationCompat.Builder
}
}
关于 NotificationCompat.MediaStyle
的更多内容,请参考请参考 Android 官方文档:使用媒体控件创建通知
PlayerService.NotificationView
是个抽象类,子类需要实现以下抽象方法:
-
onCreateNotification()
:返回一个Notification
对象,不能为null
。该Notification
对象会作为播放器的通知栏控制器显式在通知栏中。 -
getNotificationId()
:返回Notification
的id
。
例:
public class MyCustomNotificationView extends PlayerService.NotificationView {
// ...
@Override
public Notification onCreateNotification() {
// return a Notification instance
}
@Override
public int getNotificationId() {
return 1;
}
}
注意!使用 NotificationCompat.Builder
创建 Notification
对象时,其 channelId
应该设置为 PlayerService.NotificationView.CHANNEL_ID
。
例:
NotificationCompat.Builder builder = new NotificationCompat.Builder(getContext(), PlayerService.NotificationView.CHANNEL_ID);
可以使用 buildCustomAction(String actionName, PlayerService.CustomAction customAction)
方法创建一个要与 Notification
动作进行关联的 PendingIntent
对象。
例:
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) {
// 创建 “上一曲” PendingIntent
mSkipToPrevious = buildCustomAction(ACTION_SKIP_TO_PREVIOUS, new CustomAction() {
@Override
public void doAction(@NonNull Player player, @Nullable Bundle extras) {
player.skipToPrevious();
}
});
// 创建 “播放/暂停” PendingIntent
mPlayPause = buildCustomAction(ACTION_PLAY_PAUSE, new CustomAction() {
@Override
public void doAction(@NonNull Player player, @Nullable Bundle extras) {
player.playPause();
}
});
// 创建 “下一曲” 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) {
// 添加 “上一曲” 动作
builder.addAction(R.drawable.snow_ic_skip_previous, "skip_to_previous", mSkipToPrevious);
// 添加 “播放/暂停” 动作
if (isPlayingState()) {
builder.addAction(R.drawable.snow_ic_pause, "pause", mPlayPause);
} else {
builder.addAction(R.drawable.snow_ic_play, "play", mPlayPause);
}
// 添加 “下一曲” 动作
builder.addAction(R.drawable.snow_ic_skip_next, "skip_to_next", mSkipToNext);
}
}
通过覆盖 PlayerService
的 onCreateNotificationView()
方法来应用自定义的通知栏控制器。
例:
@PersistenId("MyPlayerService")
public MyPlayerService extends PlayerService {
...
@Nullable
@Override
protected NotificationView onCreateNotificationView() {
return new MyCustomNotificationView();
}
}
PlayerService.NotificationView
实现了 Icon 加载功能。你可以对其进行配置,或者实现你自己的 Icon 加载逻辑。
可以调用以下方法配置 Icon 加载功能:
-
setIconSize(int size)
:设置 Icon 的大小(默认为96dp
)。这会对 Icon 进行等比缩放,以节约内存。 -
setIconSize(int width, int height)
:分别设置 Icon 的宽和高。 -
setDefaultIcon(Bitmap)
:设置通知的默认图标,该图标会在图片加载失败时展示。
可以覆盖 onInit(Context)
方法,并在该方法中完成以上设置。
可以覆盖 NotificationView
的 onCreateBetterIconLoader(Context context)
方法并返回一个自定义的 BetterIconLoader
来自定义 Icon 加载功能。
// 自定义 BetterIconLoader
public class MyBetterIconLoader implements PlayerService.NotificationView.BetterIconLoader {
@Override
public void loadIcon(@NonNull MusicItem musicItem, int width, int height, @NonNull AsyncResult<Bitmap> result) {
// ...加载图片
// 该方法会在异步线程中执行
// 当图片加载成功时,应该调用 result 参数的 onSuccess(Bitmap) 方法返回它
// 当图片加载过程中发生错误,应该调用 result 参数的 onError(Throwable) 方法发出错误通知
}
}
// 使用自定义的 BetterIconLoader
public class MyNotificationView extends PlayerService.MediaNotificationView {
...
@NonNull
@Override
protected BetterIconLoader onCreateBetterIconLoader(@NonNull Context context) {
return new MyBetterIconLoader();
}
}
图片加载失败时将使用默认图片。可以使用 setDefaultIcon(Bitmap)
方法设置默认图片。
如果你不需要在通知栏中显示通知栏控制器,可以覆盖 PlayerService
的 onCreateNotificationView()
方法并返回 null
即可。
例:
@PersistenId("MyPlayerService")
public class MyPlayerService extends PlayerService{
...
@Nullable
@Override
public NotificationView onCreateNotificationView() {
// 返回 null 会隐藏通知栏控制器
return null;
}
}
End