HarmonyOS自定義常用通知欄
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
通知(Notification)旨在讓用戶以合適的方式及時獲得有用的新消息,幫助用戶高效地處理任務(wù)。
系統(tǒng)為開發(fā)者提供了不同種類的通知樣式模板可以使用,開發(fā)者也可以根據(jù)自己需要自定義通知樣式。
HarmonyOS通知相關(guān)類
與通知相關(guān)的主要邏輯在NotificationSlot、NotificationRequest 和 NotificationHelper這三個類中,那這三個類都有什么作用呢?下面為大家逐一介紹。
1. NotificationSlot
這是一個定義通知的主題類,它可以設(shè)置通知的特征集合,包括通知到來時的提示音調(diào)、振動、鎖屏顯示以及設(shè)置通知的重要級別等。一般可以在應(yīng)用的AbilityPackage里設(shè)置,用以統(tǒng)一整個應(yīng)用的通知主題特征,一個應(yīng)用也可以關(guān)聯(lián)多個不同NotificationSlot。
重點說下NotificationSlot的幾個重要級別,也可以查看官方Api文檔:
- LEVEL_NONE: 表示通知不發(fā)布。
- LEVEL_MIN:表示通知可以發(fā)布,但是不顯示在通知欄,不自動彈出,無提示音;該級別不適用于前臺服務(wù)的場景。
- LEVEL_LOW:表示通知可以發(fā)布且顯示在通知欄,不自動彈出,無提示音。
- LEVEL_DEFAULT:表示通知發(fā)布后可在通知欄顯示,不自動彈出,觸發(fā)提示音。
- LEVEL_HIGH:表示通知發(fā)布后可在通知欄顯示,自動彈出,觸發(fā)提示音。
代碼示例
- // 創(chuàng)建notificationSlot對象
- NotificationSlot slot = new NotificationSlot(id, "testSlot", NotificationSlot.LEVEL_HIGH);
- slot.setDescription("create notificationSlot description");
- slot.setLevel(NotificationSlot.LEVEL_HIGH);
- // 設(shè)置振動提醒
- slot.setEnableVibration(true);
- // 設(shè)置鎖屏模式
- slot.setLockscreenVisibleness(NotificationRequest.VISIBLENESS_TYPE_PUBLIC);
- // 設(shè)置開啟呼吸燈提醒
slot.setEnableLight(true);
- // 設(shè)置呼吸燈的提醒顏色
- slot.setLedLightColor(Color.RED.getValue());
- slot.enableBypassDnd(true);
- slot.enableBadge(true);
- try {
- NotificationHelper.addNotificationSlot(slot);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
關(guān)于設(shè)置呼吸燈說明,由于手上只有一部P40Pro不帶呼吸燈,所以無法驗證實際效果。
2. NotificationRequest
NotificationRequest是通知最主要的部分,主要設(shè)置通知的樣式,HarmonyOS主要提供了6種類型的樣式:普通文本NotificationNormalContent、長文本NotificationLongTextContent、圖片NotificationPictureContent、多行NotificationMultiLineContent、社交NotificationConversationalContent、媒體NotificationMediaContent。另外還有一種自定義樣式,這些會在后面具體介紹。
雖然通知中提供了各種屬性的設(shè)置,但是一個通知對象,有幾個屬性是必須要設(shè)置的,其他的屬性均是可選的,必須設(shè)置的屬性如下:
- 小圖標(biāo),使用setLittleIcon()方法設(shè)置。
- 標(biāo)題,使用setTitle()方法設(shè)置。
- 文本內(nèi)容,使用setText()方法設(shè)置。
調(diào)用setIntentAgent()設(shè)置通知可以觸發(fā)的事件
- Intent intent = new Intent();
- // 指定要啟動的Ability的BundleName和AbilityName字段
- // 將Operation對象設(shè)置到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;
- // 設(shè)置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
該靜態(tài)類主要是管理通知,提供了發(fā)布、更新、刪除通知等靜態(tài)方法;
主要接口如下:
- publishNotification(NotificationRequest request),發(fā)布通知,當(dāng)NotificationRequest被設(shè)置后,通過該接口去發(fā)布通知;
- cancelNotification(int notificationId),取消通知,每個NotificationRequest創(chuàng)建時都必須有一個notificationId,可以通過這個接口取消創(chuàng)建的通知;
- cancelAllNotifications(),取消之前發(fā)布的所有通知;
- addNotificationSlot(NotificationSlot slot),創(chuàng)建一個NotificationSlot;
- setNotificationBadgeNum(int num),設(shè)置通知的角標(biāo);
通知的代碼結(jié)構(gòu)基本就是圍繞這三個類來構(gòu)建的,其中最重要的就是NotificationRequest這個類,整個HarmonyOS各種酷炫通知都是基于這個類來定制的,所以研究通知,不如說其實就是研究NotificationRequest。下面就來介紹下HarmonyOS官方提供的6中樣式以及自定義樣式,基本也就包含日常所有的通知需求了。
HarmonyOS通知樣式
1. 普通文本NotificationNormalContent
這是通知最基礎(chǔ)也是最常用的樣式,對應(yīng)設(shè)置NotificationRequest.setLittleIcon()、NotificationNormalContent.setTitle()、NotificationNormalContent.setText();
效果圖

代碼示例
- 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);
- // 設(shè)置通知的內(nèi)容
- request.setContent(notificationContent);
- request.setIntentAgent(intentAgent);
- try {
- NotificationHelper.publishNotification(request);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- /**
- * 圖片轉(zhuǎn)換工具方法
- *
- * @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
效果圖


代碼示例
- 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);
- // 設(shè)置通知的內(nèi)容
- request.setContent(notificationContent);
- request.setIntentAgent(intentAgent);
- try {
- NotificationHelper.publishNotification(request);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
3. 圖片NotificationPictureContent
效果圖


代碼示例
- 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);
- // 設(shè)置通知的內(nèi)容
- request.setContent(notificationContent);
- request.setIntentAgent(intentAgent);
- try {
- NotificationHelper.publishNotification(request);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
4. 多行NotificationMultiLineContent
效果圖


代碼示例
- 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("基礎(chǔ)工資: 210000")
- .addSingleLine("加班補助: 97630")
- .addSingleLine("餐補: 900")
- .addSingleLine("交通補助: 1200")
- .addSingleLine("出差補助: 9800")
- .setExpandedTitle("張學(xué)友工資單");
- NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(multiLineContent);
- // 設(shè)置通知的內(nèi)容
- request.setContent(notificationContent);
- request.setIntentAgent(intentAgent);
- try {
- NotificationHelper.publishNotification(request);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
5. 社交NotificationConversationalContent
效果圖


代碼示例
- ArrayList<String> arrayListStr = new ArrayList<>();
- arrayListStr.add("結(jié)婚以后兩個人在一起最重要的是什么?");
- arrayListStr.add("你是如何走出人生的陰霾的?");
- arrayListStr.add("怎么不回復(fù)我??我生氣了??!");
- 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);
- // 設(shè)置通知的內(nèi)容
- request.setContent(notificationContent);
- request.setIntentAgent(intentAgent);
- try {
- NotificationHelper.publishNotification(request);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
6. 媒體NotificationMediaContent
具體媒體會話管理,請參考開發(fā)-媒體會話管理開發(fā)指導(dǎo)
效果圖

代碼示例
- // 按鈕文字設(shè)置無效,圖標(biāo)顏色也不生效,默認(rèn)都是灰色
- 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后,此通知可以與關(guān)聯(lián)的AVSession交互,以便用戶可以在此通知中控制媒體播放
- NotificationRequest.NotificationMediaContent mediaContent = new NotificationRequest.NotificationMediaContent();
- mediaContent.setTitle(title)
- .setText(conStr)
- .setAVToken(avBrowser.getAVToken())
- .setShownActions(a);
- NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(mediaContent);
- // 設(shè)置通知的內(nèi)容
- request.setContent(notificationContent);
- try {
- NotificationHelper.publishNotification(request);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
7. 自定義通知樣式
效果圖

代碼示例
- 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的父布局中設(shè)置一個卡片屬性“ohos:remote="true"”,否則自定義效果無法出現(xiàn)
- ComponentProvider componentProvider = new ComponentProvider(layoutId, context); // 創(chuàng)建ComponentProvider對象
- // componentProvider.setString(ResourceTable.Id_ongoing_card_text, "setText", "TextContent"); // 設(shè)置布局中的文本內(nèi)容
- request.setCustomView(componentProvider);
- request.setIntentAgent(intentAgent);
- try {
- NotificationHelper.publishNotification(request);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
上面這些就是通知常用的幾種效果,有很多其他的屬性沒有在demo中展示出來,比如角標(biāo)、通知欄進度條等,這些都有屬性可以設(shè)置的,相比其他移動操作系統(tǒng),鴻蒙的通知樣式更加豐富全面也更加統(tǒng)一,相對來說開發(fā)的成本也更高一些,希望鴻蒙發(fā)展的越來越好。
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)