安卓應用角標那些事兒
什么是應用角標?
應用角標最開始是在ios系統中出現的,大概長這樣:
角標.jpg
不知道從什么時候開始,國內各大安卓手機系統上,也慢慢出現了應用角標的身影,到現在幾乎成為了安卓系統的標配,發張圖片讓大家近距離感受一下:
screenshot.png
但是有一點要特別提一下,那就是 原生的Android系統,是不支持應用角標的 (這也是文章標題叫“安卓角標”而不是“Android角標”的原因)。畢竟應用角標是一個帶有爭議的設計,有些強迫癥用戶對應用角標咬牙切齒,有些用戶看不到應用角標又渾身癢癢,對于這一點我也只能說“仁者見仁,智者見智”吧。
如何支持應用角標?
安卓應用的角標是由Launcher支持的,而原生的Android系統Launcher并沒有提供角標支持,所以各大手機廠商只能自己定制Launcher來實現,然后提供接口給外部使用。主流的做法都是通過廣播Intent的形式來提供接口,不同的手機系統所支持的廣播Intent也不太一樣,所以需要針對不同的手機系統來做適配(恭喜你又成功跳入一個系統適配的坑!)。
角標開源庫介紹
相信每個安卓開發者看到系統適配這幾個字,都不會不由自主噴出一口老血。。。但是這次不用慌,因為已經有不怕死的家伙為我們造好了輪子,接下來就為大家隆重推出 ShortcutBadger (github大法好啊~真是好~)。這個開源庫為我們封裝了各種系統適配的細節,如文檔所描述的,擁有了ShortcutBadger,你也就免除了以下系統適配的煩惱:
角標02.png
但在實際使用時,你會發現,圖片很美,現實卻很殘酷!經不完全測試(原諒我的“不完全”,畢竟安卓機型碎片化太過嚴重),我發現這個開源庫對于小米、華為、vivo和oppo等主流機型的支持都是有各種問題的,要么完全不奏效,要么就有bug。當然這個開源庫也在不斷完善,但是在它還不夠穩定的情況下,建議大家還是先用來當備選方案,支持一些冷門機型可以,主流機型還是自己適配比較靠譜點。
特殊機型適配
華為系列
傳送門: 華為角標官方文檔
按照華為官方文檔的介紹,如果要獲得應用角標支持,需要為應用申請華為證書,然后在“權簽平臺”下載開發者證書,再將開發者證書集成到應用中,整個流程跑下來還是很繁瑣的。
那么吃瓜群眾肯定就要問了,有沒有簡單一點的方法呢?答案當然是有的!結合華為的《角標開發指導書》中的代碼參考和親身實踐,我發現只需要其中兩步,也可以實現華為角標支持(目前只驗證了華為mate8 和華為 p7,其他機型手頭暫時沒有,歡迎大家補充):
- 在AndroidManifest.xml中申請華為角標權限
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
- 參考以下代碼,設置應用角標即可
Bundle bundle = new Bundle(); bundle.putString("package", context.getPackageName()); String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName(); bundle.putString("class", launchClassName); bundle.putInt("badgenumber", msgCount); context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bundle);
小米系列
傳送門: 小米角標官方文檔
在小米機型上,系統默認是支持應用角標的,不過支持的方式非常反人類,導致經常有用戶來反饋說角標數字不對的問題。小米官方文檔關于默認情況是這么描述的:
當app向通知欄發送了一條通知 (通知不帶進度條并且用戶可以刪除的),那么桌面app icon角標就會顯示1。此時app顯示的角標數是和通知欄里app發送的通知數對應的,即向通知欄發送了多少通知就會顯示多少角標。
那么吃瓜群眾肯定又要問了,What are you talking about?!不要慌,我舉一個例子大家就明白了,比如說千牛客戶端,每收到一條未讀的聊天消息,就會往通知欄發送一條通知(由于業務需要,通知id都是同一個),假如用戶收到了5條未讀消息,理論上來說千牛的角標數字應該顯示5,但是在小米機型上你會驚奇地發現角標數字居然是1。這是因為默認情況下,應用的角標數字跟應用往通知欄發送的通知數( 注意!這個通知數是根據通知id來計算的 )相對應的,在剛剛說的場景中, 雖然千牛往通知欄發送了5條通知,但是按照通知id來統計時,對應的通知數就是1,所以角標數字也就顯示成1了 。
小米官方可能也意識到了,這個奇葩的設計會導致很多用戶產生困惑,所以在官方文檔中也提供了修改角標數的接口。不同于其他手機系統通過廣播來修改角標,小米系統是通過反射機制來修改角標,關鍵代碼參考如下:
Field field = notification.getClass().getDeclaredField("extraNotification");
Object extraNotification = field.get(notification);
Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
method.invoke(extraNotification, unreadCount);
OPPO系列
抱歉,沒有發現官方文檔。
聯系過oppo的開發者客服,客服MM表示:
oppo角標提醒目前只針對內部軟件還有微信、QQ開放,其他的暫時無法提供
啊,多么痛的領悟~不過客服MM也及時發了一張好人卡:
后續應該會計劃對其他應用開放的,敬請關注我們的開發平臺
嗯,雖然被拒絕了,但是希望還是有的,那就繼續關注 oppo開發者官網 吧~
VIVO系列
抱歉,沒有發現官方文檔。
不過最近有幸在網上看到一段代碼,據說能支持vivo角標展示,抱著“死馬當作活馬醫”的心態,我嘗試了一把,最后發現居然奏效了。不多說了,貼代碼共賞之:
Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
intent.putExtra("packageName", context.getPackageName());
String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
intent.putExtra("className", launchClassName);
intent.putExtra("notificationNum", msgCount);
context.sendBroadcast(intent);
Sony系列
參考資料: https://developer.sony.com/2016/06/23/xperia-home-badge-api-now-publicly-available/
來自:http://www.jianshu.com/p/f429777f798d