Android-0.使用Notification来处理消息通知


官方文档:
https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Compatibility (中文,主要参考)

示例

简单示例

测试代码:

        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("FCM_foreground", "FCM", NotificationManager.IMPORTANCE_HIGH);
            channel.enableLights(false);
            channel.enableVibration(false);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            }
        }

        String text = "这里是内容";
        Intent stateIntent = new Intent(this, MainActivity.class);
        stateIntent.putExtra(PAYLOAD, "abc");
        stateIntent.putExtra(PUSH_ID, "123");
        PendingIntent statePendingIntent = PendingIntent.getActivity(this, 0, stateIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this, "FCM_foreground")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("内容的标题")//设置内容标题
                .setContentText(text)//设置显示的内容
                .setContentIntent(statePendingIntent)//设置意图
                .setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE)
                .setSound(null)
                .setPriority(Notification.PRIORITY_HIGH)
                .setAutoCancel(true);//点击后消失

        NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);
        // notificationId is a unique int for each notification that you must define
        notificationManagerCompat.notify((int) 123, mBuilder.build());

效果如下:

自定义通知布局示例

layout_notificaiton.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:orientation="vertical"
    android:paddingEnd="48dp"
    android:paddingStart="48dp">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentRight="true"
        android:src="@mipmap/ic_launcher_round" />

    <TextView
        android:id="@+id/tv_s"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:gravity="center_vertical"
        android:text="Left" />

    <TextView
        android:id="@+id/tv_e"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:gravity="center_vertical"
        android:text="Right" />

</RelativeLayout>

测试代码:

 NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("FCM_foreground", "FCM", NotificationManager.IMPORTANCE_HIGH);
            channel.enableLights(false);
            channel.enableVibration(false);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            }
        }
        
        String text = "这里是内容";
        Intent stateIntent = new Intent(this, MainActivity.class);
        stateIntent.putExtra(PAYLOAD, "abc");
        stateIntent.putExtra(PUSH_ID, "123");
        PendingIntent statePendingIntent = PendingIntent.getActivity(this, 0, stateIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notificaiton);
        remoteViews.setTextViewText(R.id.tv_s, "Start");
        remoteViews.setTextViewText(R.id.tv_e, "End");
        remoteViews.setImageViewResource(R.id.iv_icon, R.mipmap.ic_launcher);
        remoteViews.setOnClickPendingIntent(R.id.tv_e, statePendingIntent);// 去掉就不能点击跳转

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this, "FCM_foreground")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("内容的标题")//设置内容标题
                .setContentText(text)//设置显示的内容
                .setContent(remoteViews)//在这里设置自定义通知的内容
                //.setContentIntent(statePendingIntent)
                .setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE)
                .setSound(null)
                .setPriority(Notification.PRIORITY_HIGH)
                .setAutoCancel(true);

        NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);
        // notificationId is a unique int for each notification that you must define
        notificationManagerCompat.notify((int) 123, mBuilder.build());

效果:

可以看出,只有点击到End按钮上才会跳转,而且setContentTitle这些接口都无效了,因为现在使用的是自定义通知栏。

弹出式示例

        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("FCM_foreground", "FCM", NotificationManager.IMPORTANCE_HIGH);
            channel.enableLights(false);
            channel.enableVibration(false);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            }
        }

        String text = "这里是内容";
        Intent stateIntent = new Intent(this, MainActivity.class);
        stateIntent.putExtra(PAYLOAD, "abc");
        stateIntent.putExtra(PUSH_ID, "123");
        PendingIntent statePendingIntent = PendingIntent.getActivity(this, 0, stateIntent, PendingIntent.FLAG_CANCEL_CURRENT);
        
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this, "FCM_foreground")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("内容的标题")//设置内容标题
                .setContentText(text)//设置显示的内容
                //.setContent(remoteViews)//在这里设置自定义通知的内容
                .setFullScreenIntent(statePendingIntent,true)
                //.setContentIntent(statePendingIntent)
                .setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE)
                .setSound(null)
                .setPriority(Notification.PRIORITY_HIGH)
                .setAutoCancel(true);

        NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);
        // notificationId is a unique int for each notification that you must define
        notificationManagerCompat.notify((int) 123, mBuilder.build());

效果:

华为,小米还是会显示成抽屉式的,不会显示桌面悬浮窗

简介

Android官方提供了NotificationCompat兼容类来帮助开发实现体验统一的Notification

在升级到Android O (Android 8.0)版本后, 推荐使用NotificationCompat.Builder(Context context, String channelId),之前的notification可以直接加一个String参数即可。

channelId的实际作用是将notification进行分类,如设置不同优先级等。

Notification是一种具有全局效果的通知,可以在系统的通知栏中显示。当 APP 向系统发出通知时,它将先以图标的形式显示在通知栏中。用户可以下拉通知栏查看通知的详细信息。通知栏和抽屉式通知栏均是由系统控制,用户可以随时查看。

通知的目的是告知用户 App 事件。在平时的使用中,通知主要有以下几个作用:
1. 显示接收到短消息、及时消息等信息(如QQ、微信、新浪、短信)。
2. 显示客户端的推送消息,如广告、优惠、版本更新、推荐新闻等,常用的第三方 SDK 有: JPush 、 个推 、 阿里云推送。
3. 显示正在进行的事物,例如:后台运行的程序,如音乐播放进度、下载进度等。

其中,前两点可以归结为与用户交互,第三点是实时的任务提醒,但不可否认的是,第三点也会与用户交互。

Notification 的基本操作

Notification 的基本操作主要有创建、更新、取消这三种。一个 Notification 的必要属性有三项,如果不设置则在运行时会抛出异常:

1.小图标,通过 setSmallIcon 方法设置。
2.标题,通过 setContentTitle方法设置。
3.内容,通过 setContentText方法设置。

除了以上三项,其它均为可选项。虽然如此,但还是应该给 Notification 设置一个 Action ,这样就可以直接跳转到 App 的某个 Activity 、启动一个 Service 或者发送一个 Broadcast。否则,Notification 仅仅只能起到通知的效果,而不能与用户交互。

当系统接收到通知时,可以通过震动、响铃、呼吸灯等多种方式进行提醒。

创建 Notification

获取 NotificationManager 对象:

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

前面讲到,Notification 有三个必要属性。下面,我们就来创建一个简单的 Notification 。主要有以下三步:

  1. 获取 NotificationManager 实例。
  2. 实例化 NotificationCompat.Builder 并设置相关属性。
  3. 通过 builder.build() 方法生成 Notification 对象,并发送通知。

示例代码:

        NotificationManager notifyManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        //实例化NotificationCompat.Builde并设置相关属性
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "abc")
                //设置小图标
                .setSmallIcon(R.mipmap.ic_launcher)
                //设置通知标题
                .setContentTitle("最简单的Notification")
                //设置通知内容
                .setContentText("只有小图标、标题、内容");
        //设置通知时间,默认为系统发出通知的时间,通常不用设置
        //.setWhen(System.currentTimeMillis());
        //通过builder.build()方法生成Notification对象,并发送通知,id=1
        notifyManager.notify(1, builder.build());

效果如下:

给 Notification 设置 Action

这里,我们来实现一个点击 Notification 跳转到 MainActivity 的效果。代码如下:

        NotificationManager notifyManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

        Intent mainIntent = new Intent(this, MainActivity.class);
        PendingIntent mainPendingIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        //创建 Notification.Builder 对象
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "abc")
                .setSmallIcon(R.mipmap.ic_launcher)
                //点击通知后自动清除
                .setAutoCancel(true)
                .setContentTitle("我是带Action的Notification")
                .setContentText("点我会打开MainActivity")
                .setContentIntent(mainPendingIntent);
        //发送通知
        notifyManager.notify(3, builder.build());

相比发送最简单的通知,发送具有 Action 的通知多了创建 Intent 、 PendingIntent 和 setContentIntent() 这几步。

PendingIntent

PendingIntent 是一种特殊的 Intent ,字面意思可以解释为延迟的 Intent ,用于在某个事件结束后执行特定的 Action 。从上面带 Action 的通知也能验证这一点,当用户点击通知时,才会执行。

PendingIntent 是 Android 系统管理并持有的用于描述和获取原始数据的对象的标志(引用)。也就是说,即便创建该PendingIntent对象的进程被杀死了,这个PendingItent对象在其他进程中还是可用的。
日常使用中的短信、闹钟等都用到了 PendingIntent

PendingIntent 主要可以通过以下三种方式获取:

//获取一个用于启动 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)

PendingIntent 具有以下几种 flag:

FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的 PendingIntent 对象,那么就将先将已有的 PendingIntent 取消,然后重新生成一个 PendingIntent 对象。

FLAG_NO_CREATE:如果当前系统中不存在相同的 PendingIntent 对象,系统将不会创建该 PendingIntent 对象而是直接返回 null 。

FLAG_ONE_SHOT:该 PendingIntent 只作用一次。

FLAG_UPDATE_CURRENT:如果系统中已存在该 PendingIntent 对象,那么系统将保留该 PendingIntent 对象,但是会使用新的 Intent 来更新之前 PendingIntent 中的 Intent 对象数据,例如更新 Intent 中的 Extras 。

更新 Notification

更新通知很简单,只需要再次发送相同 ID 的通知即可,如果之前的通知还未被取消,则会直接更新该通知相关的属性;如果之前的通知已经被取消,则会重新创建一个新通知。
更新通知跟发送通知使用相同的方式。详见上节:创建 Notification。

取消 Notification

取消通知有如下 5 种方式:

  1. 点击通知栏的清除按钮,会清除所有可清除的通知
  2. 设置了 setAutoCancel() 或 FLAG_AUTO_CANCEL 的通知,点击该通知时会清除它
  3. 通过 NotificationManager 调用 cancel(int id) 方法清除指定 ID 的通知
  4. 通过 NotificationManager 调用 cancel(String tag, int id) 方法清除指定 TAG 和 ID 的通知
  5. 通过 NotificationManager 调用 cancelAll() 方法清除所有该应用之前发送的通知

如果你是通过 NotificationManager.notify(String tag, int id, Notification notify) 方法创建的通知,那么只能通过 NotificationManager.cancel(String tag, int id) 方法才能清除对应的通知,调用NotificationManager.cancel(int id) 无效。

设置 Notification 的通知效果

Notification 有震动、响铃、呼吸灯三种响铃效果,可以通过 setDefaults(int defualts) 方法来设置。 Default 属性有以下四种,一旦设置了 Default 效果,自定义的效果就会失效。

//添加默认震动效果,需要申请震动权限
//<uses-permission android:name="android.permission.VIBRATE" />
Notification.DEFAULT_VIBRATE

//添加系统默认声音效果,设置此值后,调用setSound()设置自定义声音无效
Notification.DEFAULT_SOUND

//添加默认呼吸灯效果,使用时须与 Notification.FLAG_SHOW_LIGHTS 结合使用,否则无效
Notification.DEFAULT_LIGHTS

//添加上述三种默认提醒效果
Notification.DEFAULT_ALL

除了以上几种设置 Notification 默认通知效果,还可以通过以下几种 FLAG 设置通知效果。

//提醒效果常用 Flag
//三色灯提醒,在使用三色灯提醒时候必须加该标志符
Notification.FLAG_SHOW_LIGHTS

//发起正在运行事件(活动中)
Notification.FLAG_ONGOING_EVENT

//让声音、振动无限循环,直到用户响应 (取消或者打开)
Notification.FLAG_INSISTENT

//发起Notification后,铃声和震动均只执行一次
Notification.FLAG_ONLY_ALERT_ONCE

//用户单击通知后自动消失
Notification.FLAG_AUTO_CANCEL

//只有调用NotificationManager.cancel()时才会清除
Notification.FLAG_NO_CLEAR

//表示正在运行的服务
Notification.FLAG_FOREGROUND_SERVICE

参考:
https://www.cnblogs.com/travellife/p/Android-Notification-xiang-jie.html(主要参考处)
https://gavinliu.cn/2017/08/22/Android-吃奥利奥系列-1-Notification/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值