Android Nofication詳解(包括8.0適配)

android.jpg

通知欄的作用

通知欄的主要目的就是將一些重要的信息即使告訴用戶,通知欄的設(shè)計(jì)非常巧妙,不用占用空間,只是在通知欄顯示,當(dāng)用戶下拉就可以看到了,如果用戶設(shè)置了通知的程度為最高的話,當(dāng)受到消息會在當(dāng)前界面顯示內(nèi)容(時(shí)間為2秒),之后就會隱藏到通知欄中。

為什么要是適配通知欄?

用于現(xiàn)在手機(jī)技術(shù)的發(fā)展,通知欄已經(jīng)不再是我們以前見到的通知欄了,各個(gè)App為了搶占通知欄的空間,想要將自己的產(chǎn)品推薦給用戶,將各種推送消息推送給用戶,一段時(shí)間不看的話,用戶的通知欄就會特別臃腫,已經(jīng)全部都是各個(gè)App推送的消息了。

用戶如何自己關(guān)閉/開啟推送開關(guān)?

設(shè)置—>應(yīng)用—>找到這個(gè)應(yīng)用之后,里面有個(gè)通知,可以看到各種推送的消息,將自己需要的推送打開就可以了,一些垃圾信息,可以通過關(guān)閉來進(jìn)行攔截。

通知欄適配

這里主要的分水嶺是8.0(targetSdkVersion=26),在8.0以下的話我們可以在應(yīng)用中找到顯示通知,來進(jìn)行關(guān)閉,這樣的話所有的推送我們都收不到(包括一些重要的信息),所以8.0之后google新增了通知渠道,就是每條通知都要屬于一個(gè)對應(yīng)的渠道。每個(gè)App都可以自由地創(chuàng)建當(dāng)前App擁有哪些通知渠道,但是這些通知渠道的控制權(quán)都是掌握在用戶手上的。用戶可以自由地選擇這些通知渠道的重要程度,是否響鈴、是否振動(dòng)、或者是否要關(guān)閉這個(gè)渠道的通知。擁有了這些控制權(quán)之后,用戶就再也不用害怕那些垃圾推送消息的打擾了,因?yàn)橛脩艨梢宰灾鞯剡x擇自己關(guān)心哪些通知、不關(guān)心哪些通知。

對于每個(gè)App來說,通知渠道的劃分是非常需要仔細(xì)考究的,因?yàn)橥ㄖ酪坏﹦?chuàng)建之后就不能再修改了,因此開發(fā)者需要仔細(xì)分析自己的App一共有哪些類型的通知,然后再去創(chuàng)建相應(yīng)的通知渠道。這里我們來參考一下ProjectDemo(自己的demo)的通知渠道劃分:

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

這里可以明顯看出來8.0以上通知渠道區(qū)分的很明確,用戶可以根據(jù)自己的喜好,將需要的通知打開就可以了

這里先來說下8.0以前的Notification的寫法

//1、通過獲取NotificationManager實(shí)例來進(jìn)行對通知進(jìn)行管理
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//2、由于Android每個(gè)版本都對APi有不同的修改,為了兼容所有版本的API 采用v4包下邊的NotificationCompat來創(chuàng)建Notification對象
NotificationCompat.Builder notification= new NotificationCompat.Builder(this);
//2、通過PendingIntent方法來進(jìn)行點(diǎn)擊通知進(jìn)行的操作
/**
* 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、設(shè)置一些屬性
                 notification
                .setContentTitle(title)//設(shè)置標(biāo)題
                //設(shè)置style如果文字內(nèi)容過多顯示省略號之后可以用樣式來顯示全
                //.setStyle(new NotificationCompat.BigTextStyle().bigText(""))
                .setContentText(content)//設(shè)置內(nèi)容
                .setWhen(System.currentTimeMillis())//被創(chuàng)建的時(shí)間,毫秒為單位
                .setSmallIcon(R.mipmap.ic_launcher) //設(shè)置小圖標(biāo)
                 //這里通過style來設(shè)置大圖
//                .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))).setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))//設(shè)置大圖標(biāo)
                .setAutoCancel(true) //是否自動(dòng)消失,true表示響應(yīng)點(diǎn)擊之后自動(dòng)消失。
//                .setSound(Uri.fromFile(new File("")))//這里用來傳入音頻文件的url
                .setVibrate(new long[]{0, 1000, 1000, 1000})//設(shè)置震動(dòng),注意這里需要在AndroidManifest.xml中設(shè)置 
                //<!-- 聲明手機(jī)震動(dòng)權(quán)限 -->
               //   <uses-permission android:name="android.permission.VIBRATE" />
                .setLights(Color.BLUE, 1000, 1000)//設(shè)置LED閃爍
//                .setDefaults(NotificationCompat.DEFAULT_ALL)//根據(jù)手機(jī)環(huán)境播放鈴聲
//設(shè)置通知的重要程度
                /**
                 * NotificationCompat.PRIORITY_MIN 最低程度
                 * NotificationCompat.PRIORITY_LOW 較低程度
                 * NotificationCompat.PRIORITY_DEFAULT 默認(rèn)程度相當(dāng)于不設(shè)置
                 * NotificationCompat.PRIORITY_HIGH 較高程度
                 * NotificationCompat.PRIORITY_MAX 最高程度
                 */
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setContentIntent(pendingIntent)//點(diǎn)擊通知進(jìn)行操作
                .build();
//5、最后通過manager.notify將通知發(fā)送出去
manager.notify(1, notification);

8.0適配(不適配會怎樣呢)

如果不進(jìn)行適配的話,如果你的應(yīng)用在8.0或者更高的版本上通知是接受不到了,google這次也算很強(qiáng)硬的,已經(jīng)做出一些對應(yīng)的策略。
開發(fā)者進(jìn)行8.0(O)進(jìn)行通知欄的適配 如果你的targetSdkVersion>=26 那么恭喜你的 你需要進(jìn)行8.0通知欄適配,不然用戶是收不到你的通知信息。
8.0通知欄適配效果:用戶可以根據(jù)自己想要收到的通知,在設(shè)置里面找到應(yīng)用來進(jìn)行通知的關(guān)閉和打開
注意:這里必須區(qū)分8.0以后和8.0之前的區(qū)別 不然在低版本的手機(jī)上會出現(xiàn)崩潰的現(xiàn)象

/**
*  這里需要?jiǎng)?chuàng)建一個(gè)通知渠道其中必須包括
*  渠道id  這個(gè)可以隨便定義,但是要保證全局的唯一性
*  渠道名稱 這個(gè)是最直接最接近可以的 用來讓用戶知道渠道的用途
*  重要等級
*/
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("收到一條聊天信息", "這是聊天內(nèi)容", "chat");
            manager.notify(1, notification);
}

下面是自己的demo(可以直接復(fù)制)

這里將8.0上下綜合到一起,大家可以稍作改動(dòng)封裝運(yùn)用到自己的項(xiàng)目中

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="發(fā)送聊天消息" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="sendSubscribeMsg"
            android:text="發(fā)送訂閱消息" />
    </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() {
        //判斷當(dāng)前版本是不是>=8.0
        /**
         * 由于現(xiàn)在所有的app應(yīng)用都希望通過推送消息來進(jìn)行自己app的宣傳造成用戶的通知欄非常的臃腫,有時(shí)候一晚上不看手機(jī),第二天通知欄已經(jīng)爆滿了
         * google已經(jīng)根據(jù)這種情況做出了相應(yīng)的對策
         * 開發(fā)者進(jìn)行8.0(O)進(jìn)行通知欄的適配 如果你的targetSdkVersion>=26  那么恭喜你的  你需要進(jìn)行8.0通知欄適配,不然用戶是收不到你的通知信息
         * 8.0通知欄適配效果:用戶可以根據(jù)自己想要收到的通知,在設(shè)置里面找到應(yīng)用來進(jìn)行通知的關(guān)閉和打開
         * 注意:這里必須區(qū)分8.0以后和8.0之前的區(qū)別  不然在低版本的手機(jī)上會出現(xiàn)崩潰的現(xiàn)象
         *  這里需要?jiǎng)?chuàng)建一個(gè)通知渠道其中必須包括
         *  渠道id  這個(gè)可以隨便定義,但是要保證全局的唯一性
         *  渠道名稱 這個(gè)是最直接最接近可以的 用來讓用戶知道渠道的用途
         *  重要等級
         */
        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("收到一條聊天信息", "這是聊天內(nèi)容", "chat");
            manager.notify(1, notification);
        } else {
            Notification notification_25 = getNotification_25("收到一條聊天信息", "這是聊天內(nèi)容");
            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("收到一條訂閱消息", "這是訂閱內(nèi)容", "subscribe");
            manager.notify(2, notification);
        } else {
            Notification notification_25 = getNotification_25("收到一條訂閱消息", "這是訂閱內(nèi)容");
            manager.notify(2, notification_25);
        }

    }
}

微信圖片_20190804155450.jpg
微信圖片_20190804154818.jpg

我demo中用的DataBinding如果大家想要運(yùn)行可以將
DataBindingUtil.setContentView(this, R.layout.activity_nofication);
改成setContentView(R.layout.activity_nofication);然后將布局中最外面的<layout></layout>刪掉就可以
或者在build中添加
dataBinding { enabled = true}就可以了
大家可以自己創(chuàng)建個(gè)應(yīng)用去試驗(yàn)一下Notification效果

注意

8.0一下創(chuàng)建Notification對象是這樣的
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
8.0以上是這樣的
Notification.Builder builder = new Notification.Builder(this, channelId);
這里主要就是多了一個(gè)渠道號的參數(shù)

參考鏈接

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容