是否支持角标并不与手机厂商有关,而是你当前使用的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;
}
}

亲测华为手机可行!

最新文章

  1. centos install kafka and zookeeper
  2. Linux C编程(1) vim及gcc命令
  3. ural 1070. Local Time
  4. 将字符串拆分为id
  5. UNIX环境高级编程笔记之进程控制
  6. OpenGL的GLUT初始化函数[转]
  7. URAL 1320 Graph Decomposition(并查集)
  8. Linux勉強
  9. NIR相机
  10. Spark Executor Driver资源调度汇总
  11. linux统计单词数
  12. IIS下无法访问.ini后缀文件
  13. ubuntu如何实现访问实际网络中windows共享文件夹
  14. js设置全局变量ajax中赋值
  15. org.apache.commons.beanutils.BeanMap简单使用例子
  16. SpringMVC上传图片并压缩及剪切demo
  17. java有关 String char 常见问题 编辑中
  18. 小tips:JS之for in、Object.keys()和Object.getOwnPropertyNames()的区别
  19. win10安装ubuntu16.04双系统历程
  20. 设计模式のSingleton Pattern(单例模式)----创建模式

热门文章

  1. MySQL 自带的4个系统数据库的说明
  2. 初入Linux
  3. Unity 渲染教程(三):使用多张纹理贴图
  4. 20180523模拟赛T2——前缀!
  5. 让iOS 开发更便捷-JSONConverter
  6. 在调试时,有什么更好的方法可以监视最后一个win32错误?
  7. vmvare ESXi使用
  8. Python中的异步任务队列 arq
  9. hive基础知识二
  10. linux 配置启动supervisor详细