安卓 Notification-通知总结

通知的常见应用模式

A1.普通通知的发送流程

 

 

        // 获取通知服务对象NotificationManager

        NotificationManager notiManager = (NotificationManager)

                getSystemService(mContext.NOTIFICATION_SERVICE);

 

        // 创建Notification对象

        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);

        builder.setTicker("Ticker");            // 通知弹出时状态栏的提示文本

        builder.setContentInfo("Info...");  //

        builder.setContentTitle("Title")    // 通知标题

                .setContentText("Content")  // 通知内容

                .setSmallIcon(R.drawable.logo_dzone_strawberry);    // 通知小图标

        builder.setDefaults(Notification.DEFAULT_SOUND);    // 设置声音/震动等

        Notification notification = builder.build();

 

        // 设置通知的点击行为:自动取消/跳转等

        builder.setAutoCancel(true);

 

        // 通过NotificationManager发送通知

        notiManager.notify(1003, notification);

 

A2.携带意图的通知

 

 

// 与普通通知相同

        // 获取通知服务对象NotificationManager

        Intent intent = new Intent(this, ModxExam2Activity.class);

        intent.putExtra("msg", "我发送了一个通知"); // 携带内容

        //getIntent().getStringExtra("msg");

        PendingIntent pendingIntent = PendingIntent.getActivity(this,

                0,   //请求码

                intent, //意图对象

                PendingIntent.FLAG_UPDATE_CURRENT);

        builder.setContentIntent(pendingIntent);

        … // 与普通通知相同

 

A3.大视图通知

    BigPictureStyle创建大视图样式,可以通过Builder.addAction()添加确认按钮。

// 与普通通知相同

        // 获取通知服务对象NotificationManager

        NotificationCompat.BigPictureStyle bigPictureStyle = new 
                NotificationCompat.BigPictureStyle(builder);

        bigPictureStyle.setSummaryText("SummaryText");  // 大图模式显示内容,取代小图

        bigPictureStyle.setBigContentTitle("BigContentTitle");  // 大图模式标题,取代小图

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),    R.drawable.logo_dzone_strawberry);

        bigPictureStyle.bigLargeIcon(bitmap);

        bigPictureStyle.bigPicture(bitmap); // 大图bitmap

        notiManager.notify(1005, bigPictureStyle.build());

        … // 与普通通知相同

A4.进度条通知

// 与普通通知相同

        // 获取通知服务对象NotificationManager

        builder.setProgress(100, progress, false);

        … // 与普通通知相同

 

A5.自定义通知

        notiManager = (NotificationManager)

                getSystemService(mContext.NOTIFICATION_SERVICE);

 

        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);

 

        // 使用RemoteViews创建view

        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notify_layout_type1);

        remoteViews.setTextViewText(R.id.textView1, "setTextViewText");

        remoteViews.setTextColor(R.id.textView1, Color.BLUE);

        remoteViews.setImageViewResource(R.id.imageView1, R.drawable.logo_dzone_strawberry);

        builder.setContent(remoteViews);

        builder.setSmallIcon(R.drawable.logo_dzone_strawberry);

 

        notiManager.notify(1008, builder.build());

通知总结

S1.通知的更新@link

要想更新通知,需要利用 NotificationManager.notify() 的 id 参数,该 id 在应用内需要唯一。要想更新特定 id 的通知,只需要创建新的 Notification,并发出与之前所用 id 相同的 Notification。如果之前的通知仍然可见,则系统会根据新的 Notification 对象的内容更新该通知。相反,如果之前的通知已被清除,系统则会创建一个新通知。

S2.删除通知@link

    删除通知可以有多种方式:

1. 通过 NotificationCompat.Builder 设置 setAutoCancel(true),这样当用户点击通知后,通知自动删除;

2. 通过 NotificationManager.cancel(id) 方法,删除指定 id 的通知;

3. 通过 NotificationManager.cancelAll() 方法,删除该应用的所有通知;

S3.意图跳转@link

    PendingIntent可以看做是对Intent的包装,通过名称可以看出PendingIntent用于处理即将发生的意图,而Intent用来用来处理马上发生的意图。而对于通知来说,它是一系统级的全局通知,并不确定这个意图被执行的时间。当在应用外部执行PendingIntent时,因为它保存了触发应用的Context,使得外部应用可以如在当前应用中一样,执行PendingIntent里的Intent,就算执行的时候响应通知的应用已经被销毁了,也可以通过存在PendingIntent里的Context照常执行它,并且还可以处理Intent说带来的额外信息。

    PendingIntent提供了多个静态的getXxx()方法,用于获得适用于不同场景的PendingIntent对象。一般需要传递的几个参数都很常规,只介绍一个flag参数,用于标识PendingIntent的构造选择:

FLAG_CANCEL_CURRENT:如果构建的PendingIntent已经存在,则取消前一个,重新构建一个。

FLAG_NO_CREATE:如果前一个PendingIntent已经不存在了,将不再构建它。

FLAG_ONE_SHOT:表明这里构建的PendingIntent只能使用一次。

FLAG_UPDATE_CURRENT:如果构建的PendingIntent已经存在,则替换它,常用。

 

扩展内容

E1.浮动通知

E2.锁屏上展示

E3.闪光灯设置/自定义声音

E4.设置时间

 

实用方案

P1.自定义通知

参考:

    Android自定义Notification并没有那么简单

 

参考:

    官方API

    Notifications google

    Android 通知栏Notification的整合 全面学习 详细(E4)(CSDN)

    Android 开发之 Notification 详解 全面(E1/E2)

    Android--通知之Notification 全面(承香墨影)

    全面了解Android Notification 全()简书

    大视图

    Android官方开发文档Training系列课程中文版:通知用户之大视图通知

 demo代码

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.button1:
                notifyNormalType1();
                break;
            case R.id.button2:
                notifyWithIntentType2();
                break;
            case R.id.button3:
                notifyBigPicType3();
                break;
            case R.id.button4:
                newThreadProgress();
                break;
            case R.id.button5:
                notifyCustomType5();
                break;
        }
    }
View Code
    NotificationManager notiManager;

    /**
     * 发送普通通知
     * SS1.创建Builder对象(NotificationCompat.Builder)
     * SS2.添加通知设置内容
     * SS3.创建通知对象通过Builder.build()构造返回
     * SS4.获取通知管理器
     * SS5.发出通知(通知ID,通知对象)
     */
    private void notifyNormalType1() {
        // 获取通知服务对象NotificationManager
        notiManager = (NotificationManager)
                getSystemService(mContext.NOTIFICATION_SERVICE);

        // 创建Notification对象
        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
        builder.setTicker("Ticker");            // 通知弹出时状态栏的提示文本
        builder.setContentInfo("Info...");  //
        builder.setContentTitle("Title")    // 通知标题
                .setContentText("Content")  // 通知内容
                .setSmallIcon(R.drawable.logo_dzone_strawberry);    // 通知小图标
        builder.setDefaults(Notification.DEFAULT_SOUND);    // 设置声音/震动等
//        builder.setDefaults(Notification.DEFAULT_ALL);    // 设置声音+震动
        Notification notification = builder.build();

        // 设置通知的点击行为:自动取消/跳转等
        builder.setAutoCancel(true);    // 单独设置未跳转?

        // 通过NotificationManager发送通知
        notiManager.notify(1003, notification);
    }

    /**
     * 发送携带意图的通知
     * SS1.创建Builder对象(NotificationCompat.Builder)
     * SS2.添加通知设置内容
     * SS+.在Builder中加入一个意图过滤器builder.setContentIntent(PendingIntent)
     * 给PendingIntent的Intent参数添加跳转的目标Activity
     * SS3.创建通知对象通过Builder.build()构造返回
     * SS4.获取通知管理器
     * SS5.发出通知(请求码,通知对象)
     */
    private void notifyWithIntentType2() {
        notiManager = (NotificationManager)
                getSystemService(ModxExam1Activity.NOTIFICATION_SERVICE);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
        builder.setTicker("弹出时提示...");
        builder.setContentInfo("内容:带意图的通知");
        builder.setContentTitle("通知标题")
                .setContentText("通知下面的文本")
                .setSmallIcon(R.drawable.logo_dzone_strawberry);
        builder.setDefaults(Notification.DEFAULT_SOUND);

        Intent intent = new Intent(this, ModxExam2Activity.class);
        intent.putExtra("msg", "我发送了一个通知");
        //getIntent().getStringExtra("msg");
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0,   //请求码
                intent, //意图对象
                PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(true);    //点击自动取消通知
        Notification notification = builder.build();

        notiManager.notify(1003, notification);
    }

    /**
     * 发送大视图通知
     * SS1.创建Builder对象(NotificationCompat.Builder)
     * SS2.添加通知设置内容
     * SS+.创建BigPictureStyle传入builder,并设置BigPictureStyle属性
     * SS3.创建通知对象通过BigPictureStyle.build()构造返回
     * SS4.获取通知管理器
     * SS5.发出通知(请求码,通知对象)
     * mark
     * 大视图通知的特点:
     * 1.必须设置setSmallIcon,设置小图标,已收到通知小图标会在状态栏显示,
     *    用户下拉获得通知的时候,小图会显示在大图标的右下角
     * 2.大图通知的标题内容设置会覆盖原来的小图通知的设置
     * 3.bigPicture方法设置的图片会在一个比较大的视图中显示
     * 兼容性问题?honor6plus 6.0
     */
    private void notifyBigPicType3() {
        notiManager = (NotificationManager)
                getSystemService(ModxExam1Activity.NOTIFICATION_SERVICE);

        Intent intent = new Intent(this, ModxExam2Activity.class);
        intent.putExtra("msg", "我发送了一个通知");
        //getIntent().getStringExtra("msg");
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0,   //请求码
                intent, //意图对象
                PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
        builder.setTicker("Ticker");
        builder.setContentInfo("Info");
        builder.setContentTitle("Title")
                .setContentText("Content")
                .setSmallIcon(R.drawable.logo_dzone_strawberry);
        builder.setDefaults(Notification.DEFAULT_SOUND);
        /**
         * 在大视图通知中设置一个按钮
         *  点击无法取消?
         *  http://blog.csdn.net/sahadev_/article/details/51714799
         */
        builder.setStyle(new NotificationCompat.BigTextStyle()
                .bigText("msg..."))
                .addAction (R.drawable.logo_dzone_strawberry,
                        "123", pendingIntent)
                .addAction (R.drawable.logo_dzone_strawberry,
                        "456", pendingIntent);
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(true);

        NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(builder);
        bigPictureStyle.setSummaryText("SummaryText");  // 大图模式显示内容,取代小图
        bigPictureStyle.setBigContentTitle("BigContentTitle");  // 大图模式标题,取代小图
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo_dzone_strawberry);
        bigPictureStyle.bigLargeIcon(bitmap);
        bigPictureStyle.bigPicture(bitmap); // 大图bitmap

        notiManager.notify(1005, bigPictureStyle.build());
    }

    /**
     * 进度通知处理
     * SS1.
     */
    private int i;
    private final int CODE_START = 1001;    // 开始
    private final int CODE_RUN = 1002;      // 下载中
    private final int CODE_END = 1003;      // 下载完成
    private final int NOF_MSG_CODE = 10086;      // notification code
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case CODE_START:
                    notifyProgressType4(0, CODE_START);
                    break;
                case CODE_RUN:
                    notifyProgressType4(msg.arg1, CODE_RUN);
                    break;
                case CODE_END:
                    notifyProgressType4(0, CODE_END);
                    break;
            }
        }
    };

    NotificationCompat.Builder builder;

    /**
     * 发送进度通知
     * @param progress 进度
     * @param code  识别码
     */
    private void notifyProgressType4(int progress, int code) {
        notiManager = (NotificationManager)
                getSystemService(mContext.NOTIFICATION_SERVICE);

        if (builder == null) {
            builder = new NotificationCompat.Builder(mContext);
            builder.setTicker("Ticker");
            builder.setContentInfo("info");
            builder.setContentTitle("变形金刚2.avi")
                    .setContentText("default content...")
                    .setSmallIcon(R.drawable.logo_dzone_strawberry);    //必须设置
        }

        if (code == CODE_RUN) {
            // 参数三设置为true/false 是否允许使用不确定模式,在不确定模式下,进度条动画无限循环
            builder.setProgress(100, progress, false);
            builder.setContentText("loading...");
        } else if (code == CODE_START) {
            builder.setContentText("ready to download");
        } else if (code == CODE_END) {
            builder.setProgress(0, 0, false);
            builder.setContentText("download finished,would you open it?");
            Intent intent = new Intent(this, ModxExam2Activity.class);
            intent.putExtra("msg", "我发送了一个通知");
            //getIntent().getStringExtra("msg");
            PendingIntent pendingIntent = PendingIntent.getActivity(this,
                    0,   // 请求码
                    intent, //意图对象
                    PendingIntent.FLAG_UPDATE_CURRENT);
            builder.setContentIntent(pendingIntent);
            builder.setDefaults(Notification.DEFAULT_SOUND);
            builder.setAutoCancel(true);
        }
        Notification notification = builder.build();

        notiManager.notify(NOF_MSG_CODE, notification);
    }

    Message message;
    NotificationManager notifyManager;

    /**
     * 模拟下载线程
     */
    private void newThreadProgress() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    notifyManager = (NotificationManager) getSystemService(mContext.NOTIFICATION_SERVICE);
                    message = new Message();    // 每次都要NEW一个message???
                    message.what = CODE_START;  // 开始
                    handler.sendMessage(message);
                    for (i = 0; i <= 100; i++) {
                        Thread.sleep(200);
//                        SystemClock.sleep(200);
                        LogUtil.infoE("" + i);
                        notifyManager.cancel(NOF_MSG_CODE);
                        message = new Message();
                        message.what = CODE_RUN;    // 正在运行
                        message.arg1 = i;
                        handler.sendMessage(message);
                    }
                    notifyManager.cancel(CODE_RUN);
                    message = new Message();
                    message.what = CODE_END;    // 结束了
                    handler.sendMessage(message);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 自定义通知
     *  必须设置setSmallIcon
     */
    private void notifyCustomType5() {
        notiManager = (NotificationManager)
                getSystemService(mContext.NOTIFICATION_SERVICE);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);

        // 使用RemoteViews创建view
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notify_layout_type1);
        remoteViews.setTextViewText(R.id.textView1, "setTextViewText");
        remoteViews.setTextColor(R.id.textView1, Color.BLUE);
        remoteViews.setImageViewResource(R.id.imageView1, R.drawable.logo_dzone_strawberry);
        builder.setContent(remoteViews);
        builder.setSmallIcon(R.drawable.logo_dzone_strawberry);

        notiManager.notify(1008, builder.build());
        ToastUtil.showS(this, "Type5");
    }
View Code

    

posted @ 2017-03-23 01:39  zhen-Android  阅读(5799)  评论(0编辑  收藏  举报