Android基础Android开发Android开发

Android Nofication详解(包括8.0适配)

2019-08-04  本文已影响11人  Android_董

通知栏的作用

通知栏的主要目的就是将一些重要的信息即使告诉用户,通知栏的设计非常巧妙,不用占用空间,只是在通知栏显示,当用户下拉就可以看到了,如果用户设置了通知的程度为最高的话,当受到消息会在当前界面显示内容(时间为2秒),之后就会隐藏到通知栏中。

为什么要是适配通知栏?

用于现在手机技术的发展,通知栏已经不再是我们以前见到的通知栏了,各个App为了抢占通知栏的空间,想要将自己的产品推荐给用户,将各种推送消息推送给用户,一段时间不看的话,用户的通知栏就会特别臃肿,已经全部都是各个App推送的消息了。

用户如何自己关闭/开启推送开关?

设置—>应用—>找到这个应用之后,里面有个通知,可以看到各种推送的消息,将自己需要的推送打开就可以了,一些垃圾信息,可以通过关闭来进行拦截。

通知栏适配

这里主要的分水岭是8.0(targetSdkVersion=26),在8.0以下的话我们可以在应用中找到显示通知,来进行关闭,这样的话所有的推送我们都收不到(包括一些重要的信息),所以8.0之后google新增了通知渠道,就是每条通知都要属于一个对应的渠道。每个App都可以自由地创建当前App拥有哪些通知渠道,但是这些通知渠道的控制权都是掌握在用户手上的。用户可以自由地选择这些通知渠道的重要程度,是否响铃、是否振动、或者是否要关闭这个渠道的通知。拥有了这些控制权之后,用户就再也不用害怕那些垃圾推送消息的打扰了,因为用户可以自主地选择自己关心哪些通知、不关心哪些通知。

对于每个App来说,通知渠道的划分是非常需要仔细考究的,因为通知渠道一旦创建之后就不能再修改了,因此开发者需要仔细分析自己的App一共有哪些类型的通知,然后再去创建相应的通知渠道。这里我们来参考一下ProjectDemo(自己的demo)的通知渠道划分:

8.0以上通知栏(1).jpg 8.0以上通知栏(2).jpg 8.0以下通知栏(1).png

这里可以明显看出来8.0以上通知渠道区分的很明确,用户可以根据自己的喜好,将需要的通知打开就可以了

这里先来说下8.0以前的Notification的写法

//1、通过获取NotificationManager实例来进行对通知进行管理
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//2、由于Android每个版本都对APi有不同的修改,为了兼容所有版本的API 采用v4包下边的NotificationCompat来创建Notification对象
NotificationCompat.Builder notification= new NotificationCompat.Builder(this);
//2、通过PendingIntent方法来进行点击通知进行的操作
/**
* Context context, int requestCode,@NonNull Intent intent, @Flags int flags, @Nullable Bundle options
* 上下文,1,inttent对象,flag,bundle
*/
Intent intent = new Intent(this, ServiceActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_ONE_SHOT);
//4、设置一些属性
                 notification
                .setContentTitle(title)//设置标题
                //设置style如果文字内容过多显示省略号之后可以用样式来显示全
                //.setStyle(new NotificationCompat.BigTextStyle().bigText(""))
                .setContentText(content)//设置内容
                .setWhen(System.currentTimeMillis())//被创建的时间,毫秒为单位
                .setSmallIcon(R.mipmap.ic_launcher) //设置小图标
                 //这里通过style来设置大图
//                .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))).setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))//设置大图标
                .setAutoCancel(true) //是否自动消失,true表示响应点击之后自动消失。
//                .setSound(Uri.fromFile(new File("")))//这里用来传入音频文件的url
                .setVibrate(new long[]{0, 1000, 1000, 1000})//设置震动,注意这里需要在AndroidManifest.xml中设置 
                //<!-- 声明手机震动权限 -->
               //   <uses-permission android:name="android.permission.VIBRATE" />
                .setLights(Color.BLUE, 1000, 1000)//设置LED闪烁
//                .setDefaults(NotificationCompat.DEFAULT_ALL)//根据手机环境播放铃声
//设置通知的重要程度
                /**
                 * NotificationCompat.PRIORITY_MIN 最低程度
                 * NotificationCompat.PRIORITY_LOW 较低程度
                 * NotificationCompat.PRIORITY_DEFAULT 默认程度相当于不设置
                 * NotificationCompat.PRIORITY_HIGH 较高程度
                 * NotificationCompat.PRIORITY_MAX 最高程度
                 */
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setContentIntent(pendingIntent)//点击通知进行操作
                .build();
//5、最后通过manager.notify将通知发送出去
manager.notify(1, notification);

8.0适配(不适配会怎样呢)

如果不进行适配的话,如果你的应用在8.0或者更高的版本上通知是接受不到了,google这次也算很强硬的,已经做出一些对应的策略。
开发者进行8.0(O)进行通知栏的适配 如果你的targetSdkVersion>=26 那么恭喜你的 你需要进行8.0通知栏适配,不然用户是收不到你的通知信息。
8.0通知栏适配效果:用户可以根据自己想要收到的通知,在设置里面找到应用来进行通知的关闭和打开
注意:这里必须区分8.0以后和8.0之前的区别 不然在低版本的手机上会出现崩溃的现象

/**
*  这里需要创建一个通知渠道其中必须包括
*  渠道id  这个可以随便定义,但是要保证全局的唯一性
*  渠道名称 这个是最直接最接近可以的 用来让用户知道渠道的用途
*  重要等级
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            channelId = "chat";
            channelName = "聊天信息";

            int importanceHigh = NotificationManager.IMPORTANCE_HIGH;
            createNotificationChannel(channelId, channelName, importanceHigh);
            channelId = "subscribe";
            channelName = "订阅消息";
            importanceHigh = NotificationManager.IMPORTANCE_DEFAULT;
            createNotificationChannel(channelId, channelName, importanceHigh);

        }

@TargetApi(Build.VERSION_CODES.O)
    private Notification getChannelNotification(String title, String content, String channelId) {
        Notification.Builder builder = new Notification.Builder(this, channelId);
        return builder
                .setContentTitle(title)
                .setContentText(content)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                .setAutoCancel(true)
                .setVibrate(new long[]{1000, 500, 2000})
                .setLights(Color.BLUE, 2000, 1000)
                .build();

    }

 NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            Notification notification = getChannelNotification("收到一条聊天信息", "这是聊天内容", "chat");
            manager.notify(1, notification);
}

下面是自己的demo(可以直接复制)

这里将8.0上下综合到一起,大家可以稍作改动封装运用到自己的项目中

1、布局

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.dongbo.demo.projectdemo.ui.NoficationActivity">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="sendChatMsg"
            android:text="发送聊天消息" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="sendSubscribeMsg"
            android:text="发送订阅消息" />
    </LinearLayout>
</layout>

2、Activity代码

package com.dongbo.demo.projectdemo.ui;

import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.databinding.DataBindingUtil;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.dongbo.demo.projectdemo.R;
import com.dongbo.demo.projectdemo.databinding.ActivityNoficationBinding;

public class NoficationActivity extends AppCompatActivity {
    ActivityNoficationBinding binding;
    private String channelId = "";
    private String channelName = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_nofication);
        iniView();
    }

    private void iniView() {
        //判断当前版本是不是>=8.0
        /**
         * 由于现在所有的app应用都希望通过推送消息来进行自己app的宣传造成用户的通知栏非常的臃肿,有时候一晚上不看手机,第二天通知栏已经爆满了
         * google已经根据这种情况做出了相应的对策
         * 开发者进行8.0(O)进行通知栏的适配 如果你的targetSdkVersion>=26  那么恭喜你的  你需要进行8.0通知栏适配,不然用户是收不到你的通知信息
         * 8.0通知栏适配效果:用户可以根据自己想要收到的通知,在设置里面找到应用来进行通知的关闭和打开
         * 注意:这里必须区分8.0以后和8.0之前的区别  不然在低版本的手机上会出现崩溃的现象
         *  这里需要创建一个通知渠道其中必须包括
         *  渠道id  这个可以随便定义,但是要保证全局的唯一性
         *  渠道名称 这个是最直接最接近可以的 用来让用户知道渠道的用途
         *  重要等级
         */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            channelId = "chat";
            channelName = "聊天信息";

            int importanceHigh = NotificationManager.IMPORTANCE_HIGH;
            createNotificationChannel(channelId, channelName, importanceHigh);
            channelId = "subscribe";
            channelName = "订阅消息";
            importanceHigh = NotificationManager.IMPORTANCE_DEFAULT;
            createNotificationChannel(channelId, channelName, importanceHigh);

        }
    }

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

    private Notification getNotification_25(String title, String content) {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        return builder.setContentTitle(title)
                .setContentText(content)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                .setAutoCancel(true)
                .build();
    }

    @TargetApi(Build.VERSION_CODES.O)
    private Notification getChannelNotification(String title, String content, String channelId) {
        Notification.Builder builder = new Notification.Builder(this, channelId);
        return builder
                .setContentTitle(title)
                .setContentText(content)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setNumber(10)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                .setAutoCancel(true)
                .setVibrate(new long[]{1000, 500, 2000})
                .setLights(Color.BLUE, 2000, 1000)
                .build();

    }

    public void sendChatMsg(View view) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            Notification notification = getChannelNotification("收到一条聊天信息", "这是聊天内容", "chat");
            manager.notify(1, notification);
        } else {
            Notification notification_25 = getNotification_25("收到一条聊天信息", "这是聊天内容");
            manager.notify(1, notification_25);
        }

    }

    public void sendSubscribeMsg(View view) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            Notification notification = getChannelNotification("收到一条订阅消息", "这是订阅内容", "subscribe");
            manager.notify(2, notification);
        } else {
            Notification notification_25 = getNotification_25("收到一条订阅消息", "这是订阅内容");
            manager.notify(2, notification_25);
        }

    }
}

微信图片_20190804155450.jpg 微信图片_20190804154818.jpg

我demo中用的DataBinding如果大家想要运行可以将
DataBindingUtil.setContentView(this, R.layout.activity_nofication);
改成setContentView(R.layout.activity_nofication);然后将布局中最外面的<layout></layout>删掉就可以
或者在build中添加
dataBinding { enabled = true}就可以了
大家可以自己创建个应用去试验一下Notification效果

注意

8.0一下创建Notification对象是这样的
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
8.0以上是这样的
Notification.Builder builder = new Notification.Builder(this, channelId);
这里主要就是多了一个渠道号的参数

参考链接

郭霖老师的链接:
https://blog.csdn.net/guolin_blog/article/details/79854070

上一篇下一篇

猜你喜欢

热点阅读