Android通告Notification全面解析

原创
小哥 3年前 (2022-11-14) 阅读数 112 #大杂烩

Notification使用的一般步骤:

1、 获取状态通知栏管理
2、 实例化通知栏构造函数
3、 设置NotificationCompat.Builder
4、 设置PendingIntent
5、 显示

因为Android快速发展的Android版本的快速升级也导致了一些兼容性问题。对于Notification而言,Android3.0是一个分水岭,在此之前Notification推荐使用NotificationCompate.Builder,是一个Android中时兼容性包的向下版本。Android3.0之后,通常建议使用Notification.Builder建筑本博客关注Android4.x开发,所以在这里使用。Notification.Builder进行解释和演示。

尽管通知中提供了各种属性设置,但必须设置通知对象的几个属性,其他属性是可选的。必须设置的属性如下:
1),小图标,使用setSamllIcon()方法设置。
2),标题,使用setContentTitle()方法设置。
3),文本内容,使用setContentText()方法设置。

Notification简介

Notification有两种视觉样式,一种是标准视图(Normal View),一个是大视图(Big view). 标准视图Android版本很常见,但对于大型视图Android4.1+的版本。
Notification.flags属性参数:(可以设置多个):
从官方文件中可以看出,标准视图显示器的尺寸仍然保持不变64dp高的如下图所示:

1、 通知标题
2、 大图标
3、 通知内容
4、 通知消息
5、 小图标
6、 也可以使用通知时间,通常为系统时间setWhen()设置。

对于大视图(Big View),只能显示其详细信息区域。256dp高含量,仅在Android4.1+它仅由以后的设备支持。它与标准视图不同,需要使用。setStyle()方法设置,其近似效果如下:

Android我们提供了三个实现类来显示不同的场景。是:
Notification.BigPictureStyle, 在详细信息部分显示一个。256dp高度位图。
Notification.BigTextStyle,在详细信息部分显示一个。大的文本块。
Notification.InboxStyle,在详细信息部分显示一行文本。

Notification.FLAG_SHOW_LIGHTS //三色灯提醒,使用三色灯提示时必须添加此符号
Notification.FLAG_ONGOING_EVENT //启动运行事件(活动)
Notification.FLAG_INSISTENT //让声音和振动无限循环,直到用户做出响应。 (取消或打开)
Notification.FLAG_ONLY_ALERT_ONCE //发起Notification之后,钟声和振动只执行一次。
Notification.FLAG_AUTO_CANCEL //用户单击通知并自动消失。
Notification.FLAG_NO_CLEAR //只有当全部清除时,Notification才会清除 ,不清楚通知(QQ通知无法清除。这是用过的。百度股份有限公司通知栏中也有这个搜索框。)。
用法:设置属性后,将其设置
Notification notification = builder.build();
notification.flags = Notification.FLAG_ONLY_ALERT_ONCE;

PendingIntent简介

对于通知,它显示的消息数量有限,通常仅用于提示一些摘要信息。然而,一般的短信无法表达所有需要告知用户的内容,因此需要绑定意图。当用户单击通知时,会调用一个意图来显示Activity用于显示详细内容。和Notification在中,不要使用常规Intent传递意图,但使用PendingIntent。
先来说说Intent和PendingIntent的区别,PendingIntent可以看作是一种权利。Intent包装PendingIntent用于处理迫在眉睫的意图Intent用于处理立即发生的意图。对于通知,它是一个系统级全局通知,不确定何时执行此意图。在应用程序外部执行时PendingIntent因为它保存了触发器应用程序。Context,使得外部应用可以像当前应用一样执行。PendingIntent里的Intent,即使响应通知的应用程序在执行时已被销毁,它仍然可以存在PendingIntent里的Context照常执行,也可以处理Intent据说会带来更多信息。
PendingInteng.getBroadcast(contex, requestCode, intent, flags)
PendingInteng.getService(contex, requestCode, intent, flags)
PendingInteng.getActivity(contex, requestCode, intent, flags)
PendingInteng.getActivities(contex, requestCode, intent, flags)
其中flags属性参数:
FLAG_ONE_SHOT 表示返回PendingIntent它只能执行一次,执行后将自动消失。
FLAG_NO_CREATE 指示如果描述PendingIntent不存在且不创建相应的PendingIntent,但返回NULL
FLAG_CANCEL_CURRENT 表示对应的PendingIntent已存在,请取消前者并创建新的PendingIntent
FLAG_UPDATE_CURRENT 表示更新的PendingIntent,如果生成PendingIntent如果它已经存在,请将其替换为常用的。

使用RemoteViews自定义Notification

需要使用RemoteViews.RemoteViews描述可以在其他进程中显示的视图层次结构的结构。RemoteViews提供了几种常用的构造函数。RemoteViews(String packageName,int layoutId). 第一个参数是包的名称,第二个参数是。layout资源的Id。当RemoteViews对象,您可以使用其系列setXxx()通过控件的方法Id设置控件的属性。上次使用NotificationCompat.Builder.setContent(RemoteViews)方法将其设置为1。Notification中。
remoteViews.setOnClickPendingIntent(viewId, pendingIntent);可以输入不同的Activity。如:
remoteViews.setOnClickPendingIntent(R.id.titleTV, PendingIntent.getActivity(context, 0,
new Intent(context, ScrollingActivity.class), PendingIntent.FLAG_UPDATE_CURRENT));

更新和删除通知

在使用NotificationManager.notify()发送通知时,需要传递标识符以唯一标识通知。对于某些情况,添加新通知并非没有限制。有时需要更新原始通知的信息。此时,可以重写构建。Notification,并使用与前一通知相同的标识符发送通知,这一次旧通知被新通知替换,这具有更新通知的效果。
对于通知,当它显示在状态栏中但使用后如何取消它?Android为我们提供两种删除通知的方法,一种是Notification自我维护、使用setAutoCancel()方法设置是否维护,传递boolean数据类型。另一种使用方法NotificationManager要维护的通知管理器对象,它已完成。notify()发送通知时,指定的通知标识Id要操纵通知,可以使用cancel(int)要删除指定的通知,还可以使用cancelAll()删除所有通知。
使用NotificationManager删除指定通知的示例:

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(0);

设置提示响应

对于某些通知,需要调用某些设备的资源,以便用户更快地找到新通知。通常,可以设置的响应是:铃声、闪光和振动。对于这三个属性,NotificationCompat.Builder提供了三种方法设置:
setSound(Uri sound):设置在通知时响应的铃声。传递aUri参数,格式为“file:///mnt/sdcard/Xxx.mp3”。
setLights(int argb, int onMs, int offMs):设置前部LED灯的闪烁速率、毫秒数和暂停毫秒数。
setVibrate(long[] pattern):将振动模式设置为1。long阵列保持毫秒间隔的振动。
大多数时候,我们不需要设置特定的响应效果,我们只需要遵循用户设备上的系统通知的效果,这样我们就可以使用它了。setDefaults(int)方法在中设置默认响应参数。Notification在中,常量用于定义其参数,我们只需要使用:
DEFAULT_ALL:铃声、闪光和振动都是系统默认值。
DEFAULT_SOUND:系统默认铃声。
DEFAULT_VIBRATE:系统默认振动。
DEFAULT_LIGHTS:系统默认闪烁。
设置振动需要许可:android.permission.VIBRATE
设置闪光灯需要权限:android.permission.FLASHLIGHT

附录

下面是我封装的通知工具类:

package com.test.testandroid;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.widget.RemoteViews;

/**
 * Created by Administrator on 2016-6-19.
 * notification builder android
 */
public class NotificationUtil {
    private Context context;
    private NotificationManager notificationManager;
    public NotificationUtil(Context context) {
        this.context = context;
        notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    /**
     * 普通的Notification
     */
    public void postNotification() {
        Notification.Builder builder = new Notification.Builder(context);
        Intent intent = new Intent(context, MainActivity.class);  //您需要跳转到指定的页面
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pendingIntent);
        builder.setSmallIcon(R.mipmap.ic_launcher);// 设置图标
        builder.setContentTitle("标题");// 设置通知的标题
        builder.setContentText("内容");// 设置通知的内容
        builder.setWhen(System.currentTimeMillis());// 设置通知到达的时间。
        builder.setAutoCancel(true); //自我维护通知的消失
        builder.setTicker("new message");// 第一个提示消失并显示在通知栏上。
        builder.setOngoing(true);
        builder.setNumber(20);

        Notification notification = builder.build();
        notification.flags = Notification.FLAG_NO_CLEAR;  //只有当全部清除时,Notification才会清除
        notificationManager.notify(0,notification);
    }

    /**
     * 使用下载的Notification,在4.0可稍后使用

* Notification.Builder类提供了setProgress(int max,int progress,boolean indeterminate)方法用于设置进度条, * max用于设置进度的最大数量,progress用于设置当前进度,indeterminate用于设置进度条是否决定进度。 * 通过indeterminate设置,可以实现两种不同风格的进度条,一种是进度标(true),一种是循环流(false)。 */ public void postDownloadNotification() { final Notification.Builder builder = new Notification.Builder(context); builder.setSmallIcon(R.mipmap.ic_launcher) .setTicker("showProgressBar").setContentInfo("contentInfo") .setOngoing(true).setContentTitle("ContentTitle") .setContentText("ContentText"); // 模拟下载过程 new Thread(new Runnable() { @Override public void run() { int progress ; for (progress = 0; progress < 100; progress += 5) { // 将setProgress的第三个参数已设置true可以显示为进度条样式,没有明确的进度 builder.setProgress(100, progress, false); notificationManager.notify(0, builder.build()); try { Thread.sleep(1 * 1000); } catch (InterruptedException e) { System.out.println("sleep failure"); } } builder.setContentTitle("Download complete") .setProgress(0, 0, false).setOngoing(false); notificationManager.notify(0, builder.build()); } }).start(); } /** * 中的大视图通知4.1可稍后使用,BigTextStyle

* ****************************************************

* Helper class for generating large-format notifications that include a lot of text. * * Heres how youd set the BigTextStyle on a notification: *
     * Notification notif = new Notification.Builder(mContext)
     *     .setContentTitle("New mail from " + sender.toString())
     *     .setContentText(subject)
     *     .setSmallIcon(R.drawable.new_mail)
     *     .setLargeIcon(aBitmap)
     *     .setStyle(new Notification.BigTextStyle()
     *         .bigText(aVeryLongString))
     *     .build();
     * 
* * @see Notification#bigContentView */ public void postBigTextNotification() { Notification.BigTextStyle textStyle = new Notification.BigTextStyle(); textStyle.setBigContentTitle("大标题") // 标题 .setSummaryText("SummaryText") .bigText("Helper class for generating large-format notifications" + " that include a lot of text; !!!!!!!!!!!" + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Notification.Builder builder2 = new Notification.Builder( context); builder2.setSmallIcon(R.mipmap.ic_launcher);// 小图标 // 大图标 builder2.setLargeIcon(BitmapFactory.decodeResource( context.getResources(), R.mipmap.ic_launcher)); //R.mipmap.close builder2.setTicker("showBigView_Text") .setContentInfo("contentInfo"); builder2.setStyle(textStyle); builder2.setAutoCancel(true); notificationManager.notify(0, builder2.build()); } /** * 中的大型布局通知4.1可稍后使用,大型布局图片 */ public void postBigPictureNotification() { Notification.BigPictureStyle bigPictureStyle = new Notification.BigPictureStyle(); bigPictureStyle.bigPicture(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher)); //R.drawable.back Notification.Builder builder = new Notification.Builder( context); builder.setSmallIcon(R.mipmap.ic_launcher);// 小图标 // 大图标 builder.setLargeIcon(BitmapFactory.decodeResource( context.getResources(), R.drawable.ic_stop)); builder.setTicker("showBigView_Picture") .setContentInfo("contentInfo"); builder.setStyle(bigPictureStyle); builder.setAutoCancel(true); notificationManager.notify(0, builder.build()); } /** * 中的大型布局通知4.1可稍后使用,InboxStyle */ public void postInboxNotification() { Notification.InboxStyle inboxStyle = new Notification.InboxStyle(); inboxStyle.setBigContentTitle("InboxStyle"); inboxStyle.setSummaryText("Test"); for(int i = 0 ; i < 10; i++){ inboxStyle.addLine("new:" + i); } Notification.Builder builder5 = new Notification.Builder( context); builder5.setSmallIcon(R.mipmap.ic_launcher);// 小图标 // 大图标 builder5.setLargeIcon(BitmapFactory.decodeResource( context.getResources(), R.drawable.ic_stop)); builder5.setTicker("showBigView_InboxStyle") .setContentInfo("contentInfo"); builder5.setStyle(inboxStyle); builder5.setAutoCancel(true); notificationManager.notify(0, builder5.build()); } /** * 自定义通知

* * 不设置notification.contentIntent = pendingIntent;报告了以下异常: * android.app.RemoteServiceException: * Bad notification posted from package com.test.testandroid: Couldnt expand RemoteViews for: StatusBarNotification( * pkg=com.test.testandroid user=UserHandle{0} id=0 tag=null score=0 key=0|com.test.testandroid|0|null|10168|0: Notification * (pri=0 contentView=com.test.testandroid/0x7f040038 vibrate=null sound=null defaults=0x0 flags=0x10 color=0xff00aeff vis=PRIVATE)) */ public void postCustomNotification() { RemoteViews contentViews = new RemoteViews(context.getPackageName(), R.layout.mynotification); contentViews.setImageViewResource(R.id.imageNotifi,R.mipmap.ic_launcher); contentViews.setTextViewText(R.id.titleTV,"自定义通知标题"); contentViews.setTextViewText(R.id.textTV,"自定义通知内容"); Intent intent = new Intent(context, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); contentViews.setOnClickPendingIntent(R.id.titleTV, pendingIntent); contentViews.setOnClickPendingIntent(R.id.textTV, PendingIntent.getActivity(context, 0, new Intent(context, ScrollingActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); Notification.Builder builder = new Notification.Builder(context); builder.setSmallIcon(R.mipmap.ic_launcher); builder.setContentTitle("custom notification"); builder.setContentText("custom test"); builder.setTicker("custom ticker"); builder.setAutoCancel(true); builder.setContent(contentViews); notificationManager.notify(0,builder.build()); } public void cancelById() { notificationManager.cancel(0); //对应NotificationManager.notify(id,notification);第一个参数 } public void cancelAllNotification() { notificationManager.cancelAll(); } }

如何使用:

NotificationUtil notiUtil = new NotificationUtil(this);
//        notiUtil .postNotification();
//        notiUtil .postDownloadNotification();
//        notiUtil .postBigTextNotification();
//        notiUtil .postBigPictureNotification();
//        notiUtil .postCustomNotification();
        notiUtil .postInboxNotification();

在哪里定制postCustomNotification()操作结果如下:

为什么布局不能居中?后来,使用了以下方法:




    

        
            .....

我想知道是否有更好的方法。

参考:
(1) Android-通知之Notification;
(2)
Android通知栏Notification整合;

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除