成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android探索之旅 | 為應用添加角標(Badge)

移動開發 Android
角標,英語是badge,也就是“徽章,像章,獎章; 象征,標記”的意思。一般來說,應用的角標是用來標記有多少條提醒(Notification)沒讀(unread),一旦點擊提示進應用閱讀了,角標也會消失。

[[184821]]

– 簡書作者 謝恩銘 轉載請注明出處

需求簡介

角標是什么意思呢?

看下圖即可明了:   

 

可以看到圖中的樂購這個app右上角的紅色的圓圈,里面有10這個數字的,就是一種角標。

角標,英語是badge,也就是“徽章,像章,獎章; 象征,標記”的意思。

一般來說,應用的角標是用來標記有多少條提醒(Notification)沒讀(unread),一旦點擊提示進應用閱讀了,角標也會消失。

Android角標起源

角標原本是蘋果的iOS中的東西,Android原生并不支持角標,因為Google的意思是讓大家用Notification(提示欄)即可,角標實在大有讓處女座“跳崖”的風險。幸好我不是…

最近公司的項目中,客戶的一個新需求是在我們的加密信息應用上加上角標功能,因為我們的合作伙伴是三星(可以參看我的這篇文章:程序員在法國 | 我被法國國防部盯上了!),因此我就去網上找相關資料。

找的時候,才知道上面所說的Android原生不支持角標一事。不過無妨,厲害的Android第三方廠商可以通過在自定義的Launcher(啟動器)中操作來實現添加角標。

我在第一時間當然是去找三星的移動設備如何添加角標,不過卻有幸找到了Github上的比較普適的項目。

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

不錯的github項目

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

添加角標的原理就是發送一個Broadcast(廣播),在廣播的Intent中指定需要被添加角標的應用的packageName(包名),className(類名),count(角標數目)。當然了,不同廠商的手機的角標操作的Intent的action是不一樣的。

因此,我們如果要給自己的手機里的應用添加角標,只需要簡單的利用上面兩個項目中的代碼即可,一般不需要把全部項目搬過來。當然了,如果你要適配所有手機,那么可以全盤引用項目。

比如我要給三星的手機的應用添加角標,那么我只需要做以下的幾步即可:

在AndroidManifest.xml中添加讀取和寫入角標的權限:

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

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

  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.  

使用上面的代碼時,只需要傳入三個參數,也就是:

  1. Context : 應用的Context。簡單。
  2. ComponentName :組件名,略有點麻煩。可以這樣來獲取(applicationContext就是應用的Context) :
    1. applicationContext.getPackageManager() 
    2. .getLaunchIntentForPackage(applicationContext.getPackageName()) 
    3. .getComponent() 
  3. badgeCount :角標的數目,例如10。簡單。

當然了,如果你不想要傳入三個參數這么麻煩,你也可以再寫一個方法getLauncherClassName,就只需要傳入兩個參數即可。BadgeUtils中的代碼變為: 

  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.  

使用時傳入兩個參數即可:

  1. Context : 應用的Context。
  2. badgeCount :角標的數目,例如10。

清除角標

要清除應用的角標就很簡單了,給badgeCount傳入0即可。

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

或者

  1. BadgeUtils.setBadgeCount(context, 0); 

小問題糾錯

上面的 https://github.com/leolin310148/ShortcutBadger 這個項目中,基本已經包含了大多數可以定制角標的Android生產廠商的添加角標的代碼實現,不過它也提到:

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

  1. "android.intent.action.BADGE_COUNT_UPDATE" 

但是作者在三星和LG的兩個角標操作實現類中寫了注釋:

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

意思是“三星和LG的實現代碼已經Deprecated(失效了),請用DefaultBadger類”。

因此,這兩個需要用 https://github.com/leolin310148/ShortcutBadger/blob/master/ShortcutBadger/src/main/java/me/leolin/shortcutbadger/impl/DefaultBadger.java 中的實現:

  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.  

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

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

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

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

解決辦法是去除這一個檢測,把

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

替換為簡單的

  1. context.sendBroadcast(intent); 

就可以了。

也就是我上面自己實作時的代碼。

總結

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

2023-06-28 10:48:09

平臺框架高性能

2010-05-06 17:56:15

Visual Stud

2010-02-24 15:04:54

Visual Stud

2015-11-05 17:38:32

東方通蘇州工業園大數據應用

2022-10-14 16:30:17

2012-07-30 09:41:04

Android搜索功能

2017-04-18 13:55:24

運維云計算WOT

2019-09-25 11:27:07

區塊鏈比特幣加密貨幣

2020-10-10 14:36:10

Python

2020-10-12 00:41:52

Python變量

2015-03-05 11:28:51

Linux桌面環境終極指南

2013-10-15 15:17:47

程序員數據挖掘

2020-10-11 23:45:55

Python解釋器

2023-07-26 11:22:44

騰訊趙裕

2025-02-07 14:42:59

2021-09-15 10:19:15

鴻蒙HarmonyOS應用

2020-06-12 09:20:33

前端Blob字符串

2021-10-14 08:07:33

Go 應用Prometheus監控

2021-03-08 16:12:35

AIOpsIT人工智能

2022-06-15 22:15:47

CSS視覺還原
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品久久一区 | 日韩视频免费看 | 精品一二三区 | 国产亚洲一区二区三区 | 中日韩av | 日本一区二区三区在线观看 | 久久久高清 | 新超碰97 | 日本国产一区二区 | 91欧美精品| 亚洲激情综合网 | 一区| 亚洲www啪成人一区二区麻豆 | 色视频成人在线观看免 | 又爽又黄axxx片免费观看 | 久草中文在线观看 | 亚洲精品黄色 | 欧美久久久久久久久中文字幕 | 久久精品国产一区二区三区不卡 | 欧洲视频一区 | 中文字幕亚洲一区二区三区 | 国产精品视频在线播放 | 亚洲成人免费 | 亚洲精品欧美 | 免费日韩网站 | 久久国内精品 | 日本 欧美 国产 | www国产精品 | 日本视频一区二区三区 | 国产精品日韩欧美一区二区三区 | 人人人人人爽 | 亚洲欧美中文日韩在线v日本 | 国产精品久久久久久久久久免费看 | 精品国产乱码久久久久久果冻传媒 | 亚洲精品视频在线 | 国产精品久久久久久网站 | 久久激情视频 | 国产精品精品视频一区二区三区 | 国产99精品| 国产精品伦理一区二区三区 | 欧美日韩中文字幕在线播放 |