內容,經過 setContentText() 方法設置php
NotificationManager : NotificationManager 是通知管理類,它是一個系統服務。調用 NotificationManager 的 notify() 方法能夠向系統發送通知。android
3.2.2 Notification建立步驟與代碼git
// 建立一個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);
效果如圖所示:github
具體代碼以下所示:segmentfault
//建立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 的通知便可,若是以前的通知還未被取消,則會直接更新該通知相關的屬性;若是以前的通知已經被取消,則會從新建立一個新通知。更新通知跟發送通知使用相同的方式。api
若是你是經過 NotificationManager.notify(String tag, int id, Notification notify) 方法建立的通知,那麼只能經過 NotificationManager.cancel(String tag, int id) 方法才能清除對應的通知,調用NotificationManager.cancel(int id) 無效。微信
代碼:app
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()); }
設置震動屬性ide
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; } }