1愤炸、Android O(8.0)通知的改變
NotificationChannel是android8.0新增的特性,如果App的targetSDKVersion>=26粗悯,沒有設(shè)置channel通知渠道的話俄占,就會(huì)導(dǎo)致通知無(wú)法展示辐烂。
Android O 引入了 通知渠道(Notification Channels),以提供統(tǒng)一的系統(tǒng)來(lái)幫助用戶管理通知验残,如果是針對(duì) android O 為目標(biāo)平臺(tái)時(shí)捞附,必須實(shí)現(xiàn)一個(gè)或者多個(gè)通知渠道,以向用戶顯示通知。比如聊天軟件鸟召,為每個(gè)聊天組設(shè)置一個(gè)通知渠道胆绊,指定特定聲音、燈光等配置欧募。
2压状、Android Channel通知的兼容支配
創(chuàng)建NotificationChannel
- 創(chuàng)建NotificationChannel對(duì)象,指定Channel的id跟继、name和通知的重要程度
- 使用NotificationMannager的createNotificationChannel方法來(lái)添加Channel何缓。
private NotificationManager getNotificationManager() {
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mNotificationManager;
}
@NonNull
private NotificationCompat.Builder getNotificationBuilder() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("channel_id", "channel_name",
NotificationManager.IMPORTANCE_DEFAULT);
//是否繞過(guò)請(qǐng)勿打擾模式
channel.canBypassDnd();
//閃光燈
channel.enableLights(true);
//鎖屏顯示通知
channel.setLockscreenVisibility(VISIBILITY_SECRET);
//閃關(guān)燈的燈光顏色
channel.setLightColor(Color.RED);
//桌面launcher的消息角標(biāo)
channel.canShowBadge();
//是否允許震動(dòng)
channel.enableVibration(true);
//獲取系統(tǒng)通知響鈴聲音的配置
channel.getAudioAttributes();
//獲取通知取到組
channel.getGroup();
//設(shè)置可繞過(guò) 請(qǐng)勿打擾模式
channel.setBypassDnd(true);
//設(shè)置震動(dòng)模式
channel.setVibrationPattern(new long[]{100, 100, 200});
//是否會(huì)有燈光
channel.shouldShowLights();
getNotificationManager().createNotificationChannel(channel);
}
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, "channel_id");
notification.setContentTitle("新消息來(lái)了");
notification.setContentText("周末到了,不用上班了");
notification.setSmallIcon(R.mipmap.ic_launcher);
notification.setAutoCancel(true);
return notification;
}
- 設(shè)置通知重要性級(jí)別
該級(jí)別必須要在 NotificationChannel 的構(gòu)造函數(shù)中指定还栓,總共要五個(gè)級(jí)別碌廓;范圍是從 NotificationManager.IMPORTANCE_NONE(0) ~ NotificationManager.IMPORTANCE_HIGH(4)
,如果要支持 Android 7.1(API 25)及以下的設(shè)備剩盒,還得調(diào)用NotificationCompat 的 setPriority 方法來(lái)設(shè)置谷婆,如下所示
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
Android 8.0 及以上是使用NotificationManager.IMPORTANCE_,Android 7.1 及以下是使用NotificationCompat.PRIORITY_它們都是定義的常量辽聊;下面我們以表格的形式更好的展示出來(lái)纪挎。
用戶通知級(jí)別 | Android8.0及以上 | Android7.0及以下 |
---|---|---|
緊急級(jí)別(發(fā)出通知聲音并顯示為提示通知) | IMPORTANCE_HIGH | PRIORITY_HIGH或者PRIORITY_MAX |
高級(jí)別(發(fā)出通知聲音并且通知欄有通知) | IMPORTANCE_DEFAULT | PRIORITY_DEFAULT |
中等級(jí)別(沒有通知聲音但通知欄有通知) | IMPORTANCE_LOW | PRIORITY_LOW |
低級(jí)別(沒有通知聲音也不會(huì)出現(xiàn)在狀態(tài)欄上) | IMPORTANCE_MIN | PRIORITY_MIN |
上面這些通知級(jí)別用戶都是可以在 Channel 設(shè)置中更改
3、Android Channel通知的應(yīng)用與管理(更新跟匆、刪除)
4异袄、自定義Channel通知欄
private void sendCustomNotification() {
NotificationCompat.Builder builder = getNotificationBuilder();
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_custom_notifition);
remoteViews.setTextViewText(R.id.notification_title, "custom_title");
remoteViews.setTextViewText(R.id.notification_content, "custom_content");
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, -1,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.turn_next, pendingIntent);
builder.setCustomContentView(remoteViews);
getNotificationManager().notify(3, builder.build());
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/notification_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通知欄標(biāo)題"
android:textSize="24sp"/>
<TextView
android:id="@+id/notification_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="通知欄內(nèi)容"/>
</LinearLayout>
<Button
android:id="@+id/turn_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="跳轉(zhuǎn)"/>
</RelativeLayout>
5、封裝的代碼
public class NotificationUtils extends ContextWrapper {
public static final String CHANNEL_ID = "default";
private static final String CHANNEL_NAME = "Default Channel";
private static final String CHANNEL_DESCRIPTION = "this is default channel!";
private NotificationManager mManager;
public NotificationUtils(Context base) {
super(base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel();
}
}
@TargetApi(Build.VERSION_CODES.O)
private void createNotificationChannel() {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
//是否繞過(guò)請(qǐng)勿打擾模式
channel.canBypassDnd();
//閃光燈
channel.enableLights(true);
//鎖屏顯示通知
channel.setLockscreenVisibility(VISIBILITY_SECRET);
//閃關(guān)燈的燈光顏色
channel.setLightColor(Color.RED);
//桌面launcher的消息角標(biāo)
channel.canShowBadge();
//是否允許震動(dòng)
channel.enableVibration(true);
//獲取系統(tǒng)通知響鈴聲音的配置
channel.getAudioAttributes();
//獲取通知取到組
channel.getGroup();
//設(shè)置可繞過(guò) 請(qǐng)勿打擾模式
channel.setBypassDnd(true);
//設(shè)置震動(dòng)模式
channel.setVibrationPattern(new long[]{100, 100, 200});
//是否會(huì)有燈光
channel.shouldShowLights();
getManager().createNotificationChannel(channel);
}
private NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
/**
* 發(fā)送通知
*/
public void sendNotification(String title, String content) {
NotificationCompat.Builder builder = getNotification(title, content);
getManager().notify(1, builder.build());
}
private NotificationCompat.Builder getNotification(String title, String content) {
NotificationCompat.Builder builder = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
} else {
builder = new NotificationCompat.Builder(getApplicationContext());
builder.setPriority(PRIORITY_DEFAULT);
}
//標(biāo)題
builder.setContentTitle(title);
//文本內(nèi)容
builder.setContentText(content);
//小圖標(biāo)
builder.setSmallIcon(R.mipmap.ic_launcher);
//設(shè)置點(diǎn)擊信息后自動(dòng)清除通知
builder.setAutoCancel(true);
return builder;
}
/**
* 發(fā)送通知
*/
public void sendNotification(int notifyId, String title, String content) {
NotificationCompat.Builder builder = getNotification(title, content);
getManager().notify(notifyId, builder.build());
}
/**
* 發(fā)送帶有進(jìn)度的通知
*/
public void sendNotificationProgress(String title, String content, int progress, PendingIntent intent) {
NotificationCompat.Builder builder = getNotificationProgress(title, content, progress, intent);
getManager().notify(0, builder.build());
}
/**
* 獲取帶有進(jìn)度的Notification
*/
private NotificationCompat.Builder getNotificationProgress(String title, String content,
int progress, PendingIntent intent) {
NotificationCompat.Builder builder = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
} else {
builder = new NotificationCompat.Builder(getApplicationContext());
builder.setPriority(PRIORITY_DEFAULT);
}
//標(biāo)題
builder.setContentTitle(title);
//文本內(nèi)容
builder.setContentText(content);
//小圖標(biāo)
builder.setSmallIcon(R.mipmap.ic_launcher);
//設(shè)置大圖標(biāo)玛臂,未設(shè)置時(shí)使用小圖標(biāo)代替烤蜕,拉下通知欄顯示的那個(gè)圖標(biāo)
//設(shè)置大圖片 BitmpFactory.decodeResource(Resource res,int id) 根據(jù)給定的資源Id解析成位圖
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
if (progress > 0 && progress < 100) {
//一種是有進(jìn)度刻度的(false),一種是循環(huán)流動(dòng)的(true)
//設(shè)置為false,表示刻度迹冤,設(shè)置為true讽营,表示流動(dòng)
builder.setProgress(100, progress, false);
} else {
//0,0,false,可以將進(jìn)度條隱藏
builder.setProgress(0, 0, false);
builder.setContentText("下載完成");
}
//設(shè)置點(diǎn)擊信息后自動(dòng)清除通知
builder.setAutoCancel(true);
//通知的時(shí)間
builder.setWhen(System.currentTimeMillis());
//設(shè)置點(diǎn)擊信息后的跳轉(zhuǎn)(意圖)
builder.setContentIntent(intent);
return builder;
}
}