您好,登錄后才能下訂單哦!
內容,通過 setContentText() 方法設置
NotificationManager : NotificationManager 是通知管理類,它是一個系統服務。調用 NotificationManager 的 notify() 方法可以向系統發送通知。
3.2.2 Notification創建步驟與代碼
// 創建一個NotificationManager的引用
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
// 定義Notification的各種屬性
Notification.Builder mBuilder = new Notification.Builder(this.getApplicationContext())
.setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI) //
.setSmallIcon(R.mipmap.ic_launcher) //設置通知的圖標
.setTicker("有新消息呢") //設置狀態欄的標題
.setContentTitle("這個是標題") //設置標題
.setContentText("這個是內容") //消息內容
.setDefaults(Notification.DEFAULT_ALL) //設置默認的提示音
.setPriority(Notification.PRIORITY_DEFAULT) //設置該通知的優先級
.setOngoing(false) //讓通知左右滑的時候不能取消通知
.setPriority(Notification.PRIORITY_DEFAULT) //設置該通知的優先級
.setWhen(System.currentTimeMillis()) //設置通知時間,默認為系統發出通知的時間,通常不用設置
.setAutoCancel(true); //打開程序后圖標消失
//處理點擊Notification的邏輯
Intent resultIntent = new Intent(this, TestActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //添加為棧頂Activity
resultIntent.putExtra("what",5);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this,5,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
//發送
mNotificationManager.notify(1, mBuilder.build());
//結束廣播
//mNotificationManager.cancel(1);
效果如圖所示:
具體代碼如下所示:
//創建intent
Intent resultIntent = new Intent(this, TestActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //添加為棧頂Activity
resultIntent.putExtra("what",5);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this,5,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
//發送pendingIntent
mBuilder.setContentIntent(resultPendingIntent);
更新通知很簡單,只需要再次發送相同 ID 的通知即可,如果之前的通知還未被取消,則會直接更新該通知相關的屬性;如果之前的通知已經被取消,則會重新創建一個新通知。更新通知跟發送通知使用相同的方式。
如果你是通過 NotificationManager.notify(String tag, int id, Notification notify) 方法創建的通知,那么只能通過 NotificationManager.cancel(String tag, int id) 方法才能清除對應的通知,調用NotificationManager.cancel(int id) 無效。
代碼:
private void sendNotification9() {
Notification.Builder mBuilder = new Notification.Builder(this.getApplicationContext())
.setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI)
.setSmallIcon(R.mipmap.ic_launcher) //設置通知的圖標
.setTicker("有新消息呢9") //設置狀態欄的標題
.setContentTitle("這個是標題9") //設置標題
.setContentText("這個是內容9") //消息內容
.setDefaults(Notification.DEFAULT_ALL) //設置默認的提示音
.setOngoing(false) //讓通知左右滑的時候不能取消通知
.setAutoCancel(true); //打開程序后圖標消失
Notification notification = mBuilder.build();
//設置 Notification 的 flags = FLAG_NO_CLEAR
//FLAG_NO_CLEAR 表示該通知不能被狀態欄的清除按鈕給清除掉,也不能被手動清除,但能通過 cancel() 方法清除
//flags 可以通過 |= 運算疊加效果
notification.flags |= Notification.FLAG_NO_CLEAR;
//獲取NotificationManager 對象
mNotificationManager.notify(9, notification);
}
//取消通知:
if(mNotificationManager!=null){
mNotificationManager.cancelAll();
}
//設置系統默認提醒效果,一旦設置默認提醒效果,則自定義的提醒效果會全部失效。具體可看源碼//添加默認震動效果,需要申請震動權限//<uses-permission android:name="android.permission.VIBRATE" />
Notification.DEFAULT_VIBRATE
//添加系統默認聲音效果,設置此值后,調用setSound()設置自定義聲音無效
Notification.DEFAULT_SOUND
//添加默認呼吸燈效果,使用時須與 Notification.FLAG_SHOW_LIGHTS 結合使用,否則無效
Notification.DEFAULT_LIGHTS
//添加上述三種默認提醒效果
Notification.DEFAULT_ALL
//提醒效果常用 Flag//三色燈提醒,在使用三色燈提醒時候必須加該標志符
Notification.FLAG_SHOW_LIGHTS
//發起正在運行事件(活動中)
Notification.FLAG_ONGOING_EVENT
//讓聲音、振動無限循環,直到用戶響應 (取消或者打開)
Notification.FLAG_INSISTENT
//發起Notification后,鈴聲和震動均只執行一次
Notification.FLAG_ONLY_ALERT_ONCE
//用戶單擊通知后自動消失
Notification.FLAG_AUTO_CANCEL
//只有調用NotificationManager.cancel()時才會清除
Notification.FLAG_NO_CLEAR
//表示正在運行的服務
Notification.FLAG_FOREGROUND_SERVICE
// 添加默認聲音提醒
builder.setDefaults(Notification.DEFAULT_SOUND);
// 添加默認呼吸燈提醒,自動添加FLAG_SHOW_LIGHTS
builder.setDefaults(Notification.DEFAULT_LIGHTS);
private void sendNotification11() {
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是伴有鈴聲效果的通知11")
.setContentText("美妙么?安靜聽~11")
//調用系統默認響鈴,設置此屬性后setSound()會無效
//.setDefaults(Notification.DEFAULT_SOUND)
//調用系統多媒體褲內的鈴聲
//.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"));
//調用自己提供的鈴聲,位于 /res/values/raw 目錄下
.setSound(Uri.parse("android.resource://com.yc.cn.ycnotification/" + R.raw.hah));
//另一種設置鈴聲的方法
//Notification notify = builder.build();
//調用系統默認鈴聲
//notify.defaults = Notification.DEFAULT_SOUND;
//調用自己提供的鈴聲
//notify.sound = Uri.parse("android.resource://com.yc.cn.ycnotification/"+R.raw.sound);
//調用系統自帶的鈴聲
//notify.sound = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2");
//mManager.notify(11,notify);
mNotificationManager.notify(11, builder.build());
}
設置震動屬性
private void sendNotification12() {
//震動也有兩種設置方法,與設置鈴聲一樣,在此不再贅述
long[] vibrate = new long[]{0, 500, 1000, 1500};
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是伴有震動效果的通知")
.setContentText("顫抖吧,逗比哈哈哈哈哈~")
//使用系統默認的震動參數,會與自定義的沖突
//.setDefaults(Notification.DEFAULT_VIBRATE)
//自定義震動效果
.setVibrate(vibrate);
//另一種設置震動的方法
//Notification notify = builder.build();
//調用系統默認震動
//notify.defaults = Notification.DEFAULT_VIBRATE;
//調用自己設置的震動
//notify.vibrate = vibrate;
//mManager.notify(3,notify);
mNotificationManager.notify(12, builder.build());
}
.setContent(getRemoteViews()) // 設置通知欄的布局
//創建自定義布局
private RemoteViews getRemoteViews() {
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_mobile_play);
// 設置 點擊通知欄的上一首按鈕時要執行的意圖
remoteViews.setOnClickPendingIntent(R.id.btn_pre, getActivityPendingIntent(11));
// 設置 點擊通知欄的下一首按鈕時要執行的意圖
remoteViews.setOnClickPendingIntent(R.id.btn_next, getActivityPendingIntent(12));
// 設置 點擊通知欄的播放暫停按鈕時要執行的意圖
remoteViews.setOnClickPendingIntent(R.id.btn_start, getActivityPendingIntent(13));
// 設置 點擊通知欄的根容器時要執行的意圖
remoteViews.setOnClickPendingIntent(R.id.ll_root, getActivityPendingIntent(14));
remoteViews.setTextViewText(R.id.tv_title, "標題"); // 設置通知欄上標題
remoteViews.setTextViewText(R.id.tv_artist, "藝術家"); // 設置通知欄上藝術家
return remoteViews;
}
PendingIntent 是 Android 系統管理并持有的用于描述和獲取原始數據的對象的標志(引用)。也就是說,即便創建該PendingIntent對象的進程被殺死了,這個PendingItent對象在其他進程中還是可用的。
日常使用中的短信、鬧鐘等都用到了 PendingIntent。
//獲取一個用于啟動 Activity 的 PendingIntent 對象public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags);
//獲取一個用于啟動 Service 的 PendingIntent 對象public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags);
//獲取一個用于向 BroadcastReceiver 廣播的 PendingIntent 對象public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
FLAG_CANCEL_CURRENT:如果當前系統中已經存在一個相同的 PendingIntent 對象,那么就將先將已有的 PendingIntent 取消,然后重新生成一個 PendingIntent 對象。
FLAG_NO_CREATE:如果當前系統中不存在相同的 PendingIntent 對象,系統將不會創建該 PendingIntent 對象而是直接返回 null 。
FLAG_ONE_SHOT:該 PendingIntent 只作用一次。
FLAG_UPDATE_CURRENT:如果系統中已存在該 PendingIntent 對象,那么系統將保留該 PendingIntent 對象,但是會使用新的 Intent 來更新之前 PendingIntent 中的 Intent 對象數據,例如更新 Intent 中的 Extras 。
Notification.Builder mBuilder = new Notification.Builder(context)
.setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("廣播接受者標題,小楊")
.setContentText("廣播接受者內容,扯犢子")
.setAutoCancel(true);
Log.i(TAG, "onReceive: intent" + intent.getClass().getName());
Intent resultIntent = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
//將該Activity添加為棧頂
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
系統默認使用R.layout.notification_template_material_base生產一個RemoteView.
至于這里的布局是怎么查到的,請看下面源碼分析
6.3.1 創建NotificationChannel步驟
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//android 8.0以上需要特殊處理,也就是targetSDKVersion為26以上
createNotificationChannel();
}
@TargetApi(Build.VERSION_CODES.O)
private void createNotificationChannel() {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.canBypassDnd();//是否繞過請勿打擾模式
channel.enableLights(true);//閃光燈
channel.setLockscreenVisibility(VISIBILITY_SECRET);//鎖屏顯示通知
channel.setLightColor(Color.RED);//閃關燈的燈光顏色
channel.canShowBadge();//桌面launcher的消息角標
channel.enableVibration(true);//是否允許震動
channel.getAudioAttributes();//獲取系統通知響鈴聲音的配置
channel.getGroup();//獲取通知取到組
channel.setBypassDnd(true);//設置可繞過 請勿打擾模式
channel.setVibrationPattern(new long[]{100, 100, 200});//設置震動模式
channel.shouldShowLights();//是否會有燈光
getManager().createNotificationChannel(channel);
}
- 設置通知重要性級別
- 該級別必須要在 NotificationChannel的構造函數中指定,總共要五個級別;范圍是從NotificationManager.IMPORTANCE_NONE(0) ~ NotificationManager.IMPORTANCE_HIGH(4)
- 如果要支持 Android 7.1(API 25)及以下的設備,還得調用NotificationCompat 的 setPriority 方法來設置
如下所示
public class NotificationUtils extends ContextWrapper {
public static final String CHANNEL_ID = "default";
private static final String CHANNEL_NAME = "Default_Channel";
private NotificationManager mManager;
private int[] flags;
public NotificationUtils(Context base) {
super(base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//android 8.0以上需要特殊處理,也就是targetSDKVersion為26以上
createNotificationChannel();
}
}
@TargetApi(Build.VERSION_CODES.O)
private void createNotificationChannel() {
//第一個參數:channel_id
//第二個參數:channel_name
//第三個參數:設置通知重要性級別
//注意:該級別必須要在 NotificationChannel 的構造函數中指定,總共要五個級別;
//范圍是從 NotificationManager.IMPORTANCE_NONE(0) ~ NotificationManager.IMPORTANCE_HIGH(4)
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT);
channel.canBypassDnd();//是否繞過請勿打擾模式
channel.enableLights(true);//閃光燈
channel.setLockscreenVisibility(VISIBILITY_SECRET);//鎖屏顯示通知
channel.setLightColor(Color.RED);//閃關燈的燈光顏色
channel.canShowBadge();//桌面launcher的消息角標
channel.enableVibration(true);//是否允許震動
channel.getAudioAttributes();//獲取系統通知響鈴聲音的配置
channel.getGroup();//獲取通知取到組
channel.setBypassDnd(true);//設置可繞過 請勿打擾模式
channel.setVibrationPattern(new long[]{100, 100, 200});//設置震動模式
channel.shouldShowLights();//是否會有燈光
getManager().createNotificationChannel(channel);
}
/**
* 獲取創建一個NotificationManager的對象
* @return NotificationManager對象
*/
public NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
/**
* 清空所有的通知
*/
public void clearNotification(){
getManager().cancelAll();
}
/**
* 建議使用這個發送通知
* 調用該方法可以發送通知
* @param notifyId notifyId
* @param title title
* @param content content
*/
public void sendNotification(int notifyId, String title, String content , int icon) {
Notification build;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//android 8.0以上需要特殊處理,也就是targetSDKVersion為26以上
//通知用到NotificationCompat()這個V4庫中的方法。但是在實際使用時發現書上的代碼已經過時并且Android8.0已經不支持這種寫法
Notification.Builder builder = getChannelNotification(title, content, icon);
build = builder.build();
} else {
NotificationCompat.Builder builder = getNotificationCompat(title, content, icon);
build = builder.build();
}
if (flags!=null && flags.length>0){
for (int a=0 ; a<flags.length ; a++){
build.flags |= flags[a];
}
}
getManager().notify(notifyId, build);
}
/**
* 調用該方法可以發送通知
* @param notifyId notifyId
* @param title title
* @param content content
*/
public void sendNotificationCompat(int notifyId, String title, String content , int icon) {
NotificationCompat.Builder builder = getNotificationCompat(title, content, icon);
Notification build = builder.build();
if (flags!=null && flags.length>0){
for (int a=0 ; a<flags.length ; a++){
build.flags |= flags[a];
}
}
getManager().notify(notifyId, build);
}
private NotificationCompat.Builder getNotificationCompat(String title, String content, int icon) {
NotificationCompat.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
} else {
//注意用下面這個方法,在8.0以上無法出現通知欄。8.0之前是正常的。這里需要增強判斷邏輯
builder = new NotificationCompat.Builder(getApplicationContext());
builder.setPriority(PRIORITY_DEFAULT);
}
builder.setContentTitle(title);
builder.setContentText(content);
builder.setSmallIcon(icon);
builder.setPriority(priority);
builder.setOnlyAlertOnce(onlyAlertOnce);
builder.setOngoing(ongoing);
if (remoteViews!=null){
builder.setContent(remoteViews);
}
if (intent!=null){
builder.setContentIntent(intent);
}
if (ticker!=null && ticker.length()>0){
builder.setTicker(ticker);
}
if (when!=0){
builder.setWhen(when);
}
if (sound!=null){
builder.setSound(sound);
}
if (defaults!=0){
builder.setDefaults(defaults);
}
//點擊自動刪除通知
builder.setAutoCancel(true);
return builder;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private Notification.Builder getChannelNotification(String title, String content, int icon){
Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID);
Notification.Builder notificationBuilder = builder
//設置標題
.setContentTitle(title)
//消息內容
.setContentText(content)
//設置通知的圖標
.setSmallIcon(icon)
//讓通知左右滑的時候是否可以取消通知
.setOngoing(ongoing)
//設置優先級
.setPriority(priority)
//是否提示一次.true - 如果Notification已經存在狀態欄即使在調用notify函數也不會更新
.setOnlyAlertOnce(onlyAlertOnce)
.setAutoCancel(true);
if (remoteViews!=null){
//設置自定義view通知欄
notificationBuilder.setContent(remoteViews);
}
if (intent!=null){
notificationBuilder.setContentIntent(intent);
}
if (ticker!=null && ticker.length()>0){
//設置狀態欄的標題
notificationBuilder.setTicker(ticker);
}
if (when!=0){
//設置通知時間,默認為系統發出通知的時間,通常不用設置
notificationBuilder.setWhen(when);
}
if (sound!=null){
//設置sound
notificationBuilder.setSound(sound);
}
if (defaults!=0){
//設置默認的提示音
notificationBuilder.setDefaults(defaults);
}
if (pattern!=null){
//自定義震動效果
notificationBuilder.setVibrate(pattern);
}
return notificationBuilder;
}
private boolean ongoing = false;
private RemoteViews remoteViews = null;
private PendingIntent intent = null;
private String ticker = "";
private int priority = Notification.PRIORITY_DEFAULT;
private boolean onlyAlertOnce = false;
private long when = 0;
private Uri sound = null;
private int defaults = 0;
private long[] pattern = null;
/**
* 讓通知左右滑的時候是否可以取消通知
* @param ongoing 是否可以取消通知
* @return
*/
public NotificationUtils setOngoing(boolean ongoing){
this.ongoing = ongoing;
return this;
}
/**
* 設置自定義view通知欄布局
* @param remoteViews view
* @return
*/
public NotificationUtils setContent(RemoteViews remoteViews){
this.remoteViews = remoteViews;
return this;
}
/**
* 設置內容點擊
* @param intent intent
* @return
*/
public NotificationUtils setContentIntent(PendingIntent intent){
this.intent = intent;
return this;
}
/**
* 設置狀態欄的標題
* @param ticker 狀態欄的標題
* @return
*/
public NotificationUtils setTicker(String ticker){
this.ticker = ticker;
return this;
}
/**
* 設置優先級
* 注意:
* Android 8.0以及上,在 NotificationChannel 的構造函數中指定,總共要五個級別;
* Android 7.1(API 25)及以下的設備,還得調用NotificationCompat 的 setPriority方法來設置
*
* @param priority 優先級,默認是Notification.PRIORITY_DEFAULT
* @return
*/
public NotificationUtils setPriority(int priority){
this.priority = priority;
return this;
}
/**
* 是否提示一次.true - 如果Notification已經存在狀態欄即使在調用notify函數也不會更新
* @param onlyAlertOnce 是否只提示一次,默認是false
* @return
*/
public NotificationUtils setOnlyAlertOnce(boolean onlyAlertOnce){
this.onlyAlertOnce = onlyAlertOnce;
return this;
}
/**
* 設置通知時間,默認為系統發出通知的時間,通常不用設置
* @param when when
* @return
*/
public NotificationUtils setWhen(long when){
this.when = when;
return this;
}
/**
* 設置sound
* @param sound sound
* @return
*/
public NotificationUtils setSound(Uri sound){
this.sound = sound;
return this;
}
/**
* 設置默認的提示音
* @param defaults defaults
* @return
*/
public NotificationUtils setDefaults(int defaults){
this.defaults = defaults;
return this;
}
/**
* 自定義震動效果
* @param pattern pattern
* @return
*/
public NotificationUtils setVibrate(long[] pattern){
this.pattern = pattern;
return this;
}
/**
* 設置flag標簽
* @param flags flags
* @return
*/
public NotificationUtils setFlags(int... flags){
this.flags = flags;
return this;
}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。