目的:制作消息提醒,横幅显示并显示应用角标数量
前言:首先通过查阅资料,消息提醒不需要区分设备类型,而应用角标在原生APP上只会显示一个小圆点,不会显示数字,颜色有绿的白的等等。于是各大厂商纷纷定制属于自己的应用角标,所以对于应用角标这个功能,我们需要调用对应厂商的API。
1、状态栏通知 - Notification
消息提醒又叫状态栏通知Notification,很常见。像微信、QQ、短信一有消息就会推送通知到状态栏。
基本布局:
组成元素 | 说明 |
---|---|
Icon/Photo | 大图标 |
Title/Name | 标题 |
Message | 内容信息 |
Timestamp | 通知时间,默认是发出通知的时间,可以通过 setWhen() 设置 |
Secondary Icon | 小图标 |
内容文字 | 在小图标的左手边的一个文字 |
从基本布局中我们可以直观了解Notification的构造,最基础设置一个通知时间,发送一个内容信息,就可以进行提醒,再者设置一个级别,使它能够横幅显示,锁屏显示,设置一个响铃等等,根据需求设置我们需要的内容。
状态通知栏主要涉及到2个类:
Notification
和NotificationManager
Notification:通知信息类,对应通知栏的各种属性
NotificationManager:状态栏的管理类,负责发通知、清除通知等操作。
1、首先要获得NotificationManager
对象,一般是打开应用开启
onCreate(){
NotificationManager mNManager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
}
2、创建一个通知栏的Builder
构造类
Notification.Builder mBuilder = new Notification.Builder(this);
3、对 mBuilde
r 进行相关的设置,比如标题,内容,图标,动作等
4、调用 mBuilder.build()
方法为 notification 赋值
5、调用 NotificationManager.notify()
方法发送通知
6、另外我们还可以调用 NotificationManager.cancel()
方法取消通知
设置优先级 - setPriority(int)
设置标题/内容/图标比较简单,了解一下比较核心的设置,优先级
优先级 | 参数 | 程度 |
---|---|---|
Notification.PRIORITY_MAX | 2 | 重要而紧急的通知 |
Notification.PRIORITY_HIGH | 1 | 高优先级用于重要的通信内容 |
Notification.PRIORITY_DEFAULT | 0 | 没有特殊优先级分类的通知 |
Notification.PRIORITY_LOW | -1 | 低优先级可以通知用户但又不是很紧急的事件 |
Notification.PRIORITY_MIN | -2 | 用于后台消息,用户下拉通知抽屉才能看到内容 |
设置振动方式 - setVibrate(long[])
振动方式就比较有意思了,我们可以根据振动方式设置短振动、长振动、自定义振动等。
setVibrate(new long[]{0,100,300,500});
例如这个振动方式就表示延迟0ms,振动100ms,再延迟300ms,振动500ms
设置启动页面 - setContentIntent(PendingIntent)
一般用来通过设置PendingIntent来启动指定页面,当然也可以设置执行次数,但主要是用于远程服务通信、闹铃、通知等,用的比较少。
PendingIntent 的位标识符(第四个参数) 可以是以下值值之一
值 | 说明 |
FLAG_ONE_SHOT | 表示返回的 PendingIntent 仅能执行一次,执行完后自动取消 |
FLAG_NO_CREATE | 表示如果描述的 PendingIntent 不存在,并不创建相应的 PendingIntent,而是返回 NULL |
FLAG_CANCEL_CURRENT | 表示相应的 PendingIntent 已经存在,则取消前者,然后创建新的 PendingIntent,这个有利于数据保持为最新的,可以用于即时通信的通信场景 |
FLAG_UPDATE_CURRENT | 表示更新的 PendingIntent |
Intent intent = new Intent(mContxt,DemoActivity.class);
// 上下文、请求码、intent对象、标志位
PendingIntent pIntent = PendingIntent.getActivity(mContxt,0,intent,0);
Notification.Builder mBuilder = new Notification.Builder(mContext);
mBuilder..setContentIntent(pendingIntent) // 设置PendingIntent
...
// 请求码是在创建多个PendingIntent时,使用请求码来区分他们,
// 然后结合标志位来进行更新或者取消当前PendingIntent
PendingIntent pIntent = PendingIntent.getActivity(mContext,100,intent,PendingIntent.FLAG_UPDATE_CURRENT);
// 这里我们设置了一个请求码为100,标志位为PendingIntent.FLAG_UPDATE_CURRENT;
// 当存在一个具有相同请求码的PendingIntent,那么旧的PendingIntent就会被更新;
// 同理,设置标志位为PendingIntent.FLAG_CANCEL_CURRENT 可以取消旧的 PendingIntent。
其他设置
1、设置进度条 - setProgress(int,int,boolean)
参数依次为:进度条最大数值,当前进度,进度是否不确定
2、setOngoing(boolean)
设置为 ture,表示它为一个正在进行的通知
3、设置接收到通知时的铃声 - setSound(Uri)
可以用系统的,也可以自己设置
4、设置三色灯 - setLights(int argb, int onMs, int offMs)
参数依次是:灯光颜色,亮持续时间,暗的时间
5、设置默认 - setDefaults(int)
属性 | 说明 |
---|---|
Notification.DEFAULT_VIBRATE | 添加默认震动提醒 |
Notification.DEFAULT_SOUND | 添加默认声音提醒 |
Notification.DEFAULT_LIGHTS | 添加默认三色灯提醒 |
Notification.DEFAULT_ALL | 添加默认以上3种全部提醒 |
2、应用角标 - Badge
如前言所说,原生Android没有对应用角标作定制化,所以在设置消息数量时,设置.setNumber(0),在应用图标上只能看得见一个小圆点,还不是红色的。于是各大厂商纷纷定制属于自家的应用角标,我使用过华为设备,操作起来也比较方便,不用担心内网外网这些
1、使用华为厂商角标的权限
<!-- 华为厂商角标 -->
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
2、将消息数量写全局方法
public static void setBadgeNumber(Context context, int number){
try {
if (number < 0) number = 0;
Bundle bundle = new Bundle();
bundle.putString("package", context.getPackageName());
String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
bundle.putString("class", launchClassName);
bundle.putInt("badgenumber", number);
context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bundle);
} catch (Exception e) {
e.printStackTrace();
}
}
3、哪里需要哪里调用即可
Notification.Builder mBuilder = new Notification.Builder(mContext);
notification = mBuilder.build();
notificationManager.notify(NOTIFY_ID, notification);
// 在状态栏通知初始化完调用也可以,建议在数量会变化的地方使用,做到实时刷新数量
setBadgeNumber(mContext,10);// 修改角标
示例代码
<!-- 访问系统通知、设置消息提醒权限 -->
<uses-permission android:name="android.permission.READ_LOCK_SCREEN_USAGE" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<!-- 华为厂商角标 -->
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
private Notification notification;//通知信息类
private NotificationManage notificationManage;//状态栏通知的管理类
private Context mContext;// 上下文
private int noti_number = 0;// 消息数量
@Override
protected void onCreate(Bundle savedInstanceState) {
mContext = DemoActivity.this;
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);// 要开启系统服务
// noti_btn相当于一个触发动作,并不一定是按钮,有可能是广播推送,有可能是服务推送,所以只需要在你需要触发的地方发送状态栏通知即可
noti_btn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
sendNotification();
}
});
}
// 发送通知
private void sendNotification(){
Notification.Builder mBuilder = new Notification.Builder(mContext);
mBuilder.setContentTitle("设置标题")
.setContentText("设置内容")
.setSubText("设置内容下面一小行的文字,API 16+ 才可以用")
.setTicker("设置收到通知时在顶部显示的文字信息")
.setWhen(System.currentTimeMillis())//设置通知时间,一般设置的是收到通知时的时间
.setSmallIcon(R.drawable.ic_launcher)//设置右下角的小图标,可以直接设置应用图标
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE) // 设置默认的三色灯与振动器
.setAutoCancel(true)// 用户点击 Notification 点击面板后是否让通知取消(默认不取消)
.setNumber(noti_number)//设置数量
.setPriority(Notification.PRIORITY_HIGH);//设置优先级
notification = mBuilder.Builder();
notificationManager.notify(1, notification);
setBadgeNumber(mContext,noti_number);
}
// 华为API -- 在你需要更新应用角标数量的任何地方使用该方法即可
public static void setBadgeNumber(Context context, int number){
try {
if (number < 0) number = 0;
Bundle bundle = new Bundle();
bundle.putString("package", context.getPackageName());
String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
bundle.putString("class", launchClassName);
bundle.putInt("badgenumber", number);
context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bundle);
} catch (Exception e) {
e.printStackTrace();
}
}
注:如果横幅没有弹出,去设置里看看通知设置有没有横幅、锁屏设置,有没有打开