封装一个通知栏工具类 — NotificationHelper

前言

在Android开发过程中,我们偶尔会用到通知栏Notification来展示一个通知或消息。然后我就简单的封装了一个 NotificationHelper 工具类,用于方便调用 通知的发送,取消和一些相关的基本配置。下面就来讲讲deNotificationHelper的使用吧。

今天涉及内容:

  1. NotificationHelper 初始化
  2. NotificationHelper 创建系统通知
  3. NotificationHelper 创建自定义通知
  4. 自定义通知需要注意的问题
  5. MainActivity中调用示例
  6. 效果图和项目结构图
  7. 参考资料及NotificationHelper源码

先来波效果图
系统样式


1.gif

自定义布局样式


5.gif

一. NotificationHelper 初始化

NotificationHelper作为一个通知工具类,你可以这样初始化它:

        //创建工具类对象
        mNotificationHelper = new NotificationHelper();

在你需要使用通知相关方法的时候,你必须创建NotificationHelper对象,因为与通知相关的方法,都需要通过NotificationHelper对象来调用。

二.NotificationHelper 创建系统通知

大家都知道,一个通知的使用流程依次是以下几步:

  1. 创建NotificationManager对象
  2. 创建NotificationCompat.Builder对象
  3. 通过给builder设置参数来设置通知相关属性
  4. 通过builder获得Notification对象
  5. NotificationManager设置Notification并发送通知
  6. 使用完毕后,通过NotificationManager取消通知

在整个流程中,“创建NotificationCompat.Builder对象”并“通过给builder设置参数来设置通知相关属性”是很重要的两步。在系统样式通知的使用过程中,你可以像下面这样创建一个简洁的Builder:

        //创建builder
        NotificationCompat.Builder builder = mNotificationHelper.init(R.mipmap.ic_launcher)//初始化,设置小图标,必须调用,一般设置app的icon
                                 .createBuilder(MainActivity.this);//创建builder

这样,你只能获得一个什么都没设置的builder,但是你可以用这个builder来设置你需要的任何属性,如:

   //设置小图标
   builder .setSmallIcon(R.mipmap.ic_launcher)
           //点击后自动清除
          .setAutoCancel(true)
          //设置通知标题
         .setContentTitle("最简单的通知")
         //设置通知内容
         .setContentText("真的很简单很简单很简单")
         //设置通知的动作
         .setContentIntent(mPendingIntent)
         //设置通知时间,默认为系统发出通知的时间
         .setWhen(System.currentTimeMillis());

等等众多NotificationCompat.Builder的原始属性,这里就不作过多介绍了。
但是,由于是讲到NotificationHelper的使用,那么你也可以直接用NotificationHelper建一个基本够用的通知,如下:

        //创建builder
        NotificationCompat.Builder builder = mNotificationHelper.init(R.mipmap.ic_launcher)//初始化,设置小图标,必须调用,一般设置app的icon
                .setLargeIcon(R.mipmap.ic_launcher)//设置大图标
                .setTitle("提示")//设置标题
                .setContent("内容")//设置内容
                .setActivityIntent(null, 1, TestActivity.class)//设置点击跳转的activity
                //                .setBroadcastIntent(null,1,MyBroadcast.class)//设置点击跳转的广播类<注:一般设置静态广播类接收>
                .createBuilder(MainActivity.this);//创建builder

其中.setActivityIntent(null, 1, TestActivity.class)是你有点击需要跳转的时候才会添加进去。然后.setBroadcastIntent(null,1,MyBroadcast.class)是你涉及需要广播统一处理的时候则添加进去。一般广播处理的话,会建一个静态注册的广播,用于统一处理通知消息。

ok,接着讲 setActivityIntent(null, 1, TestActivity.class) 与 setBroadcastIntent(null,1,MyBroadcast.class) 中的第一个参数,均是 bundle,一个用于通知向activity传参,一个用于通知向广播传参。
在Activity和广播中,你可以向下面这样接收传过来的bundle:

        //创建工具类对象
        mNotificationHelper = new NotificationHelper();
        //activity中接收bundle
        Bundle actBundle=mNotificationHelper.getActivityBundle(intent);

        //broadcast中接收bundle
        Bundle broBundle=mNotificationHelper.getBroadcastBundle(intent);

创建完builder以后,你可以像下面这样发送通知:

        //发起通知
        mNotificationHelper.sendNotification(MainActivity.this,1,builder);

使用完毕后,取消通知:

        //注销通知
        mNotificationHelper.cancel(MainActivity.this,1);

三.NotificationHelper 创建自定义通知

NotificationHelper 除了可以创建系统样式通知外,也能自定义布局通知。
先贴一个自定义通知的布局test_view.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/container_layout"
    android:layout_width="match_parent"
    android:gravity="center"
    android:layout_height="300dp"
    android:background="#ffffff"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:gravity="center"
        android:text="测试test"
        android:textColor="@color/black"
        android:textSize="14sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>

关键设置仍在builder,若你需要写一个只供展示,没有点击事件的通知,你可以建一个简单的builder,像下面这样:

        //创建自定义布局的builder
        NotificationCompat.Builder customerBuilder = mNotificationHelper.init(R.mipmap.ic_launcher)//初始化,设置小图标,必须调用,一般设置app的icon
                //创建自定义布局的builder, R.layout.test_vie为自定义布局
                .createCustomBuilder(MainActivity.this, R.layout.test_view, null);

然后,就可以调用发送通知了:

        //发起通知
        mNotificationHelper.sendNotification(MainActivity.this,1,customerBuilder );

当然,你也可以建一个基本的,含点击什么的通知,那么你需要这样写你的builder:

        //创建自定义布局的builder
        NotificationCompat.Builder customerBuilder = mNotificationHelper.init(R.mipmap.ic_launcher)//初始化,设置小图标,必须调用,一般设置app的icon
                //创建自定义布局的builder, R.layout.test_vie为自定义布局
                .createCustomBuilder(MainActivity.this, R.layout.test_view, new NotificationHelper.OnRemoteViewListener() {
                    @Override
                    public RemoteViews getRemoteView(RemoteViews remoteViews) {
                        remoteViews.setTextViewText(R.id.tv,"大家好");
                        
//                        //设置整个通知栏事件
//                        remoteViews.setOnClickPendingIntent(pendingIntent);

                        //设置自定义布局中textView的点击跳转事件
                        Intent intent = new Intent(MainActivity.this, TestActivity.class);//cls填类似“TestActivity.class”格式
                        PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 1, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                        remoteViews.setOnClickPendingIntent(R.id.tv,pendingIntent);
                        return remoteViews;
                    }
                });

如果你还需要对customerBuilder做些其他基本设置,你也可以利用NotificationCompat.Builder 的api给 customerBuilder 直接设置。
ok,customerBuilder创建完后,就可以直接发通知了:

        //发起通知
        mNotificationHelper.sendNotification(MainActivity.this,1,customerBuilder);

通知使用完毕后,注销通知:

        //注销通知
        mNotificationHelper.cancel(MainActivity.this,1);

四.自定义通知需要注意的问题

自定义通知涉及到RemoteViews,RemoteViews对布局或者控件有些要求。
通知栏RemoteViews只支持以下布局和控件:

布局容器Layout:
FrameLayout, LinearLayout, RelativeLayout
 
控件Component:
AnalogClock, Button, Chronometer, ImageButton, ImageView, ProgressBar, 
TextView, ViewFlipper, ListView, GridView, StackView, AdapterViewFlipper

超出这些控件布局,运行时会报以下错误:

android.app.RemoteServiceException: Bad notification posted from package com.example.testdemo: Couldn't expand RemoteViews for: StatusBarNotification

五.MainActivity中调用示例

下面贴出NotificationHelper在MainActivity中使用范例:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private TextView mTv;
    private Button mBtn;

    private NotificationHelper mNotificationHelper;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();
        setListener();
    }

    private void initData(){
        mTv = findViewById(R.id.tv);
        mBtn = findViewById(R.id.btn);

    }

    private void setListener() {
        mBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn:

                test();

                break;
            default:
                break;
        }
    }

    private void test(){
        LogUtil.i("======kk========");
        //创建工具类对象
        mNotificationHelper = new NotificationHelper();

//        //创建builder
//        NotificationCompat.Builder builder = mNotificationHelper.init(R.mipmap.ic_launcher)//初始化,设置小图标,必须调用,一般设置app的icon
//                .setLargeIcon(R.mipmap.ic_launcher)//设置大图标
//                .setTitle("提示")//设置标题
//                .setContent("内容")//设置内容
//                .setActivityIntent(null, 1, TestActivity.class)//设置点击跳转的activity
//                //                .setBroadcastIntent(null,1,MyBroadcast.class)//设置点击跳转的广播类<注:一般设置静态广播类接收>
//                .createBuilder(MainActivity.this);//创建builder




        //创建自定义布局的builder
        NotificationCompat.Builder customerBuilder = mNotificationHelper.init(R.mipmap.ic_launcher)//初始化,设置小图标,必须调用,一般设置app的icon
                //创建自定义布局的builder, R.layout.test_vie为自定义布局
                .createCustomBuilder(MainActivity.this, R.layout.test_view, new NotificationHelper.OnRemoteViewListener() {
                    @Override
                    public RemoteViews getRemoteView(RemoteViews remoteViews) {
                        remoteViews.setTextViewText(R.id.tv,"大家好");

//                        //设置整个通知栏事件
//                        remoteViews.setOnClickPendingIntent(pendingIntent);

                        //设置自定义布局中textView的点击跳转事件
                        Intent intent = new Intent(MainActivity.this, TestActivity.class);//cls填类似“TestActivity.class”格式
                        PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 1, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                        remoteViews.setOnClickPendingIntent(R.id.tv,pendingIntent);
                        return remoteViews;
                    }
                });
        //发起通知
        mNotificationHelper.sendNotification(MainActivity.this,1,customerBuilder);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        //注销通知
        mNotificationHelper.cancel(MainActivity.this,1);
    }
}

六.效果图和项目结构图

系统样式


1.gif

自定义布局样式


5.gif

项目结构图
image.png

七.参考资料及NotificationHelper源码

还有 40% 的精彩内容
©著作权归作者所有,转载或内容合作请联系作者
支付 ¥3.00 继续阅读
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容