08丰富程序-使用通知

作者: 何惧l | 来源:发表于2018-03-26 19:21 被阅读27次

    当某个应用程序希望向用户发出一些提示信息的时候,而该程序又不在前台运行时,这个时候就可以使用通知来实现了,发出一条通知后,手机最上方的状态栏中就会显示一个通知的图标,下拉状态栏后就可以看到通知的详细内容了

    通知的基本用法

    1. 首先需要一个NotificationManager来对通知进行管理,可以调用Context的getSystemService()方法获取到,getSystemService()方法接收一个字符串参数用于确定获取系统的那个服务,这里我们传入Context.NOTIFICATION_SERVICE就可以了,因此获取NotificationManager的实例就可以写成
    NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
    
    1. 接下来使用一个Builder构造器来创建Notification对象,问题是android中的每个版本对这个通知的支持都会有修改,这个时候使用support库中提供的兼容API,support-v4库中提供了一个NotificationManager类,使用这个类的构造器创建出来的Notification对象,就可以保证程序在所有的android版本上正常运行,代码如下
      Notification notification = new NotificationCompat.Builder(context).build();
      当然了,这是建了一个空的Notification对象,并没有实际的作用,可以在build()方法之间连缀任意多的设置方法来创建一个丰富的Notification对象,做基本设置、
    Notification notification = new NotificationCompat.Builder(context)
        .setContentTitle("This is content title")
        .setContentText("This is content text")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.drawable.small_icon)
        .setLargeIcon(BitmapFactory.decodeResource(getREsources(),
            R.drawable.large_icon))
        .build();
    
    • setContentTitle()方法用于通知标题内容,下拉系统状态栏就可以看到内容
    • setContentText()方法用于指定通知的文本内容,同样是下拉系统状态栏就可以看到这个部分的内容
    • setWhen()方法用于指定被通知的时间,以好毫秒为单位,当下拉系统状态栏时,这里指定的时间会显示在相应的通知上
    • setSmallIcon()方法用于设置通知的小图标,注意只能使用纯alpha图层的图片进行设置,小图标会显示在系统状态栏上
    • setLargeIcon()方法用于设置通知的大图标,当下拉系统状态栏的时候,就可以看见设置的大图标
    1. 上面的都写完后,只需要调用NotificationManager的notify()方法就可以让通知显示出来了,notify()方法用于接收两个参数,第一个参数是id,要保证每个通知所指定的id都是不同的,第二个参数是Notification对象,这里直接把刚刚创建好的对象传入就可以了
      managet.norify(1,notification)
    2. 通知的操作基本就是这样,通过一个例子来试试,在acticity_main中
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    
        
        <Button
            android:id="@+id/send_notice"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Send notice"
            />
    </LinearLayout>
    
    
    1. 在MainActivity中
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button sendNotice = (Button)findViewById(R.id.send_notice);
            sendNotice.setOnClickListener(this);
    
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.send_notice:
                    NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
                    Notification notification = new NotificationCompat.Builder(this)
                            .setContentTitle("This is content title")
                            .setContentText("This is content text")
                            .setWhen(System.currentTimeMillis())
                            .setSmallIcon(R.mipmap.ic_launcher)
                            .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                            .build();
                    manager.notify(1,notification);
                    break;
                default:
                    break;
            }
        }
    }
    
    
    • 点击按钮的时候,就已将完成了通知的创建工作,和上面说的一样,这里使用的图标是默认的
    • 运行程序,点击按钮,下拉系统状态栏就可以看到该通知的详细信息了


      通知的详细按钮.png
    • 这个时候点击通知是没有任何反应的,还得继续在代码中进行响应设置,这个时候就出现了一个新的概念:PendingIntent
    1. PendingInten这个和Intent有点类似,它们都可以去指明某一个‘意图’,都可以用于启动活动、启动服务以及发送广播,不同的是Intent更加倾向于立即执行某个动作,而PendingIntent更加倾向于在某个适合的时机去执行某个行为,所以可以把PendingIntent理解为延迟的Intent
    2. PendingInten用法也很见简单,有几个静态方法用于获取PendingIntent的实例,可以根据需求来确定是使用getActivity()、getBroadcast()、getService()方法,这些方法接收的参数也是相同的,第一个参数Context,第二个参数一般传入0就可以了,第三个参数是Intent对象,根据这个对象构建出PendingInten的'意图',第四个参数用于确定PendingIntent的行为,通常传入0就可以了,这个时候再看一下NotificationCompat.Builder,`这个构造器还可以连缀一个setContentIntent()方法,这个方法接收的参数正是一个PendingIntent对象,因此,这里就可以通过PendingIntent构建出一个延迟执行的'意图',当用户点击这个通知的时候就会触发相应的逻辑了
    3. 这个时候再建一个项目NotificationActivity,修改对应的layout中的代码
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
       android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    
        <TextView
            
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:text="This is notifition layout"
            />
    
    </LinearLayout>
    
    
    1. 修改Mainactivity中的代码
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button sendNotice = (Button)findViewById(R.id.send_notice);
            sendNotice.setOnClickListener(this);
    
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.send_notice:
                    //
                    Intent intent = new Intent(this,NotificationActivity.class);
                    PendingIntent p1 = PendingIntent.getActivity(this,0,intent,0);
    
                    NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
                    Notification notification = new NotificationCompat.Builder(this)
                            .setContentTitle("This is content title")
                            .setContentText("This is content text")
                            .setWhen(System.currentTimeMillis())
                            .setSmallIcon(R.mipmap.ic_launcher)
                            .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                            // 添加这个
                            .setContentIntent(p1)
                            .build();
                    manager.notify(1,notification);
                    break;
                default:
                    break;
            }
        }
    }
    
    
    • 通过这个Intent表达出想要启动那个,然后把构建好的Intent传入到PendingIntent的getActivity()方法中,接着在NotificationCompat.Builder中调用setContentIntent()方法,把它作为参数传入就可以了
    • 重新运行程序,拉下拉框,点击通知就可以看到


      点击通知.png
    1. 这个时候发现系统状态栏上的通知图标还没消失,这个时候有两种方式解决,一种是在NotificationCompat.Builder中再连缀一个setAutoCancel()方法,另一种是显示的调用NotificitionManager的cancel()方法将它取消
      第一种写法
                    
            Notification notification = new NotificationCompat.Builder(this)
                        ...
                        .setAutoCancel(true)
                        .buiid();
    
    • 这个方法中传入true,就表示当用户点击这个通知的话,通知会自动取消掉
      第二种写法
    public class NotificationActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_notification);
            NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
            manager.cancel(1);
        }
    }
    
    • 在cancel传入了1,这个1就是之前创建通知的时候给每条通知指定的id,想要取消那个通知,传入对应的id就可以了

    通知的进阶技巧

    实际上NotificationCompat.Builder中提供了丰富的API来让我们创建更多的通知效果,说些常用的

    1. setSound()方法,它可以在通知发出的时候播放一段音频,setSound()方法接收一个Uri参数,所以在指定音频文件的时候还需要获取到音频文件对应的URI,比如在每个手机的/system/media/audio/ringtones目录下都有很多音频文件,随便选一个就可以,代码如下
    Notification notification = new NotificationCompat.Builder(this)
        ...
        .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
        .build();
    
    1. 除了音频外,还可以让手机进行振动,使用的是vibrate属性,它是一个长整形的数组,用于设置手机静止和振动的时长,以毫秒为单位,下标为0的值表示手机静止1秒,下标为1的值表示手机振动的时长,下标为2的又表示振动的时长,以此类推,如果想要让手机在通知来的时候立即振动1秒,然后静止1秒,振动1秒,代码就可以写成
    Notification notification = new NotificationCompat.Builder(this)
        ...
        .setvibrate(new long[]{0,1000,1000,1000})
        .build();
    
    • 不过控制振动的时候还要声明权限,还的编辑AndroidManifest.xml中的代码
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.md.notification">
    
        <uses-permission android:name="android.permission.VIBRATE"/>
        ...
    
    </manifest>
    
    1. 当然了,在通知来的时候还可以控制手机上的LED灯,可以使用setLights()方法来实现,这个方法接收3个参数,第一个是指定LED灯的颜色,第二个参数是指定LED灯的时长,毫秒为单位,第二个参数指定LED灯暗去的时长,所以当通知来的时候,想要实现LED绿灯一闪一闪的效果就可以
    Notification notification = new NotificationCompat.Builder(this)
        ...
        .setLights(Color.GREEN,1000,1000)
        .build();
    
    • 当然了也可以使用默认的,它会根据当前手机环境来决定播放什么铃声以及如何振动,和闪灯
    Notification notification = new NotificationCompat.Builder(this)
        ...
        .setDefaults(NotificationCompat.DEFAULT_ALL)
        .build();
    
    1. 这些功能在模拟器上是无法表现出来的,需要通真机来试试

    通知的高级功能

    NotificationCompat.Builder这个类还有更加强大的API

    1. 先看这个setStyle()方法,这个方法允许我们构建出富文本的通知内容,也就是说通知中还可以包含文字和图标,这个方法就收一个NotificationCompat.Style参数,这个参数就是用来构建具体的富文本信息的,比如长文字和图片等,首先不使用这个,
      如果设置很长的文字内容会有什么效果呢
    Notification notification = new NotificationCompat.Builder(this)
        ...
        .setContentText("This is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content text")
        ...
        .build();
    
    • 运行程序点击按钮


      文字过长.png

      可以看到,只能显示那么多文字,剩下的文字显示不出来,

    • 但是你真的想要在通知当中显示一段长文字的时候,android也是支持的,通过setStyle()
    Notification notification = new NotificationCompat.Builder(this)
        ...
        .setStyle(new NotificationCompat.BigTextStyle().bigText("This is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content textThis is content text"))
        ...
        .build();
    
    • 在setStyle()方法中创建了一个NotificationCompat.BigTextStyle()对象,这个对象是封装长文字信息的,调用bigText()方法就可以将文字传入了
    • 当然了还可以在通知中传入一张大图片,基本和上面相似
    Notification notification = new NotificationCompat.Builder(this)
        ...
        .setStyle(new NotificationCompat.BiPictureStyle().bigPicture
        (BitmapFactory.decodeResource(getResources(),R.drawable.big_image)))
        ...
        .build();
    
    • 调用的仍然是setStyle()方法,在参数中创建了NotificationCompat.BiPictureStyle()对象,这个对象就是用于设置图片的,然后嗲用bigPicture()方法并将图片传入,通过BitmapFactory.decodeResource()方法将图片解析成Bitmap对象,再传入bigPicture()方法中就可以了
    • 运行程序就可以看到
    • 通知中长文字.png
    1. setPriority()方法,它可以设置通知的重要程度,一共有5个常量可以选择
      PORTANCE_DEFAULT表示默认的程度,和不设置一样,PRIORITY_MAX表示最高的重要程度,这类通知消息必须要让用户立刻看到,PORTANCE_HIGH表示较高的程度
    Notification notification = new NotificationCompat.Builder(this)
        ...
        .setPriority(NotificationCompat.PORTANCE_MAX)
        .build();
    
    • 这是最高的了,表示是一条非常重要的通知


      重要通知.png

      这在通知栏就直接是一条横幅了,表示这条通知非常重要

    在夜神上是可以执行,但是在android8.0版本的时候,有些通知不能执行,目前正在研究,也希望大神指点一二

    相关文章

      网友评论

        本文标题:08丰富程序-使用通知

        本文链接:https://www.haomeiwen.com/subject/ncxdcftx.html