appProcesses = activityManager.getRunningAppProcesses();
111 | //
112 | // if (appProcesses == null)
113 | // return false;
114 | //
115 | // for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
116 | // if (appProcess.processName.equals(packageName) && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
117 | // return true;
118 | // }
119 | // }
120 | //
121 | // return false;
122 | // }
123 | //
124 | // private void processCustomMessage(Context context, Bundle bundle) {
125 | //
126 | // String channelID = "1";
127 | // String channelName = "channel_name";
128 | //
129 | // // 跳转的Activity
130 | // Intent intent = new Intent(context, Main2Activity.class);
131 | // intent.putExtras(bundle);
132 | // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
133 | //
134 | // PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
135 | //
136 | // // 获得系统推送的自定义消息
137 | // String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
138 | //
139 | // NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
140 | //
141 | // //适配安卓8.0的消息渠道
142 | // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
143 | // NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
144 | // notificationManager.createNotificationChannel(channel);
145 | // }
146 | //
147 | // NotificationCompat.Builder notification =
148 | // new NotificationCompat.Builder(context, channelID);
149 | //
150 | // notification.setAutoCancel(true)
151 | // .setContentText(message)
152 | // .setContentTitle("我是Title")
153 | // .setSmallIcon(R.mipmap.ic_launcher)
154 | // .setDefaults(Notification.DEFAULT_ALL)
155 | // .setContentIntent(pendingIntent);
156 | //
157 | // notificationManager.notify((int) (System.currentTimeMillis() / 1000), notification.build());
158 | // }
159 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/ImageUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest;
2 |
3 | /**
4 | * 创建时间: 2019/3/14 0014.
5 | * 创建人: yanbin
6 | * 功能:
7 | */
8 |
9 | public class ImageUtils {
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/Main2Activity.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest;
2 |
3 | import android.app.NotificationManager;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.widget.TextView;
10 |
11 | public class Main2Activity extends AppCompatActivity {
12 |
13 | String mTvView;
14 |
15 | TextView textView;
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_main2);
21 | textView = findViewById(R.id.textView);
22 | try {
23 | mTvView = getIntent().getStringExtra("test");
24 | } catch (Exception e) {
25 |
26 | }
27 | textView.setOnClickListener(new View.OnClickListener() {
28 | @Override
29 | public void onClick(View view) {
30 | textView.setText(mTvView);
31 | NotificationManager managers = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
32 | // managers.cancel(R.mipmap.ic_launcher);
33 | managers.cancel(666);
34 | }
35 | });
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationChannel;
5 | import android.app.NotificationManager;
6 | import android.app.PendingIntent;
7 | import android.content.Context;
8 | import android.content.Intent;
9 | import android.graphics.Color;
10 | import android.os.Build;
11 | import android.support.annotation.RequiresApi;
12 | import android.support.v4.app.NotificationCompat;
13 | import android.support.v7.app.AppCompatActivity;
14 | import android.os.Bundle;
15 | import android.util.Log;
16 | import android.view.View;
17 | import android.widget.RemoteViews;
18 |
19 | import com.tot.badges.IconBadgeNumManager;
20 | import com.tot.badges.LauncherHelper;
21 | import com.tot.badges.SendIconNumUtil;
22 |
23 | import cn.jpush.android.api.JPushInterface;
24 |
25 |
26 | public class MainActivity extends AppCompatActivity {
27 | private static final String TAG = "MainActivity";
28 | IconBadgeNumManager setIconBadgeNumManager = new IconBadgeNumManager();
29 | public static int i = 0;
30 | NotificationManager nm;
31 | @Override
32 | protected void onCreate(Bundle savedInstanceState) {
33 | super.onCreate(savedInstanceState);
34 | setContentView(R.layout.activity_main);
35 | Log.e(TAG, Build.MANUFACTURER);
36 | Log.e(TAG, new LauncherHelper().getLauncherPackageName(this));
37 | findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
38 | @Override
39 | public void onClick(View v) {
40 | // JPushInterface.clearAllNotifications(MainActivity.this);
41 | SendIconNumUtil.clearAllIconNumNotifucation();
42 | }
43 | });
44 | findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View view) {
47 |
48 | String notificationChannelId = null;
49 | NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
50 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
51 | //8.0以上需设置消息通道id
52 | NotificationChannel notificationChannel = createNotificationChannel();
53 | nm.createNotificationChannel(notificationChannel);
54 | notificationChannelId = notificationChannel.getId();
55 | }
56 | Notification notification = null;
57 | RemoteViews remoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.image_item);
58 | remoteViews.setTextViewText(R.id.mTv, "wohahahahahahah");
59 | notification = new NotificationCompat.Builder(MainActivity.this, notificationChannelId)
60 | .setSmallIcon(getApplicationInfo().icon)
61 | .setWhen(System.currentTimeMillis())
62 | .setAutoCancel(true)
63 | .setCustomContentView(remoteViews)
64 | .build();
65 | SendIconNumUtil.sendIconNumNotification(5, getApplication(), 666, notification, nm);
66 |
67 | //点击导航栏的跳转事件(系统默认导航栏)
68 | // Intent intent = new Intent(MainActivity.this, Main2Activity.class);
69 | // //从导航传递的数据
70 | // intent.putExtra("test", "我是测试从通知栏传过来的数据");
71 | // i++;
72 | // String chann = "test" + i;
73 | // PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent,
74 | // PendingIntent.FLAG_ONE_SHOT);
75 | // SendIconNumUtil.sendIconNumNotification(1, getApplication(), i, pendingIntent,
76 | // "testTitle", "tests", R.mipmap.ic_launcher,
77 | // "我是ticker", i + "", "测试专用渠道2");
78 | // sendIconNumNotification(5);
79 | }
80 | });
81 | findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
82 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
83 | @Override
84 | public void onClick(View view) {
85 | //自定义导航栏
86 | String notificationChannelId = null;
87 | nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
88 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
89 | //8.0以上需设置消息通道id
90 | NotificationChannel notificationChannel = createNotificationChannel();
91 | nm.createNotificationChannel(notificationChannel);
92 | notificationChannelId = notificationChannel.getId();
93 | }
94 | Notification notification = null;
95 | RemoteViews remoteViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.image_item);
96 | remoteViews.setTextViewText(R.id.mTv, "wohahahahahahah");
97 | notification = new NotificationCompat.Builder(MainActivity.this, notificationChannelId)
98 | .setSmallIcon(getApplicationInfo().icon)
99 | .setWhen(System.currentTimeMillis())
100 | .setAutoCancel(true)
101 | .setCustomContentView(remoteViews)
102 | .build();
103 | SendIconNumUtil.sendIconNumNotification(5, getApplication(), 555, notification, nm);
104 | }
105 | });
106 |
107 | }
108 |
109 |
110 | @RequiresApi(api = Build.VERSION_CODES.O)
111 | private static NotificationChannel createNotificationChannel() {
112 | String channelId = "test";
113 | NotificationChannel channel = null;
114 | channel = new NotificationChannel(channelId,
115 | "第四个权限", NotificationManager.IMPORTANCE_HIGH);
116 | channel.enableLights(true); //是否在桌面icon右上角展示小红点
117 | channel.setLightColor(Color.BLACK); //小红点颜色
118 | channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
119 | return channel;
120 | }
121 |
122 |
123 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
124 | private void addNotificationChannel() {
125 | //点击后进入的界面
126 | Intent intent = new Intent(this, Main2Activity.class);
127 | intent.putExtra("test", "我是测试从通知栏传过来的数据");
128 | PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
129 |
130 |
131 | Notification notification = new Notification.Builder(this)
132 | .setTicker("托儿所")
133 | .setContentTitle("喜之郎")
134 | .setContentText("儿童节")
135 | .setSmallIcon(R.mipmap.ic_launcher)
136 | .setContentIntent(pendingIntent)
137 | .build();
138 |
139 | NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
140 | manager.notify(666, notification);
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/MyReceiver.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest;
2 |
3 | import android.app.Application;
4 | import android.app.PendingIntent;
5 | import android.content.BroadcastReceiver;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.os.Bundle;
9 | import android.text.TextUtils;
10 | import android.util.Log;
11 |
12 |
13 | import com.tot.badges.SendIconNumUtil;
14 |
15 | import cn.jpush.android.api.JPushInterface;
16 |
17 | import static com.example.billwangbw.appiconnumtest.MainActivity.i;
18 |
19 | /**
20 | * 创建时间: 2019/3/14 0014.
21 | * 创建人: yanbin
22 | * 功能:
23 | */
24 |
25 | public class MyReceiver extends BroadcastReceiver {
26 | private static final String TAG = "JIGUANG";
27 | public static String regId;
28 | String extra_json;
29 |
30 | @Override
31 | public void onReceive(Context context, Intent intent) {
32 |
33 | try {
34 | Bundle bundle = intent.getExtras();
35 |
36 | if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
37 | regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
38 | Log.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
39 |
40 | //send the Registration Id to your server...
41 |
42 | } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
43 | Log.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息(内容为): " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
44 | // processCustomMessage(context, bundle);
45 | PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
46 | PendingIntent.FLAG_ONE_SHOT);
47 | SendIconNumUtil.sendIconNumNotification(1, (Application) context.getApplicationContext(), i, pendingIntent,
48 | "testTitle", "tests", R.mipmap.ic_launcher,
49 | "我是ticker", bundle.getString(JPushInterface.EXTRA_MESSAGE), "测试专用渠道1");
50 | i++;
51 | // 自定义消息不是通知,默认不会被SDK展示到通知栏上,极光推送仅负责透传给SDK。其内容和展示形式完全由开发者自己定义。
52 | // 自定义消息主要用于应用的内部业务逻辑和特殊展示需求
53 | } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
54 | Log.d(TAG, "[MyReceiver] 接收到推送下来的通知");
55 | i++;
56 | extra_json = bundle.getString(JPushInterface.EXTRA_EXTRA);
57 | if (!TextUtils.isEmpty(extra_json))
58 | Log.d(TAG, "[MyReceiver] 接收到推送下来的通知附加字段" + extra_json);
59 |
60 | // 可以利用附加字段来区别Notication,指定不同的动作,extra_json是个json字符串
61 | // 通知(Notification),指在手机的通知栏(状态栏)上会显示的一条通知信息
62 | } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
63 |
64 | // 在这里根据 JPushInterface.EXTRA_EXTRA(附加字段) 的内容处理代码,
65 | // 比如打开新的Activity, 打开一个网页等..
66 |
67 | } else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction())) {
68 | Log.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(JPushInterface.EXTRA_EXTRA));
69 | //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..
70 | i++;
71 | } else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {
72 | boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);
73 | Log.w(TAG, "[MyReceiver]" + intent.getAction() + " connected state change to " + connected);
74 | } else {
75 | Log.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());
76 | }
77 |
78 | SendIconNumUtil.sendIconNumNotification(i, (Application) context.getApplicationContext());
79 | } catch (Exception e) {
80 |
81 | }
82 |
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/MyService.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationChannel;
5 | import android.app.NotificationManager;
6 | import android.app.Service;
7 | import android.content.Context;
8 | import android.content.Intent;
9 | import android.graphics.Color;
10 | import android.os.Build;
11 | import android.os.IBinder;
12 | import android.support.annotation.RequiresApi;
13 | import android.support.v4.app.NotificationCompat;
14 |
15 | import com.tot.badges.IconBadgeNumManager;
16 |
17 | public class MyService extends Service {
18 | IconBadgeNumManager setIconBadgeNumManager;
19 | private boolean isStop;
20 | private int count;
21 | Thread thread = new Thread(new Runnable() {
22 | @Override
23 | public void run() {
24 | while (!isStop) {
25 | try {
26 | Thread.sleep(1000);
27 | } catch (InterruptedException e) {
28 | e.printStackTrace();
29 | }
30 | count += 10;
31 | sendIconNumNotification();
32 | }
33 | }
34 | });
35 |
36 | public MyService() {
37 | setIconBadgeNumManager = new IconBadgeNumManager();
38 |
39 | }
40 |
41 | @Override
42 | public int onStartCommand(Intent intent, int flags, int startId) {
43 | isStop = false;
44 | thread.start();
45 | return super.onStartCommand(intent, flags, startId);
46 | }
47 |
48 | @Override
49 | public void onDestroy() {
50 | super.onDestroy();
51 | isStop = true;
52 | }
53 |
54 | @Override
55 | public IBinder onBind(Intent intent) {
56 | throw new UnsupportedOperationException("Not yet implemented");
57 | }
58 |
59 | private void sendIconNumNotification() {
60 | NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
61 | if (nm == null) return;
62 | String notificationChannelId = null;
63 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
64 | NotificationChannel notificationChannel = createNotificationChannel();
65 | nm.createNotificationChannel(notificationChannel);
66 | notificationChannelId = notificationChannel.getId();
67 | }
68 | Notification notification = null;
69 | try {
70 | notification = new NotificationCompat.Builder(this, notificationChannelId)
71 | .setSmallIcon(getApplicationInfo().icon)
72 | .setWhen(System.currentTimeMillis())
73 | .setContentTitle("title")
74 | .setContentText("content num: " + count)
75 | .setTicker("ticker")
76 | .setAutoCancel(true)
77 | .setNumber(count)
78 | .build();
79 | notification = setIconBadgeNumManager.setIconBadgeNum(getApplication(), notification, count);
80 |
81 | nm.notify(32154, notification);
82 | } catch (Exception e) {
83 | e.printStackTrace();
84 | }
85 | }
86 |
87 | @RequiresApi(api = Build.VERSION_CODES.O)
88 | private static NotificationChannel createNotificationChannel() {
89 | String channelId = "test";
90 | NotificationChannel channel = null;
91 | channel = new NotificationChannel(channelId,
92 | "Channel1", NotificationManager.IMPORTANCE_DEFAULT);
93 | channel.enableLights(true); //是否在桌面icon右上角展示小红点
94 | channel.setLightColor(Color.RED); //小红点颜色
95 | channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
96 | return channel;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/NotificationBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest;
2 |
3 | import android.app.NotificationManager;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.util.Log;
8 |
9 | /**
10 | * 创建时间: 2019/3/11 0011.
11 | * 创建人: yanbin
12 | * 功能:监听通知栏消失
13 | */
14 |
15 | public class NotificationBroadcastReceiver extends BroadcastReceiver {
16 | @Override
17 | public void onReceive(Context context, Intent intent) {
18 | String action = intent.getAction();
19 | int type = intent.getIntExtra("type",1);
20 | if (type == -1){
21 | NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
22 | notificationManager.cancel(type);
23 | if (action.equals("notification_cancelled")){
24 | Log.d("LogTestNotification","h删除通知栏所有成功");
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/GoogleModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.content.Intent;
6 | import android.support.annotation.NonNull;
7 |
8 | /**
9 | *
10 | */
11 | public class GoogleModelImpl implements IconBadgeNumModel {
12 | private static final String NOTIFICATION_ERROR = "google not support before API O";
13 |
14 | @Override
15 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
16 | if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
17 | throw new Exception(NOTIFICATION_ERROR);
18 | }
19 | Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
20 | intent.putExtra("badge_count", count);
21 | intent.putExtra("badge_count_package_name", context.getPackageName());
22 | intent.putExtra("badge_count_class_name", Utils.getInstance().getLaunchIntentForPackage(context)); // com.test. badge.MainActivity is your apk main activity
23 |
24 | // if (Utils.getInstance().canResolveBroadcast(context, intent)) {
25 | context.sendBroadcast(intent);
26 | // } else {
27 | // throw new Exception(UNABLE_TO_RESOLVE_INTENT_ERROR_ + intent.toString());
28 | // }
29 |
30 | return notification;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/HuaWeiModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.net.Uri;
6 | import android.os.Bundle;
7 | import android.support.annotation.NonNull;
8 |
9 | /**
10 | * https://developer.huawei.com/consumer/cn/devservice/doc/30802
11 | *
12 | * max:99
13 | */
14 | public class HuaWeiModelImpl implements IconBadgeNumModel {
15 | @Override
16 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
17 | Bundle bunlde = new Bundle();
18 | bunlde.putString("package", context.getPackageName()); // com.test.badge is your package name
19 | bunlde.putString("class", Utils.getInstance().getLaunchIntentForPackage(context)); // com.test. badge.MainActivity is your apk main activity
20 | bunlde.putInt("badgenumber", count);
21 | context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bunlde);
22 | return notification;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/IconBadgeNumManager.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.support.annotation.NonNull;
6 | import android.text.TextUtils;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | public class IconBadgeNumManager implements IconBadgeNumModel {
12 | private static final String NOT_SUPPORT_PHONE = "not support your phone [ Build.MANUFACTURER is null ]";
13 | private static final String NOT_SUPPORT_MANUFACTURER_ = "not support ";
14 | private static final String NOT_SUPPORT_LAUNCHER = "not support your launcher [ default launcher is null ]";
15 | private static final String NOT_SUPPORT_LAUNCHER_ = "not support ";
16 | private Map iconBadgeNumModelMap;
17 | private LauncherHelper launcherHelper;
18 |
19 | public IconBadgeNumManager() {
20 | this.launcherHelper = new LauncherHelper();
21 | iconBadgeNumModelMap = new HashMap<>();
22 | }
23 |
24 | @Override
25 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
26 | IconBadgeNumModel iconBadgeNumModel = getSetIconBadgeNumModel(context);
27 | return iconBadgeNumModel.setIconBadgeNum(context, notification, count);
28 | }
29 |
30 | /**
31 | * 根据手机当前launcher获取相应Model
32 | */
33 | @NonNull
34 | private IconBadgeNumModel getIconBadgeNumModelByLauncher(@NonNull String launcherType) throws Exception {
35 | switch (launcherType) {
36 | case LauncherHelper.HUAWEI:
37 | return new HuaWeiModelImpl();
38 | case LauncherHelper.XIAOMI:
39 | return new XiaoMiModelImpl();
40 | case LauncherHelper.VIVO:
41 | return new VIVOModelImpl();
42 | case LauncherHelper.OPPO:
43 | return new OPPOModelImpl();
44 | case LauncherHelper.SAMSUNG:
45 | return new SamsungModelImpl();
46 | case LauncherHelper.MEIZU:
47 | return new MeizuModelImpl();
48 | case LauncherHelper.GOOGLE:
49 | return new GoogleModelImpl();
50 | default:
51 | throw new Exception(NOT_SUPPORT_LAUNCHER_ + launcherType);
52 | }
53 | }
54 |
55 | @NonNull
56 | private IconBadgeNumModel getSetIconBadgeNumModel(@NonNull Application context) throws Exception {
57 | String launcherName = launcherHelper.getLauncherPackageName(context);
58 | if (TextUtils.isEmpty(launcherName)) {
59 | throw new Exception(NOT_SUPPORT_LAUNCHER);
60 | }
61 | String launcherType = launcherHelper.getLauncherTypeByName(launcherName);
62 | if (TextUtils.isEmpty(launcherType)) {
63 | throw new Exception(NOT_SUPPORT_LAUNCHER_ + launcherName);
64 | }
65 | if (iconBadgeNumModelMap.containsKey(launcherType)) {
66 | return iconBadgeNumModelMap.get(launcherType);
67 | }
68 | IconBadgeNumModel iconBadgeNumModel = getIconBadgeNumModelByLauncher(launcherType);
69 | iconBadgeNumModelMap.put(launcherType, iconBadgeNumModel);
70 | return iconBadgeNumModel;
71 | }
72 |
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/IconBadgeNumModel.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.support.annotation.NonNull;
6 |
7 | public interface IconBadgeNumModel {
8 | Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception;
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/LauncherHelper.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.ResolveInfo;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 |
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | public class LauncherHelper {
13 | public final static String GOOGLE = "google";
14 | public final static String HUAWEI = "huawei";
15 | public final static String MEIZU = "meizu";
16 | public final static String XIAOMI = "xiaomi";
17 | public final static String OPPO = "oppo";
18 | public final static String VIVO = "vivo";
19 | public final static String SAMSUNG = "samsung";
20 |
21 | private static Map launcherMap;
22 |
23 | static {
24 | launcherMap = new HashMap<>();
25 | launcherMap.put("com.huawei.android.launcher", HUAWEI);
26 | launcherMap.put("com.miui.home", XIAOMI);
27 | launcherMap.put("com.sec.android.app.launcher", SAMSUNG);
28 | launcherMap.put("com.google.android.apps.nexuslauncher", GOOGLE);
29 | }
30 |
31 | @Nullable
32 | public String getLauncherTypeByName(@NonNull String launcherName) {
33 | return launcherMap.get(launcherName);
34 | }
35 |
36 | @Nullable
37 | public String getLauncherPackageName(@NonNull Context context) {
38 | final Intent intent = new Intent(Intent.ACTION_MAIN);
39 | intent.addCategory(Intent.CATEGORY_HOME);
40 | final ResolveInfo res = context.getPackageManager().resolveActivity(intent, 0);
41 | if (res.activityInfo == null) {
42 | // should not happen. A home is always installed, isn't it?
43 | return null;
44 | }
45 | if (res.activityInfo.packageName.equals("android")) {
46 | return null;
47 | } else {
48 | return res.activityInfo.packageName;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/MeizuModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.support.annotation.NonNull;
6 |
7 | public class MeizuModelImpl implements IconBadgeNumModel {
8 | private static final String NOTIFICATION_ERROR = "not support : meizu";
9 |
10 | @Override
11 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
12 | if (true) {
13 | throw new Exception(NOTIFICATION_ERROR);
14 | }
15 | return null;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/OPPOModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.support.annotation.NonNull;
6 |
7 | /**
8 | * 以下是oppo客服原文(其中没有说明3.3中日活量和总下载量的标准)
9 | *
10 | * 亲,您可以通过邮件的形式提交申请,邮件形式如下:
11 | *
12 | * 1.主题:“申请开放OPPO手机应用角标权限——(应用名称)”
13 | *
14 | * 2.收件人:devtec@oppo.com
15 | *
16 | * 3.正文:应用角标申请所需材料
17 | * 以下为应用角标申请所需材料:
18 | * 1.应用方申请人基本信息(姓名、邮箱、手机、微信);
19 | * 2.应用方厂商介绍(不少于200字);
20 | * 3.申请应用近一个月内IOS与安卓系统的平均日活量及总下载量介绍;
21 | * 4.申请应用产品主要功能介绍(不少于100字);
22 | * 5.申请应用期望角标出现的全部场景。(即哪些类的消息需要出现角标,需全部列出)
23 | *
24 | * 您这边以邮件的形式申请接入角标后,OPPO方审核人员将在接收日期10个工作日内给出审核结果。感谢您对OPPO开放平台的关注与信任,还
25 | * 请您耐心等待的哦~
26 | */
27 | public class OPPOModelImpl implements IconBadgeNumModel {
28 | private static final String NOTIFICATION_ERROR = "not support : oppo";
29 |
30 | @Override
31 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
32 | if (true) {
33 | throw new Exception(NOTIFICATION_ERROR);
34 | }
35 | return null;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/SamsungModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.content.Intent;
6 | import android.support.annotation.NonNull;
7 |
8 | import static com.tot.badges.Utils.UNABLE_TO_RESOLVE_INTENT_ERROR_;
9 |
10 | /**
11 | * 没有找到官方文档说明,只有网上的方法
12 | *
13 | * Galaxy S8/SM-G9500/android 8.0
14 | * Galaxy Galaxy Note8/SM-N9500/android 8.0
15 | */
16 | public class SamsungModelImpl implements IconBadgeNumModel {
17 | private static final String NOTIFICATION_ERROR = "not support : samsung";
18 |
19 | @Override
20 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
21 | Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
22 | intent.putExtra("badge_count", count);
23 | intent.putExtra("badge_count_package_name", context.getPackageName());
24 | intent.putExtra("badge_count_class_name", Utils.getInstance().getLaunchIntentForPackage(context));
25 |
26 | if (Utils.getInstance().canResolveBroadcast(context, intent)) {
27 | context.sendBroadcast(intent);
28 | } else {
29 | throw new Exception(UNABLE_TO_RESOLVE_INTENT_ERROR_ + intent.toString());
30 | }
31 | return notification;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/Utils.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.PackageManager;
6 | import android.content.pm.ResolveInfo;
7 |
8 | import java.util.List;
9 |
10 | public class Utils {
11 | public static final String UNABLE_TO_RESOLVE_INTENT_ERROR_ = "unable to resolve intent: ";
12 |
13 | private static Utils instance;
14 |
15 | public static Utils getInstance() {
16 | if (instance == null) {
17 | instance = new Utils();
18 | }
19 | return instance;
20 | }
21 |
22 | public boolean canResolveBroadcast(Context context, Intent intent) {
23 | PackageManager packageManager = context.getPackageManager();
24 | List receivers = packageManager.queryBroadcastReceivers(intent, 0);
25 | return receivers != null && receivers.size() > 0;
26 | }
27 |
28 | public String getLaunchIntentForPackage(Context context) {
29 | return context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/VIVOModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.support.annotation.NonNull;
6 |
7 | /**
8 | * 网上查到了此段代码,但在vivo X21A[android-8.1.0/Funtouch OS_4.0]真机上并未测试成功。
9 | * 在vivo开发者平台上与人工客服联系后,对方回复暂时没有公开的方法可以设置,也没有渠道可以申请,只有vivo特别指定的应用可以实现(微信、微博等)
10 | */
11 | public class VIVOModelImpl implements IconBadgeNumModel {
12 | private static final String NOTIFICATION_ERROR = "not support : vivo";
13 |
14 | @Override
15 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
16 | if (true) {
17 | throw new Exception(NOTIFICATION_ERROR);
18 | }
19 | return null;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/XiaoMiModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.support.annotation.NonNull;
6 |
7 | import java.lang.reflect.Field;
8 | import java.lang.reflect.Method;
9 |
10 | /**
11 | * https://dev.mi.com/console/doc/detail?pId=939
12 | *
13 | * 必须发送通知
14 | */
15 | public class XiaoMiModelImpl implements IconBadgeNumModel {
16 | private static final String NOTIFICATION_ERROR = "Xiaomi phones must send notification";
17 |
18 | @Override
19 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
20 | if (notification == null) {
21 | throw new Exception(NOTIFICATION_ERROR);
22 | }
23 | Field field = notification.getClass().getDeclaredField("extraNotification");
24 | Object extraNotification = field.get(notification);
25 | Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
26 | method.invoke(extraNotification, count);
27 | return notification;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/billwangbw/appiconnumtest/badges/sendIconNumUtil.java:
--------------------------------------------------------------------------------
1 | package com.example.billwangbw.appiconnumtest.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.app.NotificationChannel;
6 | import android.app.NotificationManager;
7 | import android.app.PendingIntent;
8 | import android.content.Context;
9 | import android.graphics.Color;
10 | import android.os.Build;
11 | import android.support.annotation.RequiresApi;
12 | import android.support.v4.app.NotificationCompat;
13 | import android.util.Log;
14 |
15 | /**
16 | * 创建时间: 2019/3/12 0012.
17 | * 创建人: yanbin
18 | * 功能:
19 | */
20 |
21 | public class sendIconNumUtil {
22 |
23 | private static IconBadgeNumManager setIconBadgeNumManager = new IconBadgeNumManager();
24 |
25 | /**
26 | * 设置角标(不带出现通知栏)
27 | *
28 | * @param i 角标数字(为0时清空角标)
29 | * @param context 上下文
30 | * @param notIfyId 通知id
31 | */
32 | public static void sendIconNumNotification(int i, Application context, int notIfyId) {
33 | NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
34 | if (nm == null) return;
35 | String notificationChannelId = null;
36 |
37 | Notification notification = null;
38 | try {
39 | notification = new NotificationCompat.Builder(context, notificationChannelId)
40 | .setSmallIcon(context.getApplicationInfo().icon)
41 | .setWhen(System.currentTimeMillis())
42 | .setAutoCancel(true)
43 | .build();
44 | notification = setIconBadgeNumManager.setIconBadgeNum(context, notification, i);
45 | nm.notify(notIfyId, notification);
46 | } catch (Exception e) {
47 | e.printStackTrace();
48 | }
49 | }
50 |
51 | /**
52 | * 设置角标并且带通知栏
53 | *
54 | * @param i 角标数字(为0时清空角标)
55 | * @param context 上下文
56 | * @param notifyID 通知id
57 | * @param pendingIntent 跳转事件
58 | * @param title 标题
59 | * @param channelId 通知栏 id
60 | * @param SmallIcon 图标
61 | * @param Ticker
62 | * @param ContentText 通知内容
63 | * @param channelName 通知栏渠道划分(用来区分通知类型如果不传默认为其他分类)
64 | */
65 | public static void sendIconNumNotification(int i, Application context, int notifyID, PendingIntent pendingIntent, String title, String channelId, int SmallIcon
66 | , String Ticker, String ContentText, String channelName) {
67 |
68 | NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
69 | if (nm == null) return;
70 | Notification notification = null;
71 | String notificationChannelId = null;
72 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
73 | NotificationChannel notificationChannel = createNotificationChannel(channelId, channelName);
74 | nm.createNotificationChannel(notificationChannel);
75 | notificationChannelId = notificationChannel.getId();
76 |
77 | }
78 | notification = new NotificationCompat.Builder(context, notificationChannelId)
79 | .setSmallIcon(context.getApplicationInfo().icon)
80 | .setWhen(System.currentTimeMillis())
81 | .setTicker(Ticker)
82 | .setContentTitle(title)
83 | .setContentText(ContentText)
84 | .setSmallIcon(SmallIcon)
85 | .setContentIntent(pendingIntent)
86 | .setAutoCancel(true)
87 | .build();
88 | try {
89 | notification = setIconBadgeNumManager.setIconBadgeNum(context, notification, i);
90 | nm.notify(notifyID, notification);
91 | } catch (Exception e) {
92 | if (e.toString().equals(""))
93 | Log.d("SendIconNumUtil", e.toString());
94 | }
95 | }
96 |
97 | /**
98 | * 设置角标并且带通知栏(不设置通知栏渠道 默认为渠道为:其他)
99 | *
100 | * @param i 角标数字(为0时清空角标)
101 | * @param context 上下文
102 | * @param notifyID 通知id
103 | * @param pendingIntent 跳转事件
104 | * @param title 标题
105 | * @param channelId 通知栏 id
106 | * @param SmallIcon 图标
107 | * @param Ticker
108 | * @param ContentText 通知内容
109 | */
110 | public static void sendIconNumNotification(int i, Application context, int notifyID, PendingIntent pendingIntent, String title, String channelId, int SmallIcon
111 | , String Ticker, String ContentText) {
112 |
113 | NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
114 | if (nm == null) return;
115 | Notification notification = null;
116 | String notificationChannelId = null;
117 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
118 | NotificationChannel notificationChannel = createNotificationChannel(channelId, "");
119 | nm.createNotificationChannel(notificationChannel);
120 | notificationChannelId = notificationChannel.getId();
121 |
122 | }
123 | notification = new NotificationCompat.Builder(context, notificationChannelId)
124 | .setSmallIcon(context.getApplicationInfo().icon)
125 | .setWhen(System.currentTimeMillis())
126 | .setTicker(Ticker)
127 | .setContentTitle(title)
128 | .setContentText(ContentText)
129 | .setSmallIcon(SmallIcon)
130 | .setContentIntent(pendingIntent)
131 | .setAutoCancel(true)
132 | .build();
133 | try {
134 | notification = setIconBadgeNumManager.setIconBadgeNum(context, notification, i);
135 | nm.notify(notifyID, notification);
136 | } catch (Exception e) {
137 | if (e.toString().equals(""))
138 | Log.d("SendIconNumUtil", e.toString());
139 | }
140 | }
141 |
142 | /**
143 | * 使用自定义通知栏
144 | *
145 | * @param i 角标显示数量
146 | * @param context 上下文
147 | * @param notifyID 通知id
148 | * @param notification 自定义通知栏
149 | * @param nm 通知栏管理器
150 | */
151 | public static void sendIconNumNotification(int i, Application context, int notifyID, Notification notification, NotificationManager nm) {
152 |
153 | try {
154 | notification = setIconBadgeNumManager.setIconBadgeNum(context, notification, i);
155 | nm.notify(notifyID, notification);
156 | } catch (Exception e) {
157 | Log.d("SendIconNumUtil", e.toString());
158 | }
159 | }
160 |
161 |
162 | @RequiresApi(api = Build.VERSION_CODES.O)
163 | private static NotificationChannel createNotificationChannel(String channelId, String channelName) {
164 | String channelNames = channelName;
165 | NotificationChannel channel = null;
166 | channel = new NotificationChannel(channelId,
167 | (channelNames.equals("") ? "其他" : channelNames), NotificationManager.IMPORTANCE_DEFAULT);
168 | channel.canBypassDnd();//是否绕过勿扰模式
169 | channel.setBypassDnd(true);
170 | channel.enableLights(true); //是否在桌面icon右上角展示小红点
171 | channel.setLightColor(Color.RED); //小红点颜色
172 | channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
173 | return channel;
174 | }
175 |
176 |
177 | }
178 |
--------------------------------------------------------------------------------
/app/src/main/libs/arm64-v8a/libjcore127.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/arm64-v8a/libjcore127.so
--------------------------------------------------------------------------------
/app/src/main/libs/armeabi-v7a/libjcore127.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/armeabi-v7a/libjcore127.so
--------------------------------------------------------------------------------
/app/src/main/libs/armeabi/libjcore127.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/armeabi/libjcore127.so
--------------------------------------------------------------------------------
/app/src/main/libs/jcore-android-1.2.7.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/jcore-android-1.2.7.jar
--------------------------------------------------------------------------------
/app/src/main/libs/jpush-android-3.2.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/jpush-android-3.2.0.jar
--------------------------------------------------------------------------------
/app/src/main/libs/mips/libjcore127.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/mips/libjcore127.so
--------------------------------------------------------------------------------
/app/src/main/libs/mips64/libjcore127.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/mips64/libjcore127.so
--------------------------------------------------------------------------------
/app/src/main/libs/x86/libjcore127.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/x86/libjcore127.so
--------------------------------------------------------------------------------
/app/src/main/libs/x86_64/libjcore127.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/libs/x86_64/libjcore127.so
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/jpush_ic_richpush_actionbar_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/drawable/jpush_ic_richpush_actionbar_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/jpush_ic_richpush_actionbar_divider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/drawable/jpush_ic_richpush_actionbar_divider.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/jpush_richpush_btn_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/jpush_richpush_progressbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 |
9 |
10 |
11 |
12 | -
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
20 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main2.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/image_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
20 |
21 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/jpush_popwin_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/jpush_webview_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
31 |
32 |
44 |
45 |
46 |
53 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/push_notification.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
27 |
33 |
40 |
48 |
55 |
56 |
57 |
58 |
66 |
67 |
68 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/timg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-xxhdpi/timg.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/jpush_style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AppIconNumTest
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/badges/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.github.dcendents.android-maven'
3 | group='675945646@qq.com'
4 |
5 | android {
6 | compileSdkVersion 28
7 |
8 |
9 |
10 | defaultConfig {
11 | minSdkVersion 15
12 | targetSdkVersion 28
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
17 |
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 |
27 | }
28 |
29 | dependencies {
30 | implementation fileTree(dir: 'libs', include: ['*.jar'])
31 |
32 | implementation 'com.android.support:appcompat-v7:28.0.0-beta01'
33 | testImplementation 'junit:junit:4.12'
34 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
35 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
36 | }
37 |
--------------------------------------------------------------------------------
/badges/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/badges/src/main/java/com/tot/badges/IconBadgeNumManager.java:
--------------------------------------------------------------------------------
1 | package com.tot.badges;
2 |
3 | import android.app.Application;
4 | import android.app.Notification;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.net.Uri;
8 | import android.os.Build;
9 | import android.os.Bundle;
10 | import android.support.annotation.NonNull;
11 | import android.text.TextUtils;
12 | import android.util.Log;
13 |
14 | import java.lang.reflect.Field;
15 | import java.lang.reflect.Method;
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | import static com.tot.badges.Utils.UNABLE_TO_RESOLVE_INTENT_ERROR_;
20 |
21 | public class IconBadgeNumManager {
22 | private static final String NOTIFICATION_XiaoMi_ERROR = "Xiaomi phones must send notification";
23 | private static final String NOTIFICATION_GOOGLe_ERROR = "google not support before API O";
24 | private static final String NOT_SUPPORT_LAUNCHER = "not support your launcher [ default launcher is null ]";
25 | private static final String NOT_SUPPORT_LAUNCHER_ = "not support ";
26 | private static final String NOTIFICATION_VIVO_ERROR = "not support : vivo";
27 | private static final String NOTIFICATION_OPPO_ERROR = "not support : oppo";
28 | private static final String NOTIFICATION_MEIZU_ERROR = "not support : meizu";
29 | private Map iconBadgeNumModelMap;
30 | private LauncherHelper launcherHelper;
31 |
32 | public IconBadgeNumManager() {
33 | this.launcherHelper = new LauncherHelper();
34 | iconBadgeNumModelMap = new HashMap<>();
35 | }
36 |
37 |
38 | public Notification setIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
39 | switch (getSetIconBadgeNumModel(context)) {
40 | case LauncherHelper.HUAWEI:
41 | return setIconHuaWeiBadgeNum(context, notification, count);
42 | case LauncherHelper.XIAOMI:
43 | return setXiaoMiIconBadgeNum(context, notification, count);
44 | case LauncherHelper.VIVO:
45 | return setVIVOIconBadgeNum(context, notification, count);
46 | case LauncherHelper.OPPO:
47 | return setOPPOIconBadgeNum(context, notification, count);
48 | case LauncherHelper.SAMSUNG:
49 | return setSamsungIconBadgeNum(context, notification, count);
50 | case LauncherHelper.MEIZU:
51 | return setMeiZuIconBadgeNum(context, notification, count);
52 | case LauncherHelper.GOOGLE:
53 | return setGoogleIconBadgeNum(context, notification, count);
54 | default:
55 | throw new Exception(NOT_SUPPORT_LAUNCHER_ + getSetIconBadgeNumModel(context));
56 | }
57 |
58 | // IconBadgeNumModel iconBadgeNumModel = getSetIconBadgeNumModel(context);
59 | // return iconBadgeNumModel.setIconBadgeNum(context, notification, count);
60 |
61 | }
62 |
63 | private String getSetIconBadgeNumModel(@NonNull Application application) throws Exception {
64 | String launcherName = launcherHelper.getLauncherPackageName(application);
65 | if (TextUtils.isEmpty(launcherName)) {
66 | throw new Exception(NOT_SUPPORT_LAUNCHER);
67 | }
68 | String launcherType = launcherHelper.getLauncherTypeByName(launcherName);
69 | if (TextUtils.isEmpty(launcherType)) {
70 | throw new Exception(NOT_SUPPORT_LAUNCHER_ + launcherName);
71 | }
72 | if (iconBadgeNumModelMap.containsKey(launcherType)) {
73 | return launcherType;
74 | }
75 | iconBadgeNumModelMap.put(launcherType, launcherType);
76 | return launcherName;
77 | }
78 |
79 |
80 | /**
81 | * https://developer.huawei.com/consumer/cn/devservice/doc/30802
82 | * 华为角标生成方法
83 | * max:99
84 | */
85 | public Notification setIconHuaWeiBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
86 | Bundle bunlde = new Bundle();
87 | bunlde.putString("package", context.getPackageName()); // com.test.badge is your package name
88 | bunlde.putString("class", Utils.getInstance().getLaunchIntentForPackage(context)); // com.test. badge.MainActivity is your apk main activity
89 | bunlde.putInt("badgenumber", count);
90 | context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bunlde);
91 | return notification;
92 | }
93 |
94 |
95 | //Google 生成方法
96 | public Notification setGoogleIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
97 | if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
98 | throw new Exception(NOTIFICATION_GOOGLe_ERROR);
99 | }
100 | Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
101 | intent.putExtra("badge_count", count);
102 | intent.putExtra("badge_count_package_name", context.getPackageName());
103 | intent.putExtra("badge_count_class_name", Utils.getInstance().getLaunchIntentForPackage(context)); // com.test. badge.MainActivity is your apk main activity
104 | context.sendBroadcast(intent);
105 | return notification;
106 | }
107 |
108 |
109 | //魅族手机(暂不支持消息角标)
110 | public Notification setMeiZuIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
111 | if (true) {
112 | throw new Exception(NOTIFICATION_MEIZU_ERROR);
113 | }
114 | return null;
115 | }
116 |
117 |
118 | /**
119 | * 以下是oppo客服原文(其中没有说明3.3中日活量和总下载量的标准)
120 | *
121 | * 亲,您可以通过邮件的形式提交申请,邮件形式如下:
122 | *
123 | * 1.主题:“申请开放OPPO手机应用角标权限——(应用名称)”
124 | *
125 | * 2.收件人:devtec@oppo.com
126 | *
127 | * 3.正文:应用角标申请所需材料
128 | * 以下为应用角标申请所需材料:
129 | * 1.应用方申请人基本信息(姓名、邮箱、手机、微信);
130 | * 2.应用方厂商介绍(不少于200字);
131 | * 3.申请应用近一个月内IOS与安卓系统的平均日活量及总下载量介绍;
132 | * 4.申请应用产品主要功能介绍(不少于100字);
133 | * 5.申请应用期望角标出现的全部场景。(即哪些类的消息需要出现角标,需全部列出)
134 | *
135 | * 您这边以邮件的形式申请接入角标后,OPPO方审核人员将在接收日期10个工作日内给出审核结果。感谢您对OPPO开放平台的关注与信任,还
136 | * 请您耐心等待的哦~
137 | */
138 | public Notification setOPPOIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
139 | if (true) {
140 | throw new Exception(NOTIFICATION_OPPO_ERROR);
141 | }
142 | return null;
143 | }
144 |
145 | /**
146 | * 没有找到官方文档说明,只有网上的方法
147 | *
148 | * Galaxy S8/SM-G9500/android 8.0
149 | * Galaxy Galaxy Note8/SM-N9500/android 8.0
150 | */
151 | public Notification setSamsungIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
152 | Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
153 | intent.putExtra("badge_count", count);
154 | intent.putExtra("badge_count_package_name", context.getPackageName());
155 | intent.putExtra("badge_count_class_name", Utils.getInstance().getLaunchIntentForPackage(context));
156 |
157 | if (Utils.getInstance().canResolveBroadcast(context, intent)) {
158 | context.sendBroadcast(intent);
159 | } else {
160 | throw new Exception(UNABLE_TO_RESOLVE_INTENT_ERROR_ + intent.toString());
161 | }
162 | return notification;
163 | }
164 |
165 |
166 | /**
167 | * 网上查到了此段代码,但在vivo X21A[android-8.1.0/Funtouch OS_4.0]真机上并未测试成功。
168 | * 在vivo开发者平台上与人工客服联系后,对方回复暂时没有公开的方法可以设置,也没有渠道可以申请,只有vivo特别指定的应用可以实现(微信、微博等)
169 | */
170 | public Notification setVIVOIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
171 | try {
172 | Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
173 | intent.putExtra("packageName", context.getPackageName());
174 | String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
175 | intent.putExtra("className", launchClassName);
176 | intent.putExtra("notificationNum", count);
177 | context.sendBroadcast(intent);
178 | } catch (Exception e) {
179 | throw new Exception(NOTIFICATION_VIVO_ERROR);
180 | }
181 | return notification;
182 | }
183 |
184 | /**
185 | * https://dev.mi.com/console/doc/detail?pId=939
186 | *
小米生成的方法
187 | * 必须发送通知
188 | */
189 | public Notification setXiaoMiIconBadgeNum(@NonNull Application context, Notification notification, int count) throws Exception {
190 | if (notification == null) {
191 | throw new Exception(NOTIFICATION_XiaoMi_ERROR);
192 | }
193 | Field field = notification.getClass().getDeclaredField("extraNotification");
194 | Object extraNotification = field.get(notification);
195 | Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
196 | method.invoke(extraNotification, count);
197 | return notification;
198 | }
199 |
200 |
201 | }
202 |
--------------------------------------------------------------------------------
/badges/src/main/java/com/tot/badges/LauncherHelper.java:
--------------------------------------------------------------------------------
1 | package com.tot.badges;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.ResolveInfo;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 |
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | public class LauncherHelper {
13 | public final static String GOOGLE = "google";
14 | public final static String HUAWEI = "huawei";
15 | public final static String MEIZU = "meizu";
16 | public final static String XIAOMI = "xiaomi";
17 | public final static String OPPO = "oppo";
18 | public final static String VIVO = "vivo";
19 | public final static String SAMSUNG = "samsung";
20 |
21 | private static Map launcherMap;
22 |
23 | static {
24 | launcherMap = new HashMap<>();
25 | launcherMap.put("com.huawei.android.launcher", HUAWEI);
26 | launcherMap.put("com.miui.home", XIAOMI);
27 | launcherMap.put("com.sec.android.app.launcher", SAMSUNG);
28 | launcherMap.put("com.google.android.apps.nexuslauncher", GOOGLE);
29 | }
30 |
31 | @Nullable
32 | public String getLauncherTypeByName(@NonNull String launcherName) {
33 | return launcherMap.get(launcherName);
34 | }
35 |
36 | @Nullable
37 | public String getLauncherPackageName(@NonNull Context context) {
38 | final Intent intent = new Intent(Intent.ACTION_MAIN);
39 | intent.addCategory(Intent.CATEGORY_HOME);
40 | final ResolveInfo res = context.getPackageManager().resolveActivity(intent, 0);
41 | if (res.activityInfo == null) {
42 | // should not happen. A home is always installed, isn't it?
43 | return null;
44 | }
45 | if (res.activityInfo.packageName.equals("android")) {
46 | return null;
47 | } else {
48 | return res.activityInfo.packageName;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/badges/src/main/java/com/tot/badges/Utils.java:
--------------------------------------------------------------------------------
1 | package com.tot.badges;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.PackageManager;
6 | import android.content.pm.ResolveInfo;
7 |
8 | import java.util.List;
9 |
10 | public class Utils {
11 | public static final String UNABLE_TO_RESOLVE_INTENT_ERROR_ = "unable to resolve intent: ";
12 |
13 | private static Utils instance;
14 |
15 | public static Utils getInstance() {
16 | if (instance == null) {
17 | instance = new Utils();
18 | }
19 | return instance;
20 | }
21 |
22 | public boolean canResolveBroadcast(Context context, Intent intent) {
23 | PackageManager packageManager = context.getPackageManager();
24 | List receivers = packageManager.queryBroadcastReceivers(intent, 0);
25 | return receivers != null && receivers.size() > 0;
26 | }
27 |
28 | public String getLaunchIntentForPackage(Context context) {
29 | return context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/badges/src/main/java/com/tot/badges/sendIconNumUtil.java:
--------------------------------------------------------------------------------
1 | package com.tot.badges;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.app.Notification;
6 | import android.app.NotificationChannel;
7 | import android.app.NotificationManager;
8 | import android.app.PendingIntent;
9 | import android.content.Context;
10 | import android.graphics.Color;
11 | import android.os.Build;
12 | import android.os.Bundle;
13 | import android.support.annotation.RequiresApi;
14 | import android.support.v4.app.NotificationCompat;
15 | import android.util.Log;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | /**
21 | * 创建时间: 2019/3/12 0012.
22 | * 创建人: yanbin
23 | * 功能:
24 | */
25 |
26 | public class SendIconNumUtil {
27 |
28 | private static IconBadgeNumManager setIconBadgeNumManager = new IconBadgeNumManager();
29 | private static NotificationManager nm, customNm;
30 | private static List mData = new ArrayList<>();
31 | private static List mCustomData = new ArrayList<>();
32 |
33 | /**
34 | * 设置角标(不带出现通知栏)
35 | *
36 | * @param i 角标数字(为0时清空角标)
37 | * @param context 上下文
38 | */
39 | public static void sendIconNumNotification(int i, Application context) {
40 | nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
41 | if (nm == null) return;
42 | String notificationChannelId = null;
43 |
44 | Notification notification = null;
45 | try {
46 | notification = new NotificationCompat.Builder(context, notificationChannelId)
47 | .setAutoCancel(true)
48 | .build();
49 | notification = setIconBadgeNumManager.setIconBadgeNum(context, notification, i);
50 | nm.notify(0, notification);
51 | // nm.notify();
52 | } catch (Exception e) {
53 | e.printStackTrace();
54 | }
55 | }
56 |
57 | /**
58 | * 设置角标并且带通知栏
59 | *
60 | * @param i 角标数字(为0时清空角标)
61 | * @param context 上下文
62 | * @param notifyID 通知id(类似于主键 如果通知id相同不管多少通知都只会显示最新一条)
63 | * @param pendingIntent 跳转事件
64 | * @param title 标题
65 | * @param channelId 通知栏 id
66 | * @param SmallIcon 图标
67 | * @param Ticker
68 | * @param ContentText 通知内容
69 | * @param channeName 通知渠道设置(区分通知类型默认为其他)
70 | */
71 | public static void sendIconNumNotification(int i, Application context, int notifyID, PendingIntent pendingIntent, String title, String channelId, int SmallIcon
72 | , String Ticker, String ContentText, String channeName) {
73 | nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
74 | if (nm == null) return;
75 | Notification notification = null;
76 | String notificationChannelId = null;
77 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
78 | NotificationChannel notificationChannel = createNotificationChannel(channelId, channeName);
79 | nm.createNotificationChannel(notificationChannel);
80 | notificationChannelId = notificationChannel.getId();
81 | mData.add(notifyID + "");
82 |
83 | }
84 | notification = new NotificationCompat.Builder(context, notificationChannelId)
85 | .setSmallIcon(context.getApplicationInfo().icon)
86 | .setWhen(System.currentTimeMillis())
87 | .setTicker(Ticker)
88 | .setContentTitle(title)
89 | .setContentText(ContentText)
90 | .setSmallIcon(SmallIcon)
91 | .setDefaults(Notification.DEFAULT_ALL)
92 | .setLights(Color.YELLOW, 300, 0)
93 | .setContentIntent(pendingIntent)
94 | .setAutoCancel(true)
95 | .build();
96 | try {
97 | notification = setIconBadgeNumManager.setIconBadgeNum(context, notification, i);
98 | nm.notify(notifyID, notification);
99 | } catch (Exception e) {
100 | if (e.toString().equals(""))
101 | Log.d("SendIconNumUtil", e.toString());
102 | }
103 | }
104 |
105 | /**
106 | * 设置角标并且带通知栏(不设置通知栏渠道 默认为渠道为:其他 其他类型的通道ID固定为otherTypes)
107 | *
108 | * @param i 角标数字(为0时清空角标)
109 | * @param context 上下文
110 | * @param notifyID 通知id
111 | * @param pendingIntent 跳转事件
112 | * @param title 标题
113 | * // * @param channelId 通知栏 id
114 | * @param SmallIcon 图标
115 | * @param Ticker
116 | * @param ContentText 通知内容
117 | */
118 | public static void sendIconNumNotification(int i, Application context, int notifyID, PendingIntent pendingIntent, String title, int SmallIcon
119 | , String Ticker, String ContentText) {
120 | nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
121 | if (nm == null) return;
122 | Notification notification = null;
123 | String notificationChannelId = null;
124 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
125 | NotificationChannel notificationChannel =
126 | createNotificationChannel("otherTypes", "");
127 | nm.createNotificationChannel(notificationChannel);
128 | notificationChannelId = notificationChannel.getId();
129 | mData.add(notifyID + "");
130 |
131 | }
132 | notification = new NotificationCompat.Builder(context, notificationChannelId)
133 | .setSmallIcon(context.getApplicationInfo().icon)
134 | .setWhen(System.currentTimeMillis())
135 | .setTicker(Ticker)
136 | .setContentTitle(title)
137 | .setContentText(ContentText)
138 | .setSmallIcon(SmallIcon)
139 | .setContentIntent(pendingIntent)
140 | .setAutoCancel(true)
141 | .build();
142 | try {
143 | notification = setIconBadgeNumManager.setIconBadgeNum(context, notification, i);
144 | nm.notify(notifyID, notification);
145 | } catch (Exception e) {
146 | if (e.toString().equals(""))
147 | Log.d("SendIconNumUtil", e.toString());
148 | }
149 | }
150 |
151 | /**
152 | * 使用自定义通知栏
153 | *
154 | * @param i 角标显示数量
155 | * @param context 上下文
156 | * @param notifyID 通知id
157 | * @param notification 自定义通知栏
158 | * @param nm 通知栏管理器
159 | */
160 | public static void sendIconNumNotification(int i, Application context, int notifyID, Notification notification, NotificationManager nm) {
161 |
162 | try {
163 | notification = setIconBadgeNumManager.setIconBadgeNum(context, notification, i);
164 | nm.notify(notifyID, notification);
165 | customNm = nm;
166 | mCustomData.add(notifyID + "");
167 | } catch (Exception e) {
168 | Log.d("SendIconNumUtil", e.toString());
169 | }
170 | }
171 |
172 |
173 | //清除通知栏消息(默认的 更具传入消息id清除)
174 | public static void clearIconNumNotifucation(int notifyId) {
175 | nm.cancel(notifyId);
176 | }
177 |
178 | //清除自定义消息的
179 | public static void clearCustomIconNumNotifucation(int notifyId) {
180 | customNm.cancel(notifyId);
181 | }
182 |
183 | //清除所有的
184 | public static void clearAllIconNumNotifucation() {
185 | int notifyid, notifyAllId;
186 | if (mData.size() > 0 && mData != null) {
187 | for (int i = 0; i < mData.size(); i++) {
188 | notifyid = Integer.parseInt(mData.get(i));
189 | nm.cancel(notifyid);
190 | }
191 | }
192 | if (mCustomData.size() > 0 && mCustomData != null)
193 | for (int i = 0; i < mCustomData.size(); i++) {
194 | notifyAllId = Integer.parseInt(mCustomData.get(i));
195 | customNm.cancel(notifyAllId);
196 | }
197 | }
198 |
199 |
200 | @RequiresApi(api = Build.VERSION_CODES.O)
201 | private static NotificationChannel createNotificationChannel(String channelId, String channelName) {
202 | NotificationChannel channel = null;
203 | if (channelName.equals("")) {
204 | //第三个参数为通知等级 默认渠道为为两级有自定义渠道名的为三级(该等级用户可自动调控 没必要的话不需要调整)]
205 | channel = new NotificationChannel(channelId, "其他", NotificationManager.IMPORTANCE_LOW);
206 | } else {
207 | channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
208 | }
209 |
210 |
211 | Log.d("haha", channelName.equals("") ? "其他" : channelName);
212 | // channel.canBypassDnd();//是否绕过勿扰模式
213 | // channel.setBypassDnd(true);
214 | channel.enableLights(true); //是否在桌面icon右上角展示小红点
215 | channel.setLightColor(Color.RED); //小红点颜色
216 | channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
217 | return channel;
218 | }
219 |
220 | public static void init(final Application application) {
221 | application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
222 | @Override
223 | public void onActivityCreated(Activity activity, Bundle bundle) {
224 | }
225 |
226 | @Override
227 | public void onActivityStarted(Activity activity) {
228 |
229 | //不带通知栏的
230 | SendIconNumUtil.sendIconNumNotification(0, application);
231 | //测试修改
232 | }
233 |
234 | @Override
235 | public void onActivityResumed(Activity activity) {
236 | }
237 |
238 | @Override
239 | public void onActivityPaused(Activity activity) {
240 | }
241 |
242 | @Override
243 | public void onActivityStopped(Activity activity) {
244 |
245 | }
246 |
247 | @Override
248 | public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
249 | }
250 |
251 | @Override
252 | public void onActivityDestroyed(Activity activity) {
253 |
254 | }
255 | });
256 | }
257 |
258 | // @Override
259 | // public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
260 | //
261 | // }
262 | //
263 | // @Override
264 | // public void onActivityStarted(Activity activity) {
265 | //
266 | // }
267 | //
268 | // @Override
269 | // public void onActivityResumed(Activity activity) {
270 | //
271 | // }
272 | //
273 | // @Override
274 | // public void onActivityPaused(Activity activity) {
275 | //
276 | // }
277 | //
278 | // @Override
279 | // public void onActivityStopped(Activity activity) {
280 | //
281 | // }
282 | //
283 | // @Override
284 | // public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
285 | //
286 | // }
287 | //
288 | // @Override
289 | // public void onActivityDestroyed(Activity activity) {
290 | //
291 | // }
292 |
293 |
294 | }
295 |
--------------------------------------------------------------------------------
/badges/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | LauncherIconBadges
3 |
4 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.1.3'
11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | google()
18 | jcenter()
19 | maven { url 'https://jitpack.io' }
20 | }
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
26 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | android.injected.testOnly=false
15 | android.useDeprecatedNdk=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ybzqh/GSAppBadge/0b1f0c47846183f47a1e2c922b71d8439ed4a624/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Aug 02 16:44:30 GMT+08:00 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Mon Mar 11 11:57:49 CST 2019
11 | ndk.dir=F\:\\ide\\ide\\sdk\\ndk-bundle
12 | sdk.dir=F\:\\ide\\ide\\sdk
13 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':badges'
2 |
--------------------------------------------------------------------------------