自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android探索之旅 | 為應(yīng)用添加角標(biāo)(Badge)

移動(dòng)開發(fā) Android
角標(biāo),英語(yǔ)是badge,也就是“徽章,像章,獎(jiǎng)?wù)? 象征,標(biāo)記”的意思。一般來(lái)說,應(yīng)用的角標(biāo)是用來(lái)標(biāo)記有多少條提醒(Notification)沒讀(unread),一旦點(diǎn)擊提示進(jìn)應(yīng)用閱讀了,角標(biāo)也會(huì)消失。

[[184821]]

– 簡(jiǎn)書作者 謝恩銘 轉(zhuǎn)載請(qǐng)注明出處

需求簡(jiǎn)介

角標(biāo)是什么意思呢?

看下圖即可明了:   

 

可以看到圖中的樂購(gòu)這個(gè)app右上角的紅色的圓圈,里面有10這個(gè)數(shù)字的,就是一種角標(biāo)。

角標(biāo),英語(yǔ)是badge,也就是“徽章,像章,獎(jiǎng)?wù)? 象征,標(biāo)記”的意思。

一般來(lái)說,應(yīng)用的角標(biāo)是用來(lái)標(biāo)記有多少條提醒(Notification)沒讀(unread),一旦點(diǎn)擊提示進(jìn)應(yīng)用閱讀了,角標(biāo)也會(huì)消失。

Android角標(biāo)起源

角標(biāo)原本是蘋果的iOS中的東西,Android原生并不支持角標(biāo),因?yàn)镚oogle的意思是讓大家用Notification(提示欄)即可,角標(biāo)實(shí)在大有讓處女座“跳崖”的風(fēng)險(xiǎn)。幸好我不是…

最近公司的項(xiàng)目中,客戶的一個(gè)新需求是在我們的加密信息應(yīng)用上加上角標(biāo)功能,因?yàn)槲覀兊暮献骰锇槭侨?可以參看我的這篇文章:程序員在法國(guó) | 我被法國(guó)國(guó)防部盯上了!),因此我就去網(wǎng)上找相關(guān)資料。

找的時(shí)候,才知道上面所說的Android原生不支持角標(biāo)一事。不過無(wú)妨,厲害的Android第三方廠商可以通過在自定義的Launcher(啟動(dòng)器)中操作來(lái)實(shí)現(xiàn)添加角標(biāo)。

我在第一時(shí)間當(dāng)然是去找三星的移動(dòng)設(shè)備如何添加角標(biāo),不過卻有幸找到了Github上的比較普適的項(xiàng)目。

把我導(dǎo)向Github的自然是Stack Overflow,而把我導(dǎo)向Stack Overflow的就是Google,因此我會(huì)說:為什么程序員一定要會(huì)用Google和Stack Overflow? 。

不錯(cuò)的github項(xiàng)目

  1. 一般來(lái)說,現(xiàn)在被引用最多的Android添加和去除角標(biāo)的Github項(xiàng)目是這位中國(guó)人寫的:https://github.com/leolin310148/ShortcutBadger這個(gè)項(xiàng)目挺不錯(cuò),雖然更新不是特別勤快,但最近一次更新是在2016年10月31日,也就是兩個(gè)月前,還可以接受。
  2. 《Android群英傳》和《Android群英傳:神兵利器》的作者 徐宣生 也在自己的Github上建了一個(gè)項(xiàng)目:https://github.com/xuyisheng/ShortcutHelper ,挺有意思,里面還有號(hào)稱“瘋狂模式”的為所有在手機(jī)桌面上的應(yīng)用加上99的角標(biāo)數(shù)的功能,當(dāng)然了,去除的代碼也有,不然處女座豈不是要暈了~

添加角標(biāo)的原理就是發(fā)送一個(gè)Broadcast(廣播),在廣播的Intent中指定需要被添加角標(biāo)的應(yīng)用的packageName(包名),className(類名),count(角標(biāo)數(shù)目)。當(dāng)然了,不同廠商的手機(jī)的角標(biāo)操作的Intent的action是不一樣的。

因此,我們?nèi)绻o自己的手機(jī)里的應(yīng)用添加角標(biāo),只需要簡(jiǎn)單的利用上面兩個(gè)項(xiàng)目中的代碼即可,一般不需要把全部項(xiàng)目搬過來(lái)。當(dāng)然了,如果你要適配所有手機(jī),那么可以全盤引用項(xiàng)目。

比如我要給三星的手機(jī)的應(yīng)用添加角標(biāo),那么我只需要做以下的幾步即可:

在AndroidManifest.xml中添加讀取和寫入角標(biāo)的權(quán)限:

  1. <uses-permission android:name="com.sec.android.provider.badge.permission.READ" /> 
  2. <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />  

自己寫一個(gè)類,隨便取名字,比如叫做 BadgeUtils,在類中添加如下內(nèi)容:

  1. public class BadgeUtils { 
  2.   private static final String INTENT_ACTION = "android.intent.action.BADGE_COUNT_UPDATE"
  3.   private static final String INTENT_EXTRA_BADGE_COUNT = "badge_count"
  4.   private static final String INTENT_EXTRA_PACKAGENAME = "badge_count_package_name"
  5.   private static final String INTENT_EXTRA_ACTIVITY_NAME = "badge_count_class_name"
  6.  
  7.   public static void setBadgeCount(Context context, ComponentName componentName, int badgeCount) { 
  8.     Intent intent = new Intent(INTENT_ACTION);      
  9.     intent.putExtra(INTENT_EXTRA_BADGE_COUNT, badgeCount);     
  10.     intent.putExtra(INTENT_EXTRA_PACKAGENAME, componentName.getPackageName());     
  11.     intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName()); 
  12.     context.sendBroadcast(intent);   
  13.   } 
  14.  

使用上面的代碼時(shí),只需要傳入三個(gè)參數(shù),也就是:

  1. Context : 應(yīng)用的Context。簡(jiǎn)單。
  2. ComponentName :組件名,略有點(diǎn)麻煩??梢赃@樣來(lái)獲取(applicationContext就是應(yīng)用的Context) :
    1. applicationContext.getPackageManager() 
    2. .getLaunchIntentForPackage(applicationContext.getPackageName()) 
    3. .getComponent() 
  3. badgeCount :角標(biāo)的數(shù)目,例如10。簡(jiǎn)單。

當(dāng)然了,如果你不想要傳入三個(gè)參數(shù)這么麻煩,你也可以再寫一個(gè)方法getLauncherClassName,就只需要傳入兩個(gè)參數(shù)即可。BadgeUtils中的代碼變?yōu)椋?nbsp;

  1. public class BadgeUtils { 
  2.   private static final String INTENT_ACTION = "android.intent.action.BADGE_COUNT_UPDATE"
  3.   private static final String INTENT_EXTRA_BADGE_COUNT = "badge_count"
  4.   private static final String INTENT_EXTRA_PACKAGENAME = "badge_count_package_name"
  5.   private static final String INTENT_EXTRA_ACTIVITY_NAME = "badge_count_class_name"
  6.  
  7.   public static void setBadgeCount(Context context, int badgeCount) { 
  8.     String launcherClassName = getLauncherClassName(context); 
  9.     if (launcherClassName == null) { 
  10.       return
  11.     } 
  12.  
  13.     Intent intent = new Intent(INTENT_ACTION);      
  14.     intent.putExtra(INTENT_EXTRA_BADGE_COUNT, badgeCount);     
  15.     intent.putExtra(INTENT_EXTRA_PACKAGENAME, context.getPackageName());     
  16.     intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, launcherClassName); 
  17.  
  18.     context.sendBroadcast(intent);   
  19.   } 
  20.  
  21.   private static String getLauncherClassName(Context context) { 
  22.     PackageManager pm = context.getPackageManager(); 
  23.  
  24.     Intent intent = new Intent(Intent.ACTION_MAIN);  
  25.     intent.addCategory(Intent.CATEGORY_LAUNCHER); 
  26.  
  27.     List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0); 
  28.     for (ResolveInfo resolveInfo : resolveInfos) { 
  29.       String pkgName = resolveInfo.activityInfo.applicationInfo.packageName; 
  30.       if (pkgName.equalsIgnoreCase(context.getPackageName())) { 
  31.         String className = resolveInfo.activityInfo.name
  32.         return className; 
  33.       } 
  34.     } 
  35.     return null;  
  36.   } 
  37.  

使用時(shí)傳入兩個(gè)參數(shù)即可:

  1. Context : 應(yīng)用的Context。
  2. badgeCount :角標(biāo)的數(shù)目,例如10。

清除角標(biāo)

要清除應(yīng)用的角標(biāo)就很簡(jiǎn)單了,給badgeCount傳入0即可。

  1. BadgeUtils.setBadgeCount(context,        
  2. context.getPackageManager()                
  3. .getLaunchIntentForPackage(context.getPackageName())                 
  4. .getComponent(),         
  5. 0);  

或者

  1. BadgeUtils.setBadgeCount(context, 0); 

小問題糾錯(cuò)

上面的 https://github.com/leolin310148/ShortcutBadger 這個(gè)項(xiàng)目中,基本已經(jīng)包含了大多數(shù)可以定制角標(biāo)的Android生產(chǎn)廠商的添加角標(biāo)的代碼實(shí)現(xiàn),不過它也提到:

三星和LG(這兩個(gè)難兄難弟)的代碼有很多類似,連角標(biāo)處理的廣播的Intent中的action也是一樣的,都是:

  1. "android.intent.action.BADGE_COUNT_UPDATE" 

但是作者在三星和LG的兩個(gè)角標(biāo)操作實(shí)現(xiàn)類中寫了注釋:

  1. // Deprecated, Samsung devices will use DefaultBadger 
  2. // Deprecated, LG devices will use DefaultBadger  

意思是“三星和LG的實(shí)現(xiàn)代碼已經(jīng)Deprecated(失效了),請(qǐng)用DefaultBadger類”。

因此,這兩個(gè)需要用 https://github.com/leolin310148/ShortcutBadger/blob/master/ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/DefaultBadger.java 中的實(shí)現(xiàn):

  1. private static final String INTENT_ACTION = "android.intent.action.BADGE_COUNT_UPDATE"
  2. private static final String INTENT_EXTRA_BADGE_COUNT = "badge_count"
  3. private static final String INTENT_EXTRA_PACKAGENAME = "badge_count_package_name"
  4. private static final String INTENT_EXTRA_ACTIVITY_NAME = "badge_count_class_name"
  5.  
  6. @Override 
  7. public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException { 
  8.   Intent intent = new Intent(INTENT_ACTION); 
  9.   intent.putExtra(INTENT_EXTRA_BADGE_COUNT, badgeCount); 
  10.   intent.putExtra(INTENT_EXTRA_PACKAGENAME, componentName.getPackageName()); 
  11.   intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName()); 
  12.  
  13.   if (BroadcastHelper.canResolveBroadcast(context, intent)) { 
  14.     context.sendBroadcast(intent); 
  15.   } else { 
  16.     throw new ShortcutBadgeException("unable to resolve intent: " + intent.toString()); 
  17.   } 
  18.  

不過上面的代碼有一個(gè)小問題,就是那句

  1. if (BroadcastHelper.canResolveBroadcast(context, intent)) { 

在有些設(shè)備(比如Samsung Galaxy S5)上會(huì)拋出異常(Exception),找不到處理”android.intent.action.BADGE_COUNT_UPDATE”這個(gè)Intent的BroadcastReceiver,很奇怪。

但有些設(shè)備(比如Samsung Galaxy A5)上又運(yùn)行正常,沒有拋出異常。

解決辦法是去除這一個(gè)檢測(cè),把

  1. if (BroadcastHelper.canResolveBroadcast(context, intent)) { 
  2.   context.sendBroadcast(intent); 
  3. else { 
  4.   throw new ShortcutBadgeException("unable to resolve intent: " + intent.toString()); 
  5.  

替換為簡(jiǎn)單的

  1. context.sendBroadcast(intent); 

就可以了。

也就是我上面自己實(shí)作時(shí)的代碼。

總結(jié)

  1. Android的角標(biāo)添加和移除畢竟是基于各大手機(jī)廠商的Launcher的定制,因此不是正統(tǒng)的Android技巧,隨著廠商的Launcher的改變,也許你的代碼未來(lái)就不一定有用了,因此需要不斷修改,“推陳出新”。
  2. 不過正所謂“生命在于折騰”,而這也是我們喜歡Android系統(tǒng)的原因。這個(gè)萌萌的機(jī)器人可以經(jīng)得起我們隨意折騰,在嵌入式領(lǐng)域的應(yīng)用前途也是很不錯(cuò)的。
  3. 大家在平時(shí)學(xué)習(xí)編程的時(shí)候,也可以把自己的代碼或經(jīng)驗(yàn)匯總到Github項(xiàng)目,一來(lái)惠己利人,二來(lái)提高自己的業(yè)界知名度。
責(zé)任編輯:龐桂玉 來(lái)源: Android開發(fā)中文站
相關(guān)推薦

2023-06-28 10:48:09

平臺(tái)框架高性能

2010-02-24 15:04:54

Visual Stud

2010-05-06 17:56:15

Visual Stud

2015-11-05 17:38:32

東方通蘇州工業(yè)園大數(shù)據(jù)應(yīng)用

2022-10-14 16:30:17

2012-07-30 09:41:04

Android搜索功能

2017-04-18 13:55:24

運(yùn)維云計(jì)算WOT

2019-09-25 11:27:07

區(qū)塊鏈比特幣加密貨幣

2020-10-10 14:36:10

Python

2015-03-05 11:28:51

Linux桌面環(huán)境終極指南

2020-10-12 00:41:52

Python變量

2020-10-11 23:45:55

Python解釋器

2023-07-26 11:22:44

騰訊趙裕

2021-09-15 10:19:15

鴻蒙HarmonyOS應(yīng)用

2013-10-15 15:17:47

程序員數(shù)據(jù)挖掘

2025-02-07 14:42:59

2020-06-12 09:20:33

前端Blob字符串

2021-10-14 08:07:33

Go 應(yīng)用Prometheus監(jiān)控

2022-06-15 22:15:47

CSS視覺還原

2021-03-08 16:12:35

AIOpsIT人工智能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)