【中软国际】HarmonyOS自定义常用通知栏 原创 精华

中软HOS小鸿
发布于 2021-8-17 13:38
浏览
11收藏

@toc

前言

通知(Notification)旨在让用户以合适的方式及时获得有用的新消息,帮助用户高效地处理任务。
系统为开发者提供了不同种类的通知样式模板可以使用,开发者也可以根据自己需要自定义通知样式。

HarmonyOS通知相关类

与通知相关的主要逻辑在NotificationSlotNotificationRequestNotificationHelper这三个类中,那这三个类都有什么作用呢?下面为大家逐一介绍。

1. NotificationSlot

这是一个定义通知的主题类,它可以设置通知的特征集合,包括通知到来时的提示音调、振动、锁屏显示以及设置通知的重要级别等。一般可以在应用的AbilityPackage里设置,用以统一整个应用的通知主题特征,一个应用也可以关联多个不同NotificationSlot。

  • 重点说下NotificationSlot的几个重要级别,也可以查看官方Api文档:
  1. LEVEL_NONE: 表示通知不发布。
  2. LEVEL_MIN:表示通知可以发布,但是不显示在通知栏,不自动弹出,无提示音;该级别不适用于前台服务的场景。
  3. LEVEL_LOW:表示通知可以发布且显示在通知栏,不自动弹出,无提示音。
  4. LEVEL_DEFAULT:表示通知发布后可在通知栏显示,不自动弹出,触发提示音。
  5. LEVEL_HIGH:表示通知发布后可在通知栏显示,自动弹出,触发提示音。
  • 代码示例
// 创建notificationSlot对象
NotificationSlot slot = new NotificationSlot(id, "testSlot", NotificationSlot.LEVEL_HIGH);
slot.setDescription("create notificationSlot description");
slot.setLevel(NotificationSlot.LEVEL_HIGH);
// 设置振动提醒
slot.setEnableVibration(true);
// 设置锁屏模式
slot.setLockscreenVisibleness(NotificationRequest.VISIBLENESS_TYPE_PUBLIC);
// 设置开启呼吸灯提醒
slot.setEnableLight(true);
// 设置呼吸灯的提醒颜色
slot.setLedLightColor(Color.RED.getValue());
slot.enableBypassDnd(true);
slot.enableBadge(true);
try {
    NotificationHelper.addNotificationSlot(slot);
} catch (RemoteException e) {
    e.printStackTrace();
}

关于设置呼吸灯说明,由于手上只有一部P40Pro不带呼吸灯,所以无法验证实际效果。

2. NotificationRequest

NotificationRequest是通知最主要的部分,主要设置通知的样式,HarmonyOS主要提供了6种类型的样式:普通文本NotificationNormalContent、长文本NotificationLongTextContent、图片NotificationPictureContent、多行NotificationMultiLineContent、社交NotificationConversationalContent、媒体NotificationMediaContent。另外还有一种自定义样式,这些会在后面具体介绍。
虽然通知中提供了各种属性的设置,但是一个通知对象,有几个属性是必须要设置的,其他的属性均是可选的,必须设置的属性如下:

  • 小图标,使用setLittleIcon()方法设置。
  • 标题,使用setTitle()方法设置。
  • 文本内容,使用setText()方法设置。
    调用setIntentAgent()设置通知可以触发的事件
Intent intent = new Intent();
// 指定要启动的Ability的BundleName和AbilityName字段
// 将Operation对象设置到Intent中
Operation operation = new Intent.OperationBuilder()
        .withDeviceId("")
        .withBundleName(getBundleName())
        .withAbilityName(OtherAbility.class.getName())
        .build();
intent.setOperation(operation);
List<Intent> intentList = new ArrayList<>();
intentList.add(intent);
// 定义请求码
int requestCode = 200;
// 设置flags
List<IntentAgentConstant.Flags> flags = new ArrayList<>();
flags.add(IntentAgentConstant.Flags.UPDATE_PRESENT_FLAG);
// 指定启动一个有页面的Ability
IntentAgentInfo paramsInfo = new IntentAgentInfo(requestCode, 
        IntentAgentConstant.OperationType.START_ABILITY, flags, intentList, null);
// 获取IntentAgent实例
IntentAgent agent = IntentAgentHelper.getIntentAgent(this, paramsInfo);
setIntentAgent(agent);

具体API就不一一介绍了,可以参考官方

3. NotificationHelper

该静态类主要是管理通知,提供了发布、更新、删除通知等静态方法;
主要接口如下:

  • publishNotification(NotificationRequest request),发布通知,当NotificationRequest被设置后,通过该接口去发布通知;
  • cancelNotification(int notificationId),取消通知,每个NotificationRequest创建时都必须有一个notificationId,可以通过这个接口取消创建的通知;
  • cancelAllNotifications(),取消之前发布的所有通知;
  • addNotificationSlot(NotificationSlot slot),创建一个NotificationSlot;
  • setNotificationBadgeNum(int num),设置通知的角标;

通知的代码结构基本就是围绕这三个类来构建的,其中最重要的就是NotificationRequest这个类,整个HarmonyOS各种酷炫通知都是基于这个类来定制的,所以研究通知,不如说其实就是研究NotificationRequest。下面就来介绍下HarmonyOS官方提供的6中样式以及自定义样式,基本也就包含日常所有的通知需求了。

HarmonyOS通知样式

1. 普通文本NotificationNormalContent

这是通知最基础也是最常用的样式,对应设置NotificationRequest.setLittleIcon()、NotificationNormalContent.setTitle()、NotificationNormalContent.setText();

  • 效果图
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
  • 代码示例
int notificationId = 1;
NotificationRequest request = new NotificationRequest(notificationId);
request.setSlotId(slotId);
request.setLittleIcon(littleIcon);

// 普通文本
NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();
content.setTitle(title)
       .setText(countent);
NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);
// 设置通知的内容
request.setContent(notificationContent);
request.setIntentAgent(intentAgent);
try {
    NotificationHelper.publishNotification(request);
} catch (RemoteException e) {
    e.printStackTrace();
}
/**
 * 图片转换工具方法
 *
 * @param drawableId
 * @return
 */
private PixelMap getPixelMap(int drawableId) {
    InputStream drawableInputStream = null;
    try {
        drawableInputStream = context.getResourceManager().getResource(drawableId);
        ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
        ImageSource imageSource = ImageSource.create(drawableInputStream, sourceOptions);
        ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
        decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
        return imageSource.createPixelmap(decodingOptions);
    } catch (IOException | NotExistException e) {
        e.getMessage();
    } finally {
        if (drawableInputStream != null) {
        try {
            drawableInputStream.close();
        } catch (IOException e) {
            e.getMessage();
        }
    }
}
return null;
}

2. 长文本NotificationLongTextContent

  • 效果图
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
  • 代码示例
int notificationId = 2;
NotificationRequest request = new NotificationRequest(notificationId);
request.setSlotId(slotId);
request.setLittleIcon(littleIcon);
// request.setBigIcon(bigIcon);

// 长文本
NotificationRequest.NotificationLongTextContent contentLong = new NotificationRequest.NotificationLongTextContent();
contentLong.setTitle(title)
           .setLongText(longText);
NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(contentLong);
// 设置通知的内容
request.setContent(notificationContent);
request.setIntentAgent(intentAgent);
try {
    NotificationHelper.publishNotification(request);
} catch (RemoteException e) {
    e.printStackTrace();
}

3. 图片NotificationPictureContent

  • 效果图
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
  • 代码示例
int notificationId = 4;
NotificationRequest request = new NotificationRequest(notificationId);
request.setSlotId(slotId);
request.setLittleIcon(littleIcon);
request.setBigIcon(icon);

// 图片通知
NotificationRequest.NotificationPictureContent contentLong = new NotificationRequest.NotificationPictureContent();
contentLong.setTitle(title)
           .setBigPicture(icon)
           .setExpandedTitle(title)
           .setText(context);
NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(contentLong);
// 设置通知的内容
request.setContent(notificationContent);
request.setIntentAgent(intentAgent);
try {
    NotificationHelper.publishNotification(request);
} catch (RemoteException e) {
    e.printStackTrace();
}

4. 多行NotificationMultiLineContent

  • 效果图
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
  • 代码示例
int notificationId = 5;
NotificationRequest request = new NotificationRequest(notificationId);
request.setSlotId(slot.getId());
request.setLittleIcon(littleIcon);

// 多行文本
NotificationRequest.NotificationMultiLineContent multiLineContent = new NotificationRequest.NotificationMultiLineContent();
multiLineContent.setTitle("工资单")
                .setText("保密文件,禁止传递")
                .addSingleLine("基础工资: 210000")
                .addSingleLine("加班补助: 97630")
                .addSingleLine("餐补: 900")
                .addSingleLine("交通补助: 1200")
                .addSingleLine("出差补助: 9800")
                .setExpandedTitle("张学友工资单");
NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(multiLineContent);
// 设置通知的内容
request.setContent(notificationContent);
request.setIntentAgent(intentAgent);
try {
    NotificationHelper.publishNotification(request);
} catch (RemoteException e) {
    e.printStackTrace();
}

5. 社交NotificationConversationalContent

  • 效果图
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
  • 代码示例
ArrayList<String> arrayListStr = new ArrayList<>();
arrayListStr.add("结婚以后两个人在一起最重要的是什么?");
arrayListStr.add("你是如何走出人生的阴霾的?");
arrayListStr.add("怎么不回复我??我生气了!!");
arrayListStr.add("我真生气了!!!!!你听见了吗!");
arrayListStr.add("为什么新闻放完了总是要播出他们在收拾稿子的片段?");

MessageUser messageUser = new MessageUser();
messageUser.setName(name);
messageUser.setPixelMap(icon);

int notificationId = 3;
NotificationRequest request = new NotificationRequest(notificationId);
request.setSlotId(slot.getId());
request.setLittleIcon(littleIcon);
request.addMessageUser(messageUser);

// 社交
NotificationRequest.NotificationConversationalContent content = new NotificationRequest.NotificationConversationalContent(messageUser);
content.setConversationTitle("[" + arrayListStr.size() + "条]" + name)
       .setConversationGroup(true);
for (int i = 0; i < arrayListStr.size(); i++) {
    content.addConversationalMessage(arrayListStr.get(i), 1, messageUser);
}

NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);
// 设置通知的内容
request.setContent(notificationContent);
request.setIntentAgent(intentAgent);
try {
    NotificationHelper.publishNotification(request);
} catch (RemoteException e) {
    e.printStackTrace();
}

6. 媒体NotificationMediaContent

具体媒体会话管理,请参考开发-媒体会话管理开发指导

  • 效果图
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
  • 代码示例
// 按钮文字设置无效,图标颜色也不生效,默认都是灰色
NotificationActionButton.Builder builder = new NotificationActionButton.Builder(pixelMap1, "btn1", null);
NotificationActionButton.Builder builder1 = new NotificationActionButton.Builder(pixelMap2, "btn2", null);
NotificationActionButton.Builder builder2 = new NotificationActionButton.Builder(pixelMap3, "btn3", null);

int notificationId = 1;
NotificationRequest request = new NotificationRequest(notificationId);
request.setSlotId(slot.getId());
request.setLittleIcon(littleIcon);
request.addActionButton(builder.build());
request.addActionButton(builder1.build());
request.addActionButton(builder2.build());

int[] a = {0, 1, 2};
// 普通文本
// setAVToken 将指定的AVToken附加,连接AVToken后,此通知可以与关联的AVSession交互,以便用户可以在此通知中控制媒体播放
NotificationRequest.NotificationMediaContent mediaContent = new NotificationRequest.NotificationMediaContent();
mediaContent.setTitle(title)
            .setText(conStr)
            .setAVToken(avBrowser.getAVToken())
            .setShownActions(a);
NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(mediaContent);
// 设置通知的内容
request.setContent(notificationContent);
try {
    NotificationHelper.publishNotification(request);
} catch (RemoteException e) {
    e.printStackTrace();
}

7. 自定义通知样式

  • 效果图
    【中软国际】HarmonyOS自定义常用通知栏-鸿蒙开发者社区
  • 代码示例
NotificationRequest request = new NotificationRequest(context, 5);
request.setSlotId(slot.getId());
request.setLittleIcon(littleIcon);

String title = "";
String text = "";
NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();
content.setTitle(title).setText(text);
NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);
request.setContent(notificationContent);

// layoutId就是自己定义的xml布局,需要在xml的父布局中设置一个卡片属性“ohos:remote="true"”,否则自定义效果无法出现
ComponentProvider componentProvider = new ComponentProvider(layoutId, context); // 创建ComponentProvider对象
// componentProvider.setString(ResourceTable.Id_ongoing_card_text, "setText", "TextContent"); // 设置布局中的文本内容
request.setCustomView(componentProvider);
request.setIntentAgent(intentAgent);

try {
    NotificationHelper.publishNotification(request);
} catch (RemoteException e) {
    e.printStackTrace();
}

上面这些就是通知常用的几种效果,有很多其他的属性没有在demo中展示出来,比如角标、通知栏进度条等,这些都有属性可以设置的,相比其他移动操作系统,鸿蒙的通知样式更加丰富全面也更加统一,相对来说开发的成本也更高一些,希望鸿蒙发展的越来越好。
 
作者: 伏雄

更多原创内容请关注:中软国际 HarmonyOS 技术学院

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-8-17 15:10:01修改
15
收藏 11
回复
举报
9条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

厉害,各种文本看了个遍

回复
2021-8-17 14:05:49
chaoxiaoshu
chaoxiaoshu

牛,原来通知还能玩出这么多花样

回复
2021-8-17 21:40:21
火莹
火莹

强(๑•̀ㅂ•́)و✧

回复
2021-8-18 09:36:31
wx60779728634b1
wx60779728634b1

牛,原来通知还能玩出这么多花样
 

回复
2021-8-18 17:26:16
没用的喵叔
没用的喵叔

优质文章!

回复
2021-8-19 07:56:56
爆炸小清新
爆炸小清新

666

回复
2021-8-19 14:09:18
chaoxiaoshu
chaoxiaoshu

大佬,请教个问题,自定义样式中多个按钮如何设置不同的IntentAgent

回复
2021-9-22 12:45:53
修身养生
修身养生

感谢分享

回复
2021-9-26 16:31:43
中软HOS小鸿
中软HOS小鸿

超级实用

回复
2021-9-29 16:15:20
回复
    相关推荐