通知(Notification)

通知(Notification)是Android系统中一个特色功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知后,手机最上方的状态中会显示一个通知的图标,下拉状态栏可以看到详细的内容。

通知的基本用法

通知既可以在活动中创建,也可以在广播接收器中创建,也可以在服务中创建。相比于在广播接收器和服务,在活动中创建通知的场景还是比较少的,因为一般只有当程序进入后台的时候我们才需要使用通知;
创建通知的详细步骤:

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;


        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder ;
        int channelId = 1 ;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){    //Android 8.0以上适配
            NotificationChannel channel = new NotificationChannel(String.valueOf(channelId),"channel_name",
                                                              NotificationManager.IMPORTANCE_HIGH);
            manager.createNotificationChannel(channel);
            builder = new NotificationCompat.Builder(this,String.valueOf(channelId));
        }else{
            builder = new NotificationCompat.Builder(this);
        }
        builder.setContentTitle("this is content title")            //指定通知栏的标题内容
                .setContentText("this is content text")             //通知的正文内容
                .setWhen(System.currentTimeMillis())                //通知创建的时间
                .setSmallIcon(R.drawable.ic_launcher_background)    //通知显示的小图标,只能用alpha图层的图片进行设置
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background));

        Notification notification = builder.build() ;
        manager.notify(channelId,notification);

现在将这段代码在Activity中进行运行,看看效果:

package com.sl.demo;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Handler;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                createNofication();
            }
        },2000);
    }
    private void createNofication(){
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder ;
        int channelId = 1 ;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){        //Android 8.0适配
            NotificationChannel channel = new NotificationChannel(String.valueOf(channelId),
                    "channel_name",
                    NotificationManager.IMPORTANCE_HIGH);
            manager.createNotificationChannel(channel);
            builder = new NotificationCompat.Builder(this,String.valueOf(channelId));
        }else{
            builder = new NotificationCompat.Builder(this);
        }
        builder.setContentTitle("this is content title")            //指定通知栏的标题内容
                .setContentText("this is content text")             //通知的正文内容
                .setWhen(System.currentTimeMillis())                //通知创建的时间
                .setSmallIcon(R.drawable.ic_launcher_background)    //通知显示的小图标,只能用alpha图层的图片进行设置
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background));

        Notification notification = builder.build() ;
     //channelId为本条通知的id
        manager.notify(channelId,notification);
    }
}

运行效果为:
通知(Notification)_第1张图片
运行效果.png

我们在使用Android手机时,当通知栏出现通知时,基本上都可以点击的,而现在如果点击我们创建的这条通知,是没有任何效果的,而要让其有点击效果,我们就需要对代码进行设置,现在就涉及了一个新概念:PendingIntent

PendingIntent和Intent从名字上看有些类似,他们这件确实存在着不少共同点。如,它们都可以去指明某一个“意图”,都可以用于启动活动、启动服务以及发送广播等。不同的是,Intent更加倾向于去立即执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作。所以,也可以把PendingIntent理解为延迟执行的Intent;

PendingIntent的用法,它主要提供了几个静态方法用户获取PendingIntent的实例

  • getActivity(Context context,int requestCode,Intent intent,int flag):跳转到一个Activity组件
  • getBroadcast(Context context,int requestCode,Intent intent,int flag):打开一个广播组件
  • getService(Context context,int requestCode,Intent intent,int flag):打开一个服务组件

这几个方法的参数解释

  • Context就不做解释
  • 第二个参数requestCode一般用不到,通常传入0即可
  • 第三个参数是一个Intent对象,我们可以通过这个对象构建出PendingIntent的“意图”
  • 第四个参数int flag,用于确定PendingIntent的行为,有FLAG_ONE_SHOT,FLAG_NO_CREATE,FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT这4中值可选。

先看看flag的几个主要常量

  • FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个PendingIntent对象,那么先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。(测试发现,多个通知的channelId不同,PendingIntent内容相同时,只有最后发送的通知的PendingIntent有效,即点击事件有效)
  • FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent而是直接返回null。
  • FLAG_ONE_SHOT:该PendingIntent只作用一次(测试发现两个id不同但PendingIntent内容相同的通知,只要点击了其中一个,当再次点击时发现两个通知的点击事件都已经无效)
  • FLAG_UPDATE_CURRENT:①requestCode相同时:如果系统中有一个和你描述的PendingIntent对等的PendingIntent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如Intent中的Extras ; ②requestCode不同时:PendingIntent为设置的内容,不会进行改变

现在在程序中新建一个Actitvity为NotificationActivity,修改刚才的代码,创建PendingIntent并添加点击事件

        Intent intent = new Intent(this,NotificationActivity.class);
        PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
        builder...
                  .setContentIntent(pi);

现在再点击通知栏时,则程序会跳转到NotificationActivity的界面中;但是,发现点击后通知栏还是存在,并没有取消,其实取消通知栏显示有两种方法;
第一种为在NotificationCompat.Builder中再连缀一个方法,setAutoCancel(true),就是当通知栏被点击时取消该条通知,如:

  builder....
            .setAutoCancel(true);    //点击通知后,自动取消

第二种为手动取消通知,我们可以在通知对应的点击后操作的步骤中手动取消通知,如:

public class NotificationActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);
//手动调用取消通知,其中cancel(1)中的1表示想取消通知的id
        ((NotificationManager)getSystemService(NOTIFICATION_SERVICE)).cancel(1);
    }
}

通知的进阶技巧

好了,现在已经知道通知的创建、点击事件、取消通知,但是我们平常发现收到同志时会有震动、声音、Led灯闪烁,下面在看看如何进行设置;

  • setSound():设置通知接收到时播放音频,我现在用的模拟器运行,在模拟器中有该文件存在
Notification notification = new Notification.Builder(this)....
                                        .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Lyra.ogg")))
                                        .build();
  • setVibarate():设置震动,其参数为一个长整型数组,用于设置手机静止和震动的时长,以毫秒为单位。赋值规律为:静止时长、振动时长、静止时长、振动时长....,以此类推
Notification notification = new Notification.Builder(this)....
                                        .setVibrate(new long[]{0,1000,1000,1000})
                                        .build();

实现手机振动,还需要声明振动权限:

  
  • setLights():设置LED灯,第一个参数设置LED灯颜色,第二个参数亮灯时长,第三个参数暗灯时长,如
 Notification notification = new Notification.Builder(this)....
                                        .setLights(Color.GREEN,1000,1000)
                                        .build();

其实,如果不想进行这么多复杂的设置,也可以使用通知的默认效果,它会根据当前手机环境来决定播放什么铃声,以及如何振动,写法如下:

Notification notification = new Notification.Builder(this)....
                                        .setDefaults(NotificationCompat.DEFAULT_ALL)   //设置全部默认
                                        .build();


Notification notification = new Notification.Builder(this)...
                                     //设置默认声音和振动
                                 .setDefaults(NotificationCompat.DEFAULT_SOUND|NotificationCompat.DEFAULT_VIBRATE)  
                                        .build();

通知的高级功能

NotificationCompat.Builder类有很多Api是我们没有用过的,现在我们看看setStyle()方法,这个方法允许我们构建出富文本的通知内容,也就是说通知中不管可以有文字和图标,还可以包含更多的东西。

  • 在通知中显示一段长文字
Notification notification = new Notification.Builder(this)....
                                       .setStyle(new NotificationCompat.BigTextStyle().bigText("setStyle()方法,
这个方法允许我们构建出富文本的通知内容"))
                                        .build();

在模拟器测试时是直接显示为完全了,但在我的小米5显示时是没有显示完全的,只有当长按通知时才显示出来;

  • 在通知中显示一张大图片
Notification notification = new Notification.Builder(this)....
                                      .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(
                                        BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)))
                                        .build();

在测试时发现setStyle只能设置一个,如果设置多个,最后一个会覆盖之前的。

  • setPriority()方法,用于设置通知的重要程度,一共有五个值可选
  • PRIORITY_DEFAULT:表示默认的重要程度,和不设置效果是一样的
  • PRIORITY_MIN:表示最低的重要程度,系统只会在特定的场景才会显示这条通知,比如用户下拉状态栏时
  • PRIORITY_LOW:表示较低的重要程度,系统可能将这类通知缩小,或改变其显示顺序,将其排在更重要的通知之后
  • PRIORITY_HIGH:表示较高的重要程度,系统可能将这类通知放大,或改变其显示的顺序,将其排在比计较靠前的位置
  • PRIORITY_MAX:表示最高的重要程度,这类通知消息必须要让用户立即看到,甚至需要用户做出响应操作

具体写法如下:

Notification notification = new Notification.Builder(this)....
                                      .setPriority(NotificationCompat.PRIORITY_MAX)
                                        .build();

你可能感兴趣的:(通知(Notification))