
通知欄的作用
通知欄的主要目的就是將一些重要的信息即使告訴用戶,通知欄的設(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以上通知渠道區(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);
}
}
}


我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