zoukankan      html  css  js  c++  java
  • Notification的基本用法以及使用RemoteView实现自定义布局

    Notification的作用

    Notification是一种全局效果的通知,在系统的通知栏中显示。既然作为通知,其基本作用有:

    •   显示接收到短消息、即时信息等
    •   显示客户端的推送(广告、优惠、新闻等)
    •   显示正在进行的事物(后台运行的程序,如音乐播放进度、下载进度)

    Notification的基本操作:

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

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

    除了以上三项,其他均为可选项,不过一般而言,通知需要有交互的功能,所以一般Notification具有Action属性,这样就能跳转到App的某一个Activity、启动一个service或者发送一个Broadcast。

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

    下面就从Notification的基本操作逐条介绍:

    1. Notification的创建

    Notification的创建过程主要涉及到Notification.Builder、Notification、NotificationManager

    Notification.Builder:

             使用建造者模式构建Notification对象。由于Notification.Builder仅支持Android4.1及之后的版本,为了解决兼容性的问题,使用V4兼容库中的NotifivationCompat.Builder类。

    Notification:通知对应类,保存通知相关的数据。NotificationManager向系统发送通知时会用到。

    NotificationManager:通知管理类,调用NotificationManager的notify方法可以向系统发送通知。

    获取 NotificationManager 对象:

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

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

    1. 获取NotificationManager实例
    2. 实例化NotificationCompat.Builder并设置相关属性
    3. 通过builder.build方法来生成Notification对象,并发送通知
    复制代码
    private void sendNotification(){
    
        Intent intent = new Intent(this,SettingsActivity.class);
    
        PendingIntent mPendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
    
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
        NotificationCompat.Builder builder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
    
                //设置小图标
    
                .setSmallIcon(R.mipmap.ic_launcher)
    
                //点击后自动清除
    
                .setAutoCancel(true)
    
                //设置通知标题
    
                .setContentTitle("最简单的通知")
    
                //设置通知内容
    
                .setContentText("真的很简单很简单很简单")
    
                //设置通知的动作
    
                .setContentIntent(mPendingIntent)
    
                //设置通知时间,默认为系统发出通知的时间
    
                .setWhen(System.currentTimeMillis());
    
                //第一个参数为Notification的id
    
        notificationManager.notify(2,builder.build());
    
    }
    复制代码

    其中为了实现Action属性,我们需要创建Intent、PendingIntent和setContentIntent()这几步。

    不难发现,其中的PendingIntent的设置才是其中的关键。

    PendingIntent支持三种待定的意图:启动Activity,启动Service和发送Broadcast。对应于它的三个接口方法。

    static PendingIntent

    getActivity(Context context,int requestCode,Intent intent,int flags)

    获取一个PendingIntent,该意图发生时,相当于Context.startActivity(Intent)

    static PendingIntent

    getService (Context context,int requestCode,Intent intent,int flags)

    获取一个PendingIntent,该意图发生时,相当于Context.startService (Intent)

    static PendingIntent

    getBroadcast(Context context,int requestCode,Intent intent,int flags)

    获取一个PendingIntent,该意图发生时,相当于Context.sendBroadcast(Intent)

    其中context和intent不需要讲,主要说一下requestCode和flags。其中requestCode是PendingIntent发送发的请求码,多数情况下设置为0即可,requestCode会影响到flags的效果。

    PendingIntent相同:Intent相同且requestCode也相同。(Intent相同需要ComponentName和intent-filter相同)

    flags的常见类型有:

    FLAG_ONE_SHOT:只能被使用一次,然后就会被自动cancel,如果后续还有相同的PendingIntent。那么他们的send方法就会调用失败。
    FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统不会创建该PendingIntent对象,而是直接返回null。(很少使用)

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

    FLAG_UPDATE_CURRENT:当前描述的PendingIntent如果已经存在,那么它们会被更新,即Intent中的Extras会被替换到最新的。

    1. Notification的更新

    更新通知的操作很简单,只需要再次发送一次相同ID的通知即可,如果之前的通知还没有被取消,则会直接更新该通知相关的属性;如果之前的通知已经被取消,则会重新创建一个新的通知。

    更新通知和发送通知采用同样的方法。

    1. Notification的取消

    取消通知的方式主要有以下5种:

    1. 点击通知栏的清除按钮,会清除所有可清除的通知
    2. 设置了setAutoCancel()或者设置了flags为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) 或cancelAll()方法才能清除对应的通知,调用NotificationManager.cancel(int id) 无效。

    1. Notification的通知效果

    前面提到了Notification的通知效果,有了通知效果更能提醒用户去查看Notification。

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

    复制代码
    //添加默认震动效果,需要申请震动权限
    
    //<uses-permission android:name="android.permission.VIBRATE" />
    
    Notification.DEFAULT_VIBRATE
    
    //添加系统默认声音效果,设置此值后,调用setSound()设置自定义声音无效
    
    Notification.DEFAULT_SOUND
    
    //添加默认呼吸灯效果,使用时须与 Notification.FLAG_SHOW_LIGHTS 结合使用,否则无效
    
    Notification.DEFAULT_LIGHTS
    
    //添加上述三种默认提醒效果
    
    Notification.DEFAULT_ALL
    复制代码

    铃声:

    复制代码
    //调用系统默认响铃,设置此属性后setSound()会无效
    
    //.setDefaults(Notification.DEFAULT_SOUND)
    
    //调用系统多媒体裤内的铃声
    
    //.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"));
    
    //调用自己提供的铃声,位于 /res/values/raw 目录下
    
    .setSound(Uri.parse("android.resource://com.littlejie.notification/" + R.raw.sound))
    复制代码

    震动:

    复制代码
    long[] vibrate = new long[]{0, 500, 1000, 1500};
     
    
    //使用系统默认的震动参数,会与自定义的冲突
    
    //.setDefaults(Notification.DEFAULT_VIBRATE)
    
    //自定义震动效果
    
    .setVibrate(vibrate);
    复制代码

    呼吸灯

    //ledARGB 表示灯光颜色、 ledOnMS 亮持续时间、ledOffMS 暗的时间
    
    .setLights(0xFF0000, 3000, 3000);

    另一种方式:

    复制代码
    Notification notification = builder.build();
    
    //只有在设置了标志符Flags为Notification.FLAG_SHOW_LIGHTS的时候,才支持呼吸灯提醒。
    
    notify.flags = Notification.FLAG_SHOW_LIGHTS;
    
    //设置lights参数的另一种方式
    
    //notify.ledARGB = 0xFF0000;
    
    //notify.ledOnMS = 500;
    
    //notify.ledOffMS = 5000;
    复制代码

    还可以通过以下几种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
    复制代码

    上面讲到的Notification的布局都是系统默认的,当然有时候处于需求,我们可能需要自定义Notification的布局。

    那如何实现Notification的自定义布局呢?

    这里就需要提出一个新的知识点RemoteView,望文生义,即远程View。

    RemoteView表示的是一种View结构,它可以在其他进程中显示(具体来讲是SystemServer进程),由于它是在其他进程中显示,为了更新它的界面,我们不能简单地使用普通View的那一套方法,RemoteView提供了一系列Set方法用于更新界面。

    下面就是一个简单的示例;

    复制代码
    package com.pignet.remoteviewtest;
    
    import android.app.Notification;
    
    import android.app.NotificationManager;
    
    import android.app.PendingIntent;
    
    import android.content.Context;
    
    import android.content.Intent;
    
    import android.support.v7.app.AppCompatActivity;
    
    import android.os.Bundle;
    
    import android.view.View;
    
    import android.widget.Button;
    
    import android.widget.RemoteViews;
    
    public class MainActivity extends AppCompatActivity {
    
    
        @Override
    
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
            Button btnNotification = (Button) findViewById(R.id.btn_notification);
    
            btnNotification.setOnClickListener(new View.OnClickListener() {
    
                @Override
    
                public void onClick(View v) {
    
                    sendNotification();
    
                }
    
            });
    
        }
    
        private void sendNotification(){
    
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
            Notification notification =new Notification();
    
            notification.icon=R.mipmap.ic_launcher;
    
            notification.when=System.currentTimeMillis();
    
            notification.flags=Notification.FLAG_AUTO_CANCEL;
    
            //跳转意图
    
            Intent intent = new Intent(this,SettingsActivity.class);
    
            //建立一个RemoteView的布局,并通过RemoteView加载这个布局
    
            RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.layout_notification);
    
            //为remoteView设置图片和文本
    
            remoteViews.setTextViewText(R.id.message,"第一条通知");
    
            remoteViews.setImageViewResource(R.id.image,R.mipmap.ic_launcher_round);
    
            //设置PendingIntent
    
            PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    
            //为id为openActivity的view设置单击事件
    
            remoteViews.setOnClickPendingIntent(R.id.openActivity,pendingIntent);
    
            //将RemoteView作为Notification的布局
    
            notification.contentView =remoteViews;
    
            //将pendingIntent作为Notification的intent,这样当点击其他部分时,也能实现跳转
    
            notification.contentIntent=pendingIntent;
    
            notificationManager.notify(1,notification);
    
        }
    
    }
     
    复制代码

    有图:

  • 相关阅读:
    c#多线程
    把.NET程序部署到没有安装.NET Framwork的机器上
    Java字符编码转换过程说明
    Window 消息大全使用详解
    Regsvr32
    VC++的应用程序框架中各类之间的访问方法
    java接收中文输入并正常显示
    Visual C#中的数据绑定
    截取系统 API 调用(转)
    几个操作文件的API函数
  • 原文地址:https://www.cnblogs.com/zhangyingai/p/7087377.html
Copyright © 2011-2022 走看看