转自http://blog.youkuaiyun.com/uyy203/article/details/70160752?locationNum=15&fps=1
通知栏Notification的定义
ZUK
HTC
由于角标在Android原生的系统中没有支持,所以各个Android手机厂商各自为政。
正如很多资料所说,这一功能完全是效仿IOS,Android本不存在的,对于不支持的厂商如魅族、中兴、酷派,必须为他们不盲目跟风而点赞。
做起适配来,真的很麻烦,要针对各个厂商逐个去写以及测试。
目前做到支持小米、华为、三星、LG、VIVO、ZUK、HTC、NOVA等厂商的Andorid系统
效果如下图所示
特别说明一下小米自MIUI6.0以后,角标的显示和通知栏Notification绑在一起。目前我发现的做法,就只有小米需要和Notification绑在一起才能生效。
不过我在这里的例子因产品需求,全部机型的做法都把Notification绑上。
消息通知ID
- private int MQTT_IM_NOTIFICATION_ID=1007;
通知栏Notification的定义
- String content = 2 + "个联系人发了" + i + "条消息";
- NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
- builder.setSmallIcon(R.drawable.chat_notify_icon);
- builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
- builder.setTicker("收到" + i + "条消息");
- builder.setWhen(System.currentTimeMillis());
- Intent intent = new Intent(getBaseContext(), MainActivity.class);
- intent.setAction(getApplicationContext().getPackageName());
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
- builder.setContentIntent(pi);
- builder.setContentTitle(getResources().getText(R.string.app_name));
- builder.setContentText(content);
- final Notification n = builder.build();
- int defaults = Notification.DEFAULT_LIGHTS;
- defaults |= Notification.DEFAULT_SOUND;
- defaults |= Notification.DEFAULT_VIBRATE;
- n.defaults = defaults;
- n.flags = Notification.FLAG_SHOW_LIGHTS | Notification.FLAG_AUTO_CANCEL;
厂商
- private static String SYSTEM_XIAOMI="XIAOMI";
- private static String SYSTEM_SAMSUNG="SAMSUNG";
- private static String SYSTEM_HUAWEI_HONOR="HONOR";
- private static String SYSTEM_HUAWEI="HUAWEI";
- private static String SYSTEM_NOVA="NOVA";
- private static String SYSTEM_SONY="SONY";
- private static String SYSTEM_VIVO="VIVO";
- private static String SYSTEM_OPPO="OPPO";
- private static String SYSTEM_LG="LG";
- private static String SYSTEM_ZUK="ZUK";
- private static String SYSTEM_HTC="HTC";
厂商获取
- OSName=android.os.Build.BRAND.trim().toUpperCase();
类名的获取
主要是得到Activity名字,得到完整的包名、类名
- //获取类名
- public static String getLauncherClassName(Context context) {
- PackageManager packageManager = context.getPackageManager();
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setPackage(context.getPackageName());
- intent.addCategory(Intent.CATEGORY_LAUNCHER);
- ResolveInfo info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
- if (info == null) {
- info = packageManager.resolveActivity(intent, 0);
- }
- return info.activityInfo.name;
- }
广播
- //广播
- public static boolean canResolveBroadcast(Context context, Intent intent) {
- PackageManager packageManager = context.getPackageManager();
- List<ResolveInfo> receivers = packageManager.queryBroadcastReceivers(intent, 0);
- return receivers != null && receivers.size() > 0;
- }
小米
特别注意,小米的通知栏提示需要延时操作才会出现角标,但是偶尔还是没法出现,暂时没有特别好的解决办法,不过目前能保证做到较高的成功率。
除了小米以外,其他实现基本没什么问题。
- //小米
- private static void setBadgeOfXiaomi(final Context context,final Notification notification,final int NOTIFI_ID,final int num){
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- try {
- Field field = notification.getClass().getDeclaredField("extraNotification");
- Object extraNotification = field.get(notification);
- Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
- method.invoke(extraNotification, num);
- } catch (Exception e) {
- e.printStackTrace();
- Log.e("Xiaomi" + " Badge error", "set Badge failed");
- }
- // mNotificationManager.notify(0,notification);
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }
- },550);
- }
三星 & LG
- //三星和LG
- private static void setBadgeOfSamsung(Context context,Notification notification, int NOTIFI_ID,int num) {
- // 获取你当前的应用
- String launcherClassName = getLauncherClassName(context);
- if (launcherClassName == null) {
- return;
- }
- try {
- Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
- intent.putExtra("badge_count", num);
- intent.putExtra("badge_count_package_name", context.getPackageName());
- intent.putExtra("badge_count_class_name", launcherClassName);
- context.sendBroadcast(intent);
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }catch (Exception e){
- e.printStackTrace();
- Log.e("SAMSUNG" + " Badge error", "set Badge failed");
- }
- }
华为
华为及其荣耀系列通用,不需要官网认证
- //华为 系列
- private static void setBadgeOfHuaWei(Context context, Notification notification,int NOTIFI_ID,int num) {
- try{
- Bundle localBundle = new Bundle();
- localBundle.putString("package", context.getPackageName());
- localBundle.putString("class", getLauncherClassName(context));
- localBundle.putInt("badgenumber", num);
- context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, localBundle);
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }catch(Exception e){
- e.printStackTrace();
- Log.e("HUAWEI" + " Badge error", "set Badge failed");
- }
- }
- //索尼
- private static void setBadgeOfSony(Context context,Notification notification,int NOTIFI_ID, int num){
- String numString="";
- String activityName = getLauncherClassName(context);
- if (activityName == null){
- return;
- }
- Intent localIntent = new Intent();
- // int numInt = Integer.valueOf(num);
- boolean isShow = true;
- if (num < 1){
- numString = "";
- isShow = false;
- }else if (num > 99){
- numString = "99";
- }
- try {
- localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", isShow);
- localIntent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
- localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", activityName);
- localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", numString);
- localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());
- context.sendBroadcast(localIntent);
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }catch (Exception e){
- e.printStackTrace();
- Log.e("SONY" + " Badge error", "set Badge failed");
- }
- }
VIVO
- //VIVO
- private static void setBadgeOfVIVO(Context context,Notification notification,int NOTIFI_ID,int num){
- try {
- Intent localIntent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
- localIntent.putExtra("packageName", context.getPackageName());
- localIntent.putExtra("className", getLauncherClassName(context));
- localIntent.putExtra("notificationNum", num);
- context.sendBroadcast(localIntent);
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }catch (Exception e){
- e.printStackTrace();
- Log.e("VIVO" + " Badge error", "set Badge failed");
- }
- }
OPPO
目前只支持部分机型
- //OPPO *只支持部分机型
- private static void setBadgeOfOPPO(Context context, Notification notification,int NOTIFI_ID,int num){
- try {
- if (num == 0) {
- num = -1;
- }
- Intent intent = new Intent("com.oppo.unsettledevent");
- intent.putExtra("pakeageName", context.getPackageName());
- intent.putExtra("number", num);
- intent.putExtra("upgradeNumber", num);
- if (canResolveBroadcast(context, intent)) {
- context.sendBroadcast(intent);
- } else {
- try {
- Bundle extras = new Bundle();
- extras.putInt("app_badge_count", num);
- context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", null, extras);
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- } catch (Throwable th) {
- Log.e("OPPO" + " Badge error", "unable to resolve intent: " + intent.toString());
- }
- }
- }catch (Exception e){
- e.printStackTrace();
- Log.e("OPPO" + " Badge error", "set Badge failed");
- }
- }
ZUK
- //ZUK
- private static void setBadgeOfZUK(Context context,Notification notification,int NOTIFI_ID, int num){
- final Uri CONTENT_URI = Uri.parse("content://com.android.badge/badge");
- try {
- Bundle extra = new Bundle();
- extra.putInt("app_badge_count", num);
- context.getContentResolver().call(CONTENT_URI, "setAppBadgeCount", null, extra);
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }catch (Exception e){
- e.printStackTrace();
- Log.e("ZUK" + " Badge error", "set Badge failed");
- }
- }
HTC
- //HTC
- private static void setBadgeOfHTC(Context context,Notification notification,int NOTIFI_ID,int num){
- try {
- Intent intent1 = new Intent("com.htc.launcher.action.SET_NOTIFICATION");
- intent1.putExtra("com.htc.launcher.extra.COMPONENT", context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().flattenToShortString());
- intent1.putExtra("com.htc.launcher.extra.COUNT", num);
- Intent intent = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT");
- intent.putExtra("packagename", context.getPackageName());
- intent.putExtra("count", num);
- if (canResolveBroadcast(context, intent1) || canResolveBroadcast(context, intent)) {
- context.sendBroadcast(intent1);
- context.sendBroadcast(intent);
- } else {
- Log.e("HTC" + " Badge error", "unable to resolve intent: " + intent.toString());
- }
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }catch (Exception e){
- e.printStackTrace();
- Log.e("HTC" + " Badge error", "set Badge failed");
- }
- }
NOVA
- //NOVA
- private static void setBadgeOfNOVA(Context context,Notification notification,int NOTIFI_ID,int num){
- try{
- ContentValues contentValues = new ContentValues();
- contentValues.put("tag", context.getPackageName()+ "/" +getLauncherClassName(context));
- contentValues.put("count", num);
- context.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"), contentValues);
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }catch (Exception e){
- e.printStackTrace();
- Log.e("NOVA" + " Badge error", "set Badge failed");
- }
- }
其他
做个备案吧,这个真不一定能生效,只能从大多数的做法里摸规律
- //其他
- private static void setBadgeOfDefault(Context context,Notification notification,int NOTIFI_ID,int num){
- try {
- Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
- intent.putExtra("badge_count", num);
- intent.putExtra("badge_count_package_name", context.getPackageName());
- intent.putExtra("badge_count_class_name", getLauncherClassName(context));
- if (canResolveBroadcast(context, intent)) {
- context.sendBroadcast(intent);
- } else {
- Log.e("Default" + " Badge error", "unable to resolve intent: " + intent.toString());
- }
- NotificationManager notifyMgr = (NotificationManager)(context.getSystemService(NOTIFICATION_SERVICE));
- if(num!=0)notifyMgr.notify(NOTIFI_ID, notification);else notifyMgr.cancel(NOTIFI_ID);
- }catch (Exception e){
- e.printStackTrace();
- Log.e("Default" + " Badge error", "set Badge failed");
- }
- }