開發 實現右上角三角形角標_給桌面應用新增訊息角標
技術標籤:開發 實現右上角三角形角標
自從有了通知渠道,許多應用紛紛申請了多個渠道,每個渠道又有好幾條訊息,加起來便是許多訊息。這麼多的未讀訊息,空間有限的通知欄已然不夠容納,於是各應用又希望向使用者提示未讀訊息的數量,好讓使用者知曉有沒有未讀訊息,還有幾條未讀訊息。
原本通知渠道提供了setShowBadge方法,可設定是否在應用圖示的右上角展示小紅點(此紅點又稱訊息角標),呼叫該方法設定true之後,有未讀訊息時就顯示紅點,無未讀訊息則不顯示紅點。然而setShowBadge方法在國產手機上並不奏效,原因有二:其一,該方法只顯示紅點未顯示數量;其二,該方法遲至Android8.0之後才跟著通知渠道一起推出,眾多國內廠商等來不及故而早早推出了自己的紅點方案。時至今日,國產手機的四大廠商包括華為、小米、OPPO、VIVO均推出了自己的訊息角標方案,完全把Android官方的setShowBadge方法晾在一旁。國產手機的紅點方案參考了蘋果手機的紅點樣式,同樣把訊息紅點放在桌面應用的右上角,並且紅點內部顯示當前未讀訊息的數量(如下面左圖所示),而安卓官方的紅點內部不展示數字(如下面右圖所示)。
由於各廠商對訊息角標的實現方案不盡相同,因此只能給他們的手機分別適配處理了。下面就以華為和小米兩家的紅點方案為例,依次介紹華為系手機(含華為與榮耀品牌)和小米系手機(含小米和紅米品牌)的適配編碼。
華為的訊息角標不依賴通知推送,允許單獨設定紅點的展示情況,主要通過內容解析器呼叫華為核心的訊息角標服務,詳細的角標顯示程式碼示例如下:
// 華為的訊息角標需要事先宣告兩個許可權:INTERNET和CHANGE_BADGEprivate static void showBadgeOfEMUI(Context ctx, int count) { try { Bundle extra = new Bundle(); // 建立一個包裹物件 extra.putString("package", BuildConfig.APPLICATION_ID); // 應用的包名 extra.putString("class", BuildConfig.APPLICATION_ID+".MainActivity"); // 應用的首屏頁面路徑 extra.putInt("badgenumber", count); // 應用的訊息數量 Uri uri = Uri.parse("content://com.huawei.android.launcher.settings/badge/"); // 通過內容解析器呼叫華為核心的訊息角標服務 ctx.getContentResolver().call(uri, "change_badge", null, extra); } catch (Exception e) { e.printStackTrace(); }}
為了合理使用魔改後的訊息角標服務,華為規定要在AndroidManifest.xml中宣告兩個許可權配置,包括網際網路許可權INTERNET,以及徽章修改許可權CHANGE_BADGE,具體的許可權配置程式碼如下所示:
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
至於小米的訊息角標方案,則依賴於通知推送,必須在傳送通知之時一起傳送訊息數量引數。為此小米給Notification類添加了一個新欄位extraNotification,還添加了新方法setMessageCount,前者用於管理桌面上的訊息角標,而後者能夠設定角標紅點的訊息數量。下面是在小米手機上顯示訊息角標的程式碼例子:
// 小米的訊息角標需要在傳送通知的時候一塊呼叫private static void showBadgeOfMIUI(int count, Notification notify) { try { // 利用反射技術獲得額外的新增欄位extraNotification Field field = notify.getClass().getDeclaredField("extraNotification"); // 該欄位為Notification型別,下面獲取它的例項物件 Object extraNotification = field.get(notify); // 利用反射技術獲得額外的新增方法setMessageCount Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class); // 利用反射技術呼叫例項物件的setMessageCount方法,設定角標紅點的訊息數量 method.invoke(extraNotification, count); } catch (Exception e) { e.printStackTrace(); }}
綜合上述的兩種角標實現方案,形成以下的顯示角標程式碼,可同時相容華為系手機和小米系手機:
// 在桌面上的應用圖示右上角顯示數字角標public static void showMarkerCount(Context ctx, int count, Notification notify) { showBadgeOfEMUI(ctx, count); // 華為手機EMUI系統的訊息角標 // 小米手機還要進入設定裡面的應用管理,開啟當前App的“顯示桌面圖示角標” showBadgeOfMIUI(count, notify); // 小米手機MIUI系統的訊息角標}
不管是華為方案還是小米方案,若想清除桌面上的應用紅線,只要呼叫上面方法設定訊息數量為0即可。兩種方案的角標效果如下圖所示,其中下面左圖為華為手機上的訊息角標,下面右圖為小米手機上的訊息角標。