Android 桌面角标在各大品牌机型上的实现

转自http://blog.csdn.net/uyy203/article/details/70160752?locationNum=15&fps=1

由于角标在Android原生的系统中没有支持,所以各个Android手机厂商各自为政。

正如很多资料所说,这一功能完全是效仿IOS,Android本不存在的,对于不支持的厂商如魅族、中兴、酷派,必须为他们不盲目跟风而点赞。

做起适配来,真的很麻烦,要针对各个厂商逐个去写以及测试。

目前做到支持小米、华为、三星、LG、VIVO、ZUK、HTC、NOVA等厂商的Andorid系统

效果如下图所示

Android 桌面角标在各大品牌机型上的实现_第1张图片





特别说明一下小米自MIUI6.0以后,角标的显示和通知栏Notification绑在一起。目前我发现的做法,就只有小米需要和Notification绑在一起才能生效。

不过我在这里的例子因产品需求,全部机型的做法都把Notification绑上。



消息通知ID

[java] view plain copy
  1. private int MQTT_IM_NOTIFICATION_ID=1007

通知栏Notification的定义
[java] view plain copy
  1. String content = 2 + "个联系人发了" + i + "条消息";  
  2. NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());  
  3. builder.setSmallIcon(R.drawable.chat_notify_icon);  
  4. builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));  
  5. builder.setTicker("收到" + i + "条消息");  
  6. builder.setWhen(System.currentTimeMillis());  
  7. Intent intent = new Intent(getBaseContext(), MainActivity.class);  
  8.   
  9. intent.setAction(getApplicationContext().getPackageName());  
  10. intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
  11. PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);  
  12. builder.setContentIntent(pi);  
  13. builder.setContentTitle(getResources().getText(R.string.app_name));  
  14. builder.setContentText(content);  
  15.   
  16. final Notification n = builder.build();  
  17. int defaults = Notification.DEFAULT_LIGHTS;  
  18.   
  19. defaults |= Notification.DEFAULT_SOUND;  
  20.   
  21. defaults |= Notification.DEFAULT_VIBRATE;  
  22.   
  23.   
  24. n.defaults = defaults;  
  25. n.flags = Notification.FLAG_SHOW_LIGHTS | Notification.FLAG_AUTO_CANCEL;  



厂商

[java] view plain copy
  1. private static String SYSTEM_XIAOMI="XIAOMI";  
  2. private static String SYSTEM_SAMSUNG="SAMSUNG";  
  3. private static String SYSTEM_HUAWEI_HONOR="HONOR";  
  4. private static String SYSTEM_HUAWEI="HUAWEI";  
  5. private static String SYSTEM_NOVA="NOVA";  
  6. private static String SYSTEM_SONY="SONY";  
  7. private static String SYSTEM_VIVO="VIVO";  
  8. private static String SYSTEM_OPPO="OPPO";  
  9. private static String SYSTEM_LG="LG";  
  10. private static String SYSTEM_ZUK="ZUK";  
  11. private static String SYSTEM_HTC="HTC";  


厂商获取

[java] view plain copy
  1. OSName=android.os.Build.BRAND.trim().toUpperCase();  


类名的获取

主要是得到Activity名字,得到完整的包名、类名

[java] view plain copy
  1. //获取类名  
  2. public static String getLauncherClassName(Context context) {  
  3.     PackageManager packageManager = context.getPackageManager();  
  4.     Intent intent = new Intent(Intent.ACTION_MAIN);  
  5.     intent.setPackage(context.getPackageName());  
  6.     intent.addCategory(Intent.CATEGORY_LAUNCHER);  
  7.     ResolveInfo info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);  
  8.     if (info == null) {  
  9.         info = packageManager.resolveActivity(intent, 0);  
  10.     }  
  11.     return info.activityInfo.name;  
  12. }  


广播

[java] view plain copy
  1. //广播  
  2. public static boolean canResolveBroadcast(Context context, Intent intent) {  
  3.     PackageManager packageManager = context.getPackageManager();  
  4.     List receivers = packageManager.queryBroadcastReceivers(intent, 0);  
  5.     return receivers != null && receivers.size() > 0;  
  6. }  





小米

特别注意,小米的通知栏提示需要延时操作才会出现角标,但是偶尔还是没法出现,暂时没有特别好的解决办法,不过目前能保证做到较高的成功率。

除了小米以外,其他实现基本没什么问题。

[java] view plain copy
  1.     //小米  
  2.     private static void setBadgeOfXiaomi(final Context context,final Notification notification,final int NOTIFI_ID,final int  num){  
  3.   
  4.   
  5.         new Handler().postDelayed(new Runnable() {  
  6.   
  7.             @Override  
  8.             public void run() {  
  9.   
  10.   
  11.                 try {  
  12.   
  13.                     Field field = notification.getClass().getDeclaredField("extraNotification");  
  14.   
  15.                     Object extraNotification = field.get(notification);  
  16.   
  17.                     Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount"int.class);  
  18.   
  19.                     method.invoke(extraNotification, num);  
  20.   
  21.                 } catch (Exception e) {  
  22.   
  23.                     e.printStackTrace();  
  24.                     Log.e("Xiaomi" + " Badge error""set Badge failed");  
  25.   
  26.                 }  
  27.   
  28. //                mNotificationManager.notify(0,notification);  
  29.                 NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  30.                 if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  31.   
  32.   
  33.             }  
  34.         },550);  
  35.   
  36.     }  


三星 & LG

[java] view plain copy
  1. //三星和LG  
  2.  private static void setBadgeOfSamsung(Context context,Notification notification, int NOTIFI_ID,int num) {  
  3.      // 获取你当前的应用  
  4.      String launcherClassName = getLauncherClassName(context);  
  5.      if (launcherClassName == null) {  
  6.          return;  
  7.      }  
  8.   
  9.      try {  
  10.          Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");  
  11.          intent.putExtra("badge_count", num);  
  12.          intent.putExtra("badge_count_package_name", context.getPackageName());  
  13.          intent.putExtra("badge_count_class_name", launcherClassName);  
  14.          context.sendBroadcast(intent);  
  15.   
  16.          NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  17.          if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  18.   
  19.   
  20.      }catch (Exception e){  
  21.          e.printStackTrace();  
  22.          Log.e("SAMSUNG" + " Badge error""set Badge failed");  
  23.      }  
  24.  }  


华为

华为及其荣耀系列通用,不需要官网认证

[java] view plain copy
  1.     //华为 系列  
  2.     private static void setBadgeOfHuaWei(Context context, Notification notification,int NOTIFI_ID,int num) {  
  3.   
  4.   
  5.         try{  
  6.             Bundle localBundle = new Bundle();  
  7.             localBundle.putString("package", context.getPackageName());  
  8.             localBundle.putString("class", getLauncherClassName(context));  
  9.             localBundle.putInt("badgenumber", num);  
  10.             context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge"null, localBundle);  
  11.   
  12.             NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  13.             if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  14.         }catch(Exception e){  
  15.             e.printStackTrace();  
  16.             Log.e("HUAWEI" + " Badge error""set Badge failed");  
  17.         }  
  18.   
  19. }  



索尼
[java] view plain copy
  1.     //索尼  
  2.     private static void setBadgeOfSony(Context context,Notification notification,int NOTIFI_ID, int num){  
  3.         String numString="";  
  4.         String activityName = getLauncherClassName(context);  
  5.         if (activityName == null){  
  6.             return;  
  7.         }  
  8.         Intent localIntent = new Intent();  
  9. //        int numInt = Integer.valueOf(num);  
  10.         boolean isShow = true;  
  11.         if (num < 1){  
  12.             numString = "";  
  13.             isShow = false;  
  14.         }else if (num > 99){  
  15.             numString = "99";  
  16.         }  
  17.   
  18.         try {  
  19.             localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", isShow);  
  20.             localIntent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");  
  21.             localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", activityName);  
  22.             localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", numString);  
  23.             localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());  
  24.             context.sendBroadcast(localIntent);  
  25.   
  26.             NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  27.             if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  28.   
  29.   
  30.         }catch (Exception e){  
  31.             e.printStackTrace();  
  32.             Log.e("SONY" + " Badge error""set Badge failed");  
  33.         }  
  34.     }  


VIVO

[java] view plain copy
  1. //VIVO  
  2. private static void setBadgeOfVIVO(Context context,Notification notification,int NOTIFI_ID,int num){  
  3.     try {  
  4.         Intent localIntent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");  
  5.         localIntent.putExtra("packageName", context.getPackageName());  
  6.         localIntent.putExtra("className", getLauncherClassName(context));  
  7.         localIntent.putExtra("notificationNum", num);  
  8.         context.sendBroadcast(localIntent);  
  9.   
  10.         NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  11.         if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  12.   
  13.     }catch (Exception e){  
  14.         e.printStackTrace();  
  15.         Log.e("VIVO" + " Badge error""set Badge failed");  
  16.     }  
  17. }  


OPPO

目前只支持部分机型

[java] view plain copy
  1. //OPPO *只支持部分机型  
  2.  private static void setBadgeOfOPPO(Context context, Notification notification,int NOTIFI_ID,int num){  
  3.      try {  
  4.   
  5.          if (num == 0) {  
  6.              num = -1;  
  7.          }  
  8.   
  9.          Intent intent = new Intent("com.oppo.unsettledevent");  
  10.          intent.putExtra("pakeageName", context.getPackageName());  
  11.          intent.putExtra("number", num);  
  12.          intent.putExtra("upgradeNumber", num);  
  13.          if (canResolveBroadcast(context, intent)) {  
  14.              context.sendBroadcast(intent);  
  15.          } else {  
  16.   
  17.                  try {  
  18.                      Bundle extras = new Bundle();  
  19.                      extras.putInt("app_badge_count", num);  
  20.                      context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount"null, extras);  
  21.   
  22.                      NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  23.                      if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  24.   
  25.   
  26.                  } catch (Throwable th) {  
  27.                      Log.e("OPPO" + " Badge error""unable to resolve intent: " + intent.toString());  
  28.                  }  
  29.          }  
  30.   
  31.      }catch (Exception e){  
  32.          e.printStackTrace();  
  33.          Log.e("OPPO" + " Badge error""set Badge failed");  
  34.      }  
  35.  }  


ZUK
[java] view plain copy
  1. //ZUK  
  2.  private static void setBadgeOfZUK(Context context,Notification notification,int NOTIFI_ID, int num){  
  3.       final Uri CONTENT_URI = Uri.parse("content://com.android.badge/badge");  
  4.      try {  
  5.          Bundle extra = new Bundle();  
  6.          extra.putInt("app_badge_count", num);  
  7.          context.getContentResolver().call(CONTENT_URI, "setAppBadgeCount"null, extra);  
  8.   
  9.          NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  10.          if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  11.   
  12.   
  13.      }catch (Exception e){  
  14.          e.printStackTrace();  
  15.          Log.e("ZUK" + " Badge error""set Badge failed");  
  16.      }  
  17.   
  18.  }  


HTC
[java] view plain copy
  1. //HTC  
  2. private static void setBadgeOfHTC(Context context,Notification notification,int NOTIFI_ID,int num){  
  3.   
  4.     try {  
  5.         Intent intent1 = new Intent("com.htc.launcher.action.SET_NOTIFICATION");  
  6.         intent1.putExtra("com.htc.launcher.extra.COMPONENT", context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().flattenToShortString());  
  7.         intent1.putExtra("com.htc.launcher.extra.COUNT", num);  
  8.   
  9.         Intent intent = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT");  
  10.         intent.putExtra("packagename", context.getPackageName());  
  11.         intent.putExtra("count", num);  
  12.   
  13.         if (canResolveBroadcast(context, intent1) || canResolveBroadcast(context, intent)) {  
  14.             context.sendBroadcast(intent1);  
  15.             context.sendBroadcast(intent);  
  16.         } else {  
  17.             Log.e("HTC" + " Badge error""unable to resolve intent: " + intent.toString());  
  18.         }  
  19.   
  20.         NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  21.         if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  22.   
  23.   
  24.     }catch (Exception e){  
  25.         e.printStackTrace();  
  26.         Log.e("HTC" + " Badge error""set Badge failed");  
  27.     }  
  28.   
  29. }  


NOVA

[java] view plain copy
  1. //NOVA  
  2. private static void setBadgeOfNOVA(Context context,Notification notification,int NOTIFI_ID,int num){  
  3.     try{  
  4.         ContentValues contentValues = new ContentValues();  
  5.         contentValues.put("tag", context.getPackageName()+ "/" +getLauncherClassName(context));  
  6.         contentValues.put("count", num);  
  7.         context.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"), contentValues);  
  8.   
  9.         NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  10.         if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  11.   
  12.   
  13.     }catch (Exception e){  
  14.         e.printStackTrace();  
  15.         Log.e("NOVA" + " Badge error""set Badge failed");  
  16.     }  
  17. }  


其他

做个备案吧,这个真不一定能生效,只能从大多数的做法里摸规律

[java] view plain copy
  1. //其他  
  2. private static void setBadgeOfDefault(Context context,Notification notification,int NOTIFI_ID,int num){  
  3.   
  4.     try {  
  5.         Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");  
  6.         intent.putExtra("badge_count", num);  
  7.         intent.putExtra("badge_count_package_name", context.getPackageName());  
  8.         intent.putExtra("badge_count_class_name", getLauncherClassName(context));  
  9.         if (canResolveBroadcast(context, intent)) {  
  10.             context.sendBroadcast(intent);  
  11.         } else {  
  12.             Log.e("Default" + " Badge error""unable to resolve intent: " + intent.toString());  
  13.         }  
  14.   
  15.         NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));  
  16.         if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);  
  17.   
  18.   
  19.     }catch (Exception e){  
  20.         e.printStackTrace();  
  21.             Log.e("Default" + " Badge error""set Badge failed");  
  22.     }  
  23.   
  24. }  



你可能感兴趣的:(Android,应用角标)