是否支持角标并不与手机厂商有关,而是你当前使用的launcher开发厂商有关。

方法实现:

import android.app.Application;
import android.app.Notification;
import android.content.Intent;
import android.support.annotation.NonNull; /**
*谷歌
*/
public class GoogleModelImpl implements IconBadgeNumModel {
private static final String NOTIFICATION_ERROR = "google not support before API O"; @Override
public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
throw new Exception(NOTIFICATION_ERROR);
}
Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
intent.putExtra("badge_count", count);
intent.putExtra("badge_count_package_name", context.getPackageName());
intent.putExtra("badge_count_class_name", Utils.getInstance().getLaunchIntentForPackage(context)); // com.test. badge.MainActivity is your apk main activity // if (Utils.getInstance().canResolveBroadcast(context, intent)) {
context.sendBroadcast(intent);
// } else {
// throw new Exception(UNABLE_TO_RESOLVE_INTENT_ERROR_ + intent.toString());
// } return notification;
} }
import android.app.Application;
import android.app.Notification;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull; /**
* https://developer.huawei.com/consumer/cn/devservice/doc/30802
* <p>
* 华为
*/
public class HuaWeiModelImpl implements IconBadgeNumModel {
@Override
public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
Bundle bunlde = new Bundle();
bunlde.putString("package", context.getPackageName()); // com.test.badge is your package name
bunlde.putString("class", Utils.getInstance().getLaunchIntentForPackage(context)); // com.test. badge.MainActivity is your apk main activity
bunlde.putInt("badgenumber", count);
context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bunlde);
return notification;
}
}
import android.app.Application;
import android.app.Notification;
import android.support.annotation.NonNull;
//魅族
public class MeizuModelImpl implements IconBadgeNumModel {
private static final String NOTIFICATION_ERROR = "not support : meizu"; @Override
public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
if (true) {
throw new Exception(NOTIFICATION_ERROR);
}
return null;
}
}
import android.app.Application;
import android.app.Notification;
import android.support.annotation.NonNull; /**
* 以下是oppo客服原文(其中没有说明3.3中日活量和总下载量的标准)
* <p>
* 亲,您可以通过邮件的形式提交申请,邮件形式如下:
* <p>
* 1.主题:“申请开放OPPO手机应用角标权限——(应用名称)”
* <p>
* 2.收件人:devtec@oppo.com
* <p>
* 3.正文:应用角标申请所需材料
* 以下为应用角标申请所需材料:
* 1.应用方申请人基本信息(姓名、邮箱、手机、微信);
* 2.应用方厂商介绍(不少于200字);
* 3.申请应用近一个月内IOS与安卓系统的平均日活量及总下载量介绍;
* 4.申请应用产品主要功能介绍(不少于100字);
* 5.申请应用期望角标出现的全部场景。(即哪些类的消息需要出现角标,需全部列出)
* <p>
* 您这边以邮件的形式申请接入角标后,OPPO方审核人员将在接收日期10个工作日内给出审核结果。感谢您对OPPO开放平台的关注与信任,还
* 请您耐心等待的哦~
*/
public class OPPOModelImpl implements IconBadgeNumModel {
private static final String NOTIFICATION_ERROR = "not support : oppo"; @Override
public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
if (true) {
throw new Exception(NOTIFICATION_ERROR);
}
return null;
}
}
import android.app.Application;
import android.app.Notification;
import android.content.Intent;
import android.support.annotation.NonNull; import static com.demo.badges.Utils.UNABLE_TO_RESOLVE_INTENT_ERROR_; /**
* 没有找到官方文档说明,只有网上的方法
* <p>
* Galaxy S8/SM-G9500/android 8.0
* Galaxy Galaxy Note8/SM-N9500/android 8.0
* 三星
*/
public class SamsungModelImpl implements IconBadgeNumModel {
private static final String NOTIFICATION_ERROR = "not support : samsung"; @Override
public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
intent.putExtra("badge_count", count);
intent.putExtra("badge_count_package_name", context.getPackageName());
intent.putExtra("badge_count_class_name", Utils.getInstance().getLaunchIntentForPackage(context)); if (Utils.getInstance().canResolveBroadcast(context, intent)) {
context.sendBroadcast(intent);
} else {
throw new Exception(UNABLE_TO_RESOLVE_INTENT_ERROR_ + intent.toString());
}
return notification;
}
}
import android.app.Application;
import android.app.Notification;
import android.support.annotation.NonNull; /**
* 网上查到了此段代码,但在vivo X21A[android-8.1.0/Funtouch OS_4.0]真机上并未测试成功。
* 在vivo开发者平台上与人工客服联系后,对方回复暂时没有公开的方法可以设置,也没有渠道可以申请,只有vivo特别指定的应用可以实现(微信、微博等)
*/
public class VIVOModelImpl implements IconBadgeNumModel {
private static final String NOTIFICATION_ERROR = "not support : vivo"; @Override
public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
if (true) {
throw new Exception(NOTIFICATION_ERROR);
}
return null;
}
}
import android.app.Application;
import android.app.Notification;
import android.support.annotation.NonNull; import java.lang.reflect.Field;
import java.lang.reflect.Method; /**
* https://dev.mi.com/console/doc/detail?pId=939
* <p>
* 必须发送通知
*/
public class XiaoMiModelImpl implements IconBadgeNumModel {
private static final String NOTIFICATION_ERROR = "Xiaomi phones must send notification"; @Override
public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
if (notification == null) {
throw new Exception(NOTIFICATION_ERROR);
}
Field field = notification.getClass().getDeclaredField("extraNotification");
Object extraNotification = field.get(notification);
Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
method.invoke(extraNotification, count);
return notification;
}
}
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import java.util.List; public class Utils {
public static final String UNABLE_TO_RESOLVE_INTENT_ERROR_ = "unable to resolve intent: "; private static Utils instance; public static Utils getInstance() {
if (instance == null) {
instance = new Utils();
}
return instance;
} public boolean canResolveBroadcast(Context context, Intent intent) {
PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> receivers = packageManager.queryBroadcastReceivers(intent, 0);
return receivers != null && receivers.size() > 0;
} public String getLaunchIntentForPackage(Context context) {
return context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
}
}
import android.app.Application;
import android.app.Notification;
import android.support.annotation.NonNull; public interface IconBadgeNumModel {
Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception;
}
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import java.util.HashMap;
import java.util.Map; public class LauncherHelper {
public final static String GOOGLE = "google";
public final static String HUAWEI = "huawei";
public final static String MEIZU = "meizu";
public final static String XIAOMI = "xiaomi";
public final static String OPPO = "oppo";
public final static String VIVO = "vivo";
public final static String SAMSUNG = "samsung"; private static Map<String, String> launcherMap; static {
launcherMap = new HashMap<>();
launcherMap.put("com.huawei.android.launcher", HUAWEI);
launcherMap.put("com.miui.home", XIAOMI);
launcherMap.put("com.sec.android.app.launcher", SAMSUNG);
launcherMap.put("com.google.android.apps.nexuslauncher", GOOGLE);
} @Nullable
public String getLauncherTypeByName(@NonNull String launcherName) {
return launcherMap.get(launcherName);
} @Nullable
public String getLauncherPackageName(@NonNull Context context) {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
final ResolveInfo res = context.getPackageManager().resolveActivity(intent, 0);
if (res.activityInfo == null) {
// should not happen. A home is always installed, isn't it?
return null;
}
if (res.activityInfo.packageName.equals("android")) {
return null;
} else {
return res.activityInfo.packageName;
}
}
}
import android.app.Application;
import android.app.Notification;
import android.os.Build;
import android.support.annotation.NonNull;
import android.text.TextUtils; import java.util.HashMap;
import java.util.Map; public class IconBadgeNumManager implements IconBadgeNumModel {
private static final String NOT_SUPPORT_PHONE = "not support your phone [ Build.MANUFACTURER is null ]";
private static final String NOT_SUPPORT_MANUFACTURER_ = "not support ";
private static final String NOT_SUPPORT_LAUNCHER = "not support your launcher [ default launcher is null ]";
private static final String NOT_SUPPORT_LAUNCHER_ = "not support ";
private Map<String, IconBadgeNumModel> iconBadgeNumModelMap;
private LauncherHelper launcherHelper; public IconBadgeNumManager() {
this.launcherHelper = new LauncherHelper();
iconBadgeNumModelMap = new HashMap<>();
} @Override
public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
IconBadgeNumModel iconBadgeNumModel = getSetIconBadgeNumModel(context);
return iconBadgeNumModel.setIconBadgeNum(context, notification, count);
} /**
* 根据手机类型获取相应Model
*
* @deprecated 判断当前launcher更加准确
*/
@Deprecated
@NonNull
private IconBadgeNumModel getIconBadgeNumModelByManufacturer() throws Exception {
if (TextUtils.isEmpty(Build.MANUFACTURER)) {
throw new Exception(NOT_SUPPORT_PHONE);
}
switch (Build.MANUFACTURER.toLowerCase()) {
case MobileBrand.HUAWEI:
return new GoogleModelImpl();
case MobileBrand.XIAOMI:
return new XiaoMiModelImpl();
case MobileBrand.VIVO:
return new VIVOModelImpl();
case MobileBrand.OPPO:
return new OPPOModelImpl();
case MobileBrand.SAMSUNG:
return new SamsungModelImpl();
case MobileBrand.MEIZU:
return new MeizuModelImpl();
case MobileBrand.GOOGLE:
return new GoogleModelImpl();
default:
throw new Exception(NOT_SUPPORT_MANUFACTURER_ + Build.MANUFACTURER);
}
} /**
* 根据手机当前launcher获取相应Model
*/
@NonNull
private IconBadgeNumModel getIconBadgeNumModelByLauncher(@NonNull String launcherType) throws Exception {
switch (launcherType) {
case LauncherHelper.HUAWEI:
return new HuaWeiModelImpl();
case LauncherHelper.XIAOMI:
return new XiaoMiModelImpl();
case LauncherHelper.VIVO:
return new VIVOModelImpl();
case LauncherHelper.OPPO:
return new OPPOModelImpl();
case LauncherHelper.SAMSUNG:
return new SamsungModelImpl();
case LauncherHelper.MEIZU:
return new MeizuModelImpl();
case LauncherHelper.GOOGLE:
return new GoogleModelImpl();
default:
throw new Exception(NOT_SUPPORT_LAUNCHER_ + launcherType);
}
} @NonNull
private IconBadgeNumModel getSetIconBadgeNumModel(@NonNull Application context) throws Exception {
String launcherName = launcherHelper.getLauncherPackageName(context);
if (TextUtils.isEmpty(launcherName)) {
throw new Exception(NOT_SUPPORT_LAUNCHER);
}
String launcherType = launcherHelper.getLauncherTypeByName(launcherName);
if (TextUtils.isEmpty(launcherType)) {
throw new Exception(NOT_SUPPORT_LAUNCHER_ + launcherName);
}
if (iconBadgeNumModelMap.containsKey(launcherType)) {
return iconBadgeNumModelMap.get(launcherType);
}
IconBadgeNumModel iconBadgeNumModel = getIconBadgeNumModelByLauncher(launcherType);
iconBadgeNumModelMap.put(launcherType, iconBadgeNumModel);
return iconBadgeNumModel;
}
}

测试:

import android.content.Intent;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View; import com.demo.badges.LauncherHelper; public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG, Build.MANUFACTURER);
Log.e(TAG, new LauncherHelper().getLauncherPackageName(this)); findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, MyService.class);
startService(i);
}
});
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, MyService.class);
stopService(i);
}
});
}
}
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat; import com.demo.badges.IconBadgeNumManager; public class MyService extends Service {
IconBadgeNumManager setIconBadgeNumManager;
private boolean isStop;
private int count;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (!isStop) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count += 2;
sendIconNumNotification();
}
}
}); public MyService() {
setIconBadgeNumManager = new IconBadgeNumManager(); } @Override
public int onStartCommand(Intent intent, int flags, int startId) {
isStop = false;
thread.start();
return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() {
super.onDestroy();
isStop = true;
} @Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
} private void sendIconNumNotification() {
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (nm == null) return;
String notificationChannelId = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = createNotificationChannel();
nm.createNotificationChannel(notificationChannel);
notificationChannelId = notificationChannel.getId();
}
Notification notification = null;
try {
notification = new NotificationCompat.Builder(this, notificationChannelId)
.setSmallIcon(getApplicationInfo().icon)
.setWhen(System.currentTimeMillis())
.setContentTitle("title")
.setContentText("content num: " + count)
.setTicker("ticker")
.setAutoCancel(true)
.setNumber(count)
.build();
notification = setIconBadgeNumManager.setIconBadgeNum(getApplication(), notification, count); nm.notify(32154, notification);
} catch (Exception e) {
e.printStackTrace();
}
} @RequiresApi(api = Build.VERSION_CODES.O)
private static NotificationChannel createNotificationChannel() {
String channelId = "test";
NotificationChannel channel = null;
channel = new NotificationChannel(channelId,
"Channel1", NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true); //是否在桌面icon右上角展示小红点
channel.setLightColor(Color.RED); //小红点颜色
channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
return channel;
}
}

亲测华为手机可行!

android 桌面图标添加数字角标的更多相关文章

  1. Android 为应用添加数字角标

    今天在论坛上看到了一个帖子,终于搞清了我很久以来的一个困惑,android到底能不能实现ios的角标效果,QQ是怎么实现的.看了这个帖子顿时终于解除了我的困惑. 先说一个下大概的思路: 大家都知道an ...

  2. HTML页面仿iphone数字角标

    做仿iphone样式的数字角标,用简单的css来实现 <html><head><title>角标数字</title><style type=&qu ...

  3. IOS开发 应用程序图标数字角标

    其实实现这个功能很简单,只要调用UIApplication即可.   用法用例:[UIApplication sharedApplication].applicationIconBadgeNumber ...

  4. IOS 程序图标添加数字

    +(void)setAppIconNumber:(NSInteger)num{ if ([UIParam getIOSVersion]>8.0) { UIUserNotificationSett ...

  5. ios uibutton加数字角标

    http://www.jianshu.com/p/0c7fae1cadac 第一种:https://github.com/mikeMTOL/UIBarButtonItem-Badge第二种:https ...

  6. 在word文档中添加上角标和下角标

    方法一 摘录:https://jingyan.baidu.com/article/02027811b4d2da1bcc9ce5f7.html 方法二 利用MathType数学公式编辑器 exe下载:h ...

  7. ShortcutBadgerDemo【安卓应用角标(badge)实现方案】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 本文主要使用的开源库是 leolin310148/ShortcutBadger,但是在其基础上做了一些修改. 什么是应用角标? 1. ...

  8. Android上的Badge,快速实现给应用添加角标

    应用角标是iOS的一个特色,原生Android并不支持.或许是因为当时iOS的通知栏比较鸡肋(当然现在已经改进了很多),而Android的通知栏功能强大?所以才出现了一方依赖于数字角标,一方坚持强大的 ...

  9. apns关于APP数字角标的理解

    前两天群里有兄弟在吐槽,做远程推送的时候:老板要求APP桌面图标的右上角显示红色未读数字(数字角标)要精准,有多少未读通知就显示数字几:但是后台的弟兄在发送推送通知的时候,每次的角标是1,然后要移动端 ...

随机推荐

  1. 矩阵LU分解程序实现(Matlab)

    n=4;%确定需要LU分解的矩阵维数 %A=zeros(n,n); L=eye(n,n);P=eye(n,n);U=zeros(n,n);%初始化矩阵 tempU=zeros(1,n);tempP=z ...

  2. js图片转为base64的格式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. python应用-给出行数,输出相应的杨辉三角

    def main(): num = int(input('Number of rows: ')) yh = [[]] * num for row in range(num): yh[row] = [N ...

  4. CSS IE Hack

    条件注释判断浏览器!: [if !IE],The NOT operator. This is placed immediately in front of the feature, operator, ...

  5. C++的map用法

    图,自动建立表示关键字和键值(key - value)之间的对应关系,两者可以是任何数据类型,key唯一并且自动排序,value不唯一. 1.头文件#include<map> 2.map& ...

  6. csp-s 考前刷题记录

    洛谷 P2615 神奇的幻方 洛谷 P2678 跳石头 洛谷 P1226 [模板]快速幂||取余运算 洛谷 P2661 信息传递 LOJ P10147 石子合并 LOJ P10148 能量项链 LOJ ...

  7. Navicat连接oracle,出现Only compatible with oci version 8.1

    与本地oracle连接的时候,一般没问题,sqlplus和oci都是本地oracle自带的,(设置: 工具->选项->oci) 分别为:     oci:D:\app\pcman\prod ...

  8. 总结TCP与UDP的区别

    TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认.窗口.重传.拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源. TCP的缺 ...

  9. A#G/C013

    A#G/C013 A Sorted Arrays 不会/kk B Hamiltonish Path 我是傻逼 如果一条路径不合法,那么把不合法的端点向没出现过的相邻点连过去救星了 C Ants on ...

  10. 一篇文章把你带入到JavaScript中的闭包与高级函数

    在JavaScript中,函数是一等公民.JavaScript是一门面向对象的编程语言,但是同时也有很多函数式编程的特性,如Lambda表达式,闭包,高阶函数等,函数式编程时一种编程范式. funct ...