Notification 通知

Notification是Android系统中比较有特色的一个功能。当某个应用程序希望向用户发出一些提示消息,而该应用程序又不在前台运行时就可以借助通知来实现,发出一条通知后,手机最上方的通知栏中会显示一个通知的图标。

Notification的基本用法

  1. 首先需要一个NotificationManager来对通知进行管理,可以调用Context的getSystemService()方法获取到。这个方法接受一个字符串参数用于确定获取系统的哪个服务,这里传入Context.NOTIFICATION_SERVICE即可这样就获取了一个NotificationManager的实例
  2. 然后使用一个Builder构造器来创建Notification对象,support-v4和v7中提供了一个NotificationCompat类,使用这个类来创建Notification。
Notification notification = new NotificationCompat.Builder(context).build();

这样就可以创建一个空的Notification对象。
在.build()前可以设置他的5个方法。

setContentTitle()方法用于指定通知的标题内容。
setContentText()方法用于指定通知的正文内容,
setWhen() 方法用于指定通知被创建的时间,以毫秒为单位。
setSmallIcon()方法用于设置通知的小图标。
setLargeIcon()方法用于设置通知的大图标。
  1. 以上工作都完成之后只需要调用NotificationManager的notify()方法就可以让通知显示出来了。,notify()方法接受两个参数, 第一个参数是id ,要保证每个通知所指定的id都是不同的,第二个蚕食是Notification对象,这里使用刚刚创建好的Notification对象传入即可。这样显示一个通知就可以写成。

使用通知的例子。

  1. 修改activity_main.xml的布局 添加一个按钮
<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/btn_show_notification"
        android:text="显示通知"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
  1. 修改MainActivity中的代码:
public class MainActivity extends AppCompatActivity {

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

        //必须适配安卓8.0以上系统 否则8.0以上系统不会显示通知。
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            String channelId = "chat";
            String channelName = "聊天消息";
            int importance = NotificationManager.IMPORTANCE_HIGH;

            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            NotificationManager notificationManager = (NotificationManager) getSystemService(
                    NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }

        Button showNotificationButton = (Button) findViewById(R.id.btn_show_notification);
        showNotificationButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                Notification notification = new NotificationCompat.Builder(MainActivity.this, "chat")//channelID必须和createNotificationChannel中设置的对应
                .setContentTitle("收到一条聊天消息")
                .setContentText("今天中午吃什么?")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
               // .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon))
                .setAutoCancel(true)
                .build();
                manager.notify(1, notification);

            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void createNotificationChannel(String channelId, String channelName, int importance) {
        NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
        NotificationManager notificationManager = (NotificationManager) getSystemService(
                NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(channel);
    }

}

但是这时候的通知栏消息是不能点击的,如果需要设置点击效果则需要使用PendingIntent PendingIntent的用法很简单,它主要提供了几个静态方法用于获取PendingIntent的实例可以根据需求来选择是使用getActivity()、getBroadcast()、getService() 这几个方法接受的参数都是相同的,第一个参数是Context,第二个参数一般用不到通常传入0即可, 第三个参数是一个Intent对象,我们可以通过这个对象过检出PendingIntent的意图,第四个参数用于确定PendingIntent的行为,通常情况下传入0就可以了。

我们新建一个activity 然后在build()前面插入一个setContentIntent()并向这个方法传入一个PendingIntent对象。

修改MainActivity中的代码:

showNotificationButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //构建意图
        Intent intent = new Intent(MainActivity.this,Main2Activity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,0);

        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification notification = new NotificationCompat.Builder(MainActivity.this, "chat")//channelID必须和createNotificationChannel中设置的对应
        .setContentTitle("收到一条聊天消息")
        .setContentText("今天中午吃什么?")
        .setWhen(System.currentTimeMillis())
        .setContentIntent(pendingIntent)    //插入这一条。,
        .setAutoCancel(true) // 点击后自动删除这条通知与 manager.cancel(1);效果相同
        .setSmallIcon(R.mipmap.ic_launcher)
       // .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon))
        .setAutoCancel(true)
        .build();
        manager.notify(1, notification);

    }
});

其中setAutoCancel()方法和显示的调用NotificationManager的cancel()方法取消相同。

NotificationCompat.Builder中提供了非常丰富的API来让我们创建出更加多样的通知效果。

setSound(Uri.formFile(new File("路径")))

这样就可以在通知来的时候播放这个音频

设置手机静止和震动的时长,以毫秒为单位,下标为偶数的值表示手机静止的时长, 下标为奇数 的值表示手机震动的时长,

setVibrate(new long[] {0,1000, 2000, 1000})

这样手机在通知到的时候立即震动1秒,然后静止2秒,在震动1秒
不过想要控制手机震动还需要声明权限,因此还需要在AndroidManifest文件中进行声明

设置来通知时候LED灯闪烁,这个方法接受三个参数,第一个参数是LED灯的颜色,第二个则是是用于指定LED灯亮起的时长,第三个参数用于指定暗去的时长

setLights(Color.GREEN, 1000,1000)

setStyle()方法可以允许我们构建出来丰富文本的通知内容,也就是说通知中不光可以由文字和图标, 还可以包含更多东西, setStyle()方法接受一个NotificationCompat.Style参数,这个参数就是用来构建具体的富文本信息的,如长文字,图片等等。

.setStyle(new NotificationCompat.BigTextStyle().bigText("asjdfhauisjdfhauisdfhosdafiuoasdf" +
                        "uiosahdfuioahsdiofhasidfhiasdhfiausdbfiouqwbefuioqba" +
                        "ewgoibaeuasdfasdgergwethretherthertyhjetyjrtyjrtyjrtyj" +
                        "eaerfhgsahdrfugiaoshfguaosdfehauiosdfhauiosdasudfioahsdfiou" +
                        "ahbsuidgohaesuriogwqe[oirgjniofdnvahuioaedryhgioadnjrg"))

显示图片

.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(
                            getResources(),R.drawable.ic_launcher_background)))

设置通知的重要程度
setPriority() 接受一个整形参数用于设置这个通知的重要程度一般由五个常量值可以选择
public static final int PRIORITY_DEFAULT = 0;
public static final int PRIORITY_LOW = -1;
public static final int PRIORITY_MIN = -2;
public static final int PRIORITY_HIGH = 1;
public static final int PRIORITY_MAX = 2;