欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Notification的基本使用和点击跳转中的注意事项

程序员文章站 2022-07-08 18:24:06
1、Android 中通知栏的基本使用 Notification,是一种具有全局效果的通知,可以在系统的通知栏中显示。当 APP 向系统发出通知时,它将先以图标的形式显示在通知栏...

1、Android 中通知栏的基本使用

Notification,是一种具有全局效果的通知,可以在系统的通知栏中显示。当 APP 向系统发出通知时,它将先以图标的形式显示在通知栏中。用户可以下拉通知栏查看通知的详细信息。通知栏和抽屉式通知栏均是由系统控制,用户可以随时查看。
首先创建通知,需要一个NotificationManager来对通知进行管理,可以调用Context的getSystemService()方法获取到。getSystemService()方法接收一个字符串参数用于确定获取系统的哪个服务,这里传入Context.NOTIFICATION_SERVICE即可。因此,获取NotificationManager的实例可以写成:

 NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

由于Notification用的是建造者模式,所以接下来需要使用一个Builder构造器来创建Notification对象,由于不同版本的Android系统对通知这部分进行部分功能的修改,这里建议使用support库中提供的兼容Api,support-v4库中有一个NotificationCompat类,使用这个类的构造器来创建Notification对象,就可以保证我们的程序在所有Android系统版本上都能正常工作了,代码如下:

 Notification notification = new NotificationCompat.Builder(context).build();

当然上面创建的一个空的Notification对象,更常用的是我们通过一系列的链式操作,来对这个对象进行一些属性的设置;
常见的使用方式如下:

public class NotificationUtils {

    /**
     * 显示一个普通的通知
     *
     * @param context 上下文
     */
    public static void showNotification(Context context, String msgContent, int id) {

        Intent intent = new Intent(context, StuMainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra("xxxABC",true);
        Bundle bundle = new Bundle();
        bundle.putSerializable("xxxEFG", xxxEFG);
        intent.putExtras(bundle);
        Notification notification = new NotificationCompat.Builder(context)
                /**设置通知左边的大图标**/
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.logo))
                /**设置通知右边的小图标**/
                .setSmallIcon(R.mipmap.logo)
                /**通知首次出现在通知栏,带上升动画效果的**/
                .setTicker("应用名")
                /**设置通知的标题**/
                .setContentTitle(msgContent)
                /**设置通知的内容**/
                .setContentText(msgContent)
                /**通知产生的时间,会在通知信息里显示**/
                .setWhen(System.currentTimeMillis())
                /**设置该通知优先级**/
                .setPriority(Notification.PRIORITY_DEFAULT)
                /**设置这个标志当用户单击面板就可以让通知将自动取消**/
                .setAutoCancel(true)
                /**设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)**/
                .setOngoing(false)
                /**向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:Notification.DEFAULT_ALL就是3种全部提醒**/
                .setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS)
                .setContentIntent(PendingIntent.getActivity(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT))
                .build();
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        /**发起通知**/
        notificationManager.notify(id, notification);
    }
}

注意:
1、上面的这个传了的一个id值,这个是用于标记通知的,表示是不同的通知。
2、setSmallIcon()方法用于设置通知的小图标,注意只能使用纯alpha图层的图片来进行设置,小图标会显示在系统状态栏上,setLargeIcon()方法用于设置通知的大图标,下拉系统栏时,就可以看到大图标了。
 

2、点击通知栏跳转

当我们要实现点击通知栏的跳转时,这个时候需要用到PendingIntent了,PendingIntent从名字上就可以看出和Intent有点类似,其实他们直接确实有不少的共同点,比如都可以指明某一个“意图”,都可以启动活动、服务、广播等,不同的是Intent更加倾向于去立即执行某个获取,而PendingIntent更加倾向于在某个合适的时机去执行某个动作。简单点可以这么理解,PendingIntent为延迟执行的Intent。

PendingIntent用法比较简单,它主要提供了几个静态方法用于获取PendingIntent的实例,可以根据需求来选择使用getActivity()、getBroadcast()、getService()几个方法的参数是相同的。

  //获取一个用于启动 Activity 的 PendingIntent 对象
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags);

//获取一个用于启动 Service 的 PendingIntent 对象
public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags);

//获取一个用于向 BroadcastReceiver 广播的 PendingIntent 对象
public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)


第一个参数是Context
第二个参数是一个标志位,用户标记不同的pendingIntent.
第三个参数是一个Intent对象,可以通过这个对象构建出PendingIntent的“意图”
第四个参数用户确定PendingIntent的行为,有4个flag值供选择.


flags: May be FLAG_ONE_SHOT,LAG_NO_CREATE,LAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens.

目前为止只提供FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT这四个flag

FLAG_ONE_SHOT:this PendingIntent can only be used once. If set, after send() is called on it, it will be automatically canceled for you and any future attempt to send through it will fail.
利用 FLAG_ONE_SHOT获取的PendingIntent只能使用一次,即使再次利用上面三个方法重新获取,再使用PendingIntent也将失败。

FLAG_NO_CREATE:if the described PendingIntent does not already exist, then simply return null instead of creating it.
利用FLAG_NO_CREAT获取的PendingIntent,若描述的Intent不存在则返回NULL值.

FLAG_CANCEL_CURRENT:if the described PendingIntent already exists, the current one is canceled before generating a new one. You can use this to retrieve a new PendingIntent when you are only changing the extra data in the Intent; by canceling the previous pending intent, this ensures that only entities given the new data will be able to launch it. If this assurance is not an issue, consider FLAG_UPDATE_CURRENT.
如果描述的PendingIntent已经存在,则在产生新的Intent之前会先取消掉当前的。你可用使用它去检索新的Intent,如果你只是想改变Intent中的额外数据的话。通过取消先前的Intent,可用确保只有最新的实体可用启动它。如果这一保证不是问题,考虑flag_update_current。

FLAG_UPDATE_CURRENT: if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don’t care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.
最经常使用的是FLAG_UPDATE_CURRENT,因为描述的Intent有 更新的时候需要用到这个flag去更新你的描述,否则组件在下次事件发生或时间到达的时候extras永远是第一次Intent的extras。


注意:
上面4个flag中最经常使用的是FLAG_UPDATE_CURRENT,因为描述的Intent有 更新的时候需要用到这个flag去更新你的描述,否则组件在下次事件发生或时间到达的时候extras永远是第一次Intent的extras。
使用 FLAG_CANCEL_CURRENT也能做到更新extras,只不过是先把前面的extras清除,另外FLAG_CANCEL_CURRENT和 FLAG_UPDATE_CURRENT的区别在于能否新new一个Intent,FLAG_UPDATE_CURRENT能够新new一个 Intent,而FLAG_CANCEL_CURRENT则不能,只能使用第一次的Intent。
此外还需要注意参数:
int requestCode : Private request code for the sender (currently not used).

PendingIntent contentIntent = PendingIntent.getActivity(context,
num, intent, PendingIntent.FLAG_UPDATE_CURRENT);

对于FLAG_UPDATE_CURRENT,如果上面的requestCode 为常量,则对于先后出现的若干Notification,则所有对应的Intent里面的extra被更新为最新的,就是全部同一为最后一次的。
相反,如果num每次不一样,则里面的Inent的数据没被更新。
对于FLAG_CANCEL_CURRENT,则只响应最前面的第一条Notifiacation,后面所有的不响应….