1. 創(chuàng)建notification
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.id.icon)
.setContentTitle("標題")
.setContentText("詳細文本");
通過Builder模式創(chuàng)建Notification.Builder實例腌歉,有了builder對象稽鞭,可以給它添加各種屬性,例如標題二蓝,內(nèi)容誉券,圖標等
2. 定義Action
給點擊Notification后要執(zhí)行的操作增加一個Intent,由于這個Intent不是馬上就執(zhí)行的刊愚,而是有用戶觸發(fā)的踊跟,所以Android給這樣的Intent提供了一個延遲意圖PendingIntent來幫助我們完成這樣的操作
PendingIntent的使用非常簡單,只需要在Intent的基礎(chǔ)上包裝一層就可以了,代碼如下所示
Intent resultIntent = new Intent(this, ResultActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
這樣當點擊Notification后商玫,就會觸發(fā)PendingIntent事件箕憾,跳轉(zhuǎn)到指定的Activity
3. 設(shè)置點擊事件
builder.setContentIntent(resultPendingIntent);
注意事項:當點擊通知跳轉(zhuǎn)到Activity的時候,Activity會重新走生命周期拳昌,想要保持原來的狀態(tài)袭异,需要給Activity配置一個launchMode = “singleTask”
4. 發(fā)送通知
通過NotificationManager通知管理器的notify()方法來發(fā)送Notification,并給Notification一個id值炬藤,這個id會在更新Notification的時候用到
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
int mNotificationId = 001;
mNotifyMgr.notify(mNotificationId, builder.build());
5. 使用BigView樣式
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(getString(R.string.notification))
.setContentText(getString(R.string.ping))
.setDefaults(Notification.DEFAULT_ALL)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.addAction (R.drawable.ic_stat_dismiss,
getString(R.string.dismiss), piDismiss)
.addAction (R.drawable.ic_stat_snooze,
getString(R.string.snooze), piSnooze);
6. 顯示Notification進度
int id = 1;
...
NotificationManager mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder mBuilder = new Notification.Builder(this);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_notification);
new Thread(new Runnable() {
@Override
public void run() {
int i;
for (i = 0; i <= 100; i+=5) {
mBuilder.setProgress(100, i, false);
mNotifyManager.notify(id, mBuilder.build());
Thread.sleep(5*1000);
}
mBuilder.setContentText("Download complete")
.setProgress(0,0,false);
mNotifyManager.notify(id, mBuilder.build());
}
}
).start();
7. 更新通知
根據(jù)id來更新通知
8. 自定義通知布局
Notification的自定義布局通過RemoteViews去實現(xiàn)御铃,調(diào)用Notification.Builder的setCustomContentView()方法設(shè)置自定義的布局
//通過RemoteViews來創(chuàng)建自定義的Notification視圖
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
contentView.setTextViewText(R.id.tv, "show me when collapsed");
Notification.Builder builder = new Notification.Builder(this)
.setCustomContentView(contentView);
折疊式Notification
折疊式Notification 也是一種自定義視圖的Notification ,常常用于顯示長文本沈矿。它擁有兩個視圖狀態(tài)上真, 一個是普通狀態(tài)下的視圖狀態(tài), 另一個是展開狀態(tài)下的視圖狀態(tài)羹膳。在Notitication中睡互,使用RemoteViews 來幫助我們創(chuàng)建一個自定義的Notification 視圖,代碼如下所示溜徙。
//通過RemoteViews來創(chuàng)建自定義的Notification視圖
RemoteViews contentView = new RemoteViews(getPackageName(),R.layout.notification);
contentView.setTextViewText(R.id.tv,"show me when collapsed");
懸掛式Notification
觸發(fā)懸掛式的Notification的條件有
- Activity處于全屏模式
- Notification擁有很高的優(yōu)先級
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(Notification.PRIORITY_DEFAULT)
.setCategory(Notification.CATEGORY_MESSAGE)
.setContentTitle("Headsup Notification")
.setContentText("I am Headsup Notification");
Intent push = new Intent();
push.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
push.setClass(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this,0,push,PendingIntent.FLAG_CANCEL_CURRENT);
NotificationManager manager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1,builder.build());
Notification的顯示等級
Android 5.x 將Notification分成了三個等級
- VISIBILITY_PRIVATE:表面只有當沒有鎖屏的時候才能夠顯示
- VISIBILITY_PUBLIC:表明任何情況下都會顯示
- VISIBILITY_SECRET:表明在pin,password等安全鎖和沒有鎖屏的情況下才能夠顯示
設(shè)置Notification的顯示等級
Notification.Builder builder = new Notification.Builder(this)
.setVisibility(Notification.VISIBILITY_PRIVATE)犀填;
9. 創(chuàng)建一個常規(guī)的activity延遲意圖
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ResultActivity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
為Intent創(chuàng)建一個回退棧
...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
10. 創(chuàng)建一個特別的activity延遲意圖
<activity
android:name=".ResultActivity"
...
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
Intent notifyIntent = new Intent(this, ResultActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
builder.setContentIntent(notifyPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
11蠢壹、Android 7.0 通知新特性
在Android N中重新設(shè)計了通知,可以達到更容易九巡、更快使用的效果图贸。一些主要的變化包括:
模板更新:更新了通知模板重點內(nèi)容和頭像。開發(fā)者將能夠利用的新模板的優(yōu)勢冕广,在他們的代碼中實現(xiàn)最低限度的調(diào)整疏日。
捆綁通知:Android N的通知功能也更加人性化,現(xiàn)在會自動將相同應(yīng)用的通知捆綁在一起撒汉,實現(xiàn)分組顯示沟优,并且通過兩指滑動實現(xiàn)預(yù)覽,理論上用戶可以在通知界面直接閱讀郵件等內(nèi)容睬辐。
直接回復(fù):對于實時通信應(yīng)用程序挠阁,Android系統(tǒng)支持在線回復(fù),使用戶可以以短信或短信通知界面內(nèi)快速溯饵、直接響應(yīng)侵俗。
自定義視圖:兩個新的 API 讓用戶在通知中使用自定義視圖。
Android N 開發(fā)者預(yù)覽版的通知系統(tǒng)中還加入了兩個全新的 API 接口:Direct Replies 和 Bundling丰刊。前者支持為第三方應(yīng)用的通知加入快速回復(fù)和快捷操作隘谣,后者則允許同時發(fā)出多條通知的應(yīng)用進行通知拆分。
當一款應(yīng)用完美的適配了 Android N啄巧,當收到一條消息時就可以直接在下拉通知抽屜甚至是鎖屏中直接呼出輸入框進行回復(fù)寻歧,或是選擇事先設(shè)定好的快速處理操作(標記為已讀掌栅、轉(zhuǎn)發(fā)等)。而當用戶同時收到來自不同聯(lián)系人的消息時熄求,可以點擊知卡片上的通知拆分按鈕對已經(jīng)合并的通知進行拆分渣玲,拆分后的通知可以像其他的獨立通知一樣進行回復(fù)和處理。
當然弟晚,現(xiàn)階段適配了這兩個特性的應(yīng)用屈指可數(shù)忘衍,除了 Google 的環(huán)聊、Messenger 以及 Gmail 等應(yīng)用以外卿城,目前僅發(fā)現(xiàn)第三方 Telegram 客戶端 Plus Messenger 支持以上功能枚钓。
面對各種應(yīng)用的通知推送, Android N取以優(yōu)先級為核心的通知管理方式瑟押,而在 Android N中搀捷,通知管理也變得更加簡單:只需在需要在相應(yīng)的通知上左右輕掃便能看見一個設(shè)置圖標,點擊該圖標就能在通知上方呼出一個簡潔的通知優(yōu)先級設(shè)定界面多望,在這個界面可以將應(yīng)用通知設(shè)定為“靜默顯示”嫩舟、“阻攔所有通知”和“默認”三個等級。
如果在”系統(tǒng)界面調(diào)諧器 - 其它“中打開了”Show full importance settings”功能怀偷,這三個等級又將變?yōu)椤逼帘?- 低 - 一般 - 高 - 緊急”5 個家厌,設(shè)定的方式也由縱列選項變?yōu)樽笥一瑒印_@個看似新穎的設(shè)計實際上是對現(xiàn)有通知管理操作的一次簡化椎工,在 Android 6.0 中需要在兩個界面來回跳轉(zhuǎn)才能完成的操作饭于,在Android 7.0只用在一個界面就可以搞定。
同時维蒙,Google 也將其對通知優(yōu)先級的定義從”幕后”搬到了”臺前”掰吕,在進行完整的五層次優(yōu)先級設(shè)定時 Google 還會提醒不同優(yōu)先級所對應(yīng)的通知效果。最后颅痊,勿擾模式也在 Android N 中得到了完善殖熟,加入了自動規(guī)則并允許用戶在“請勿打擾”模式下屏蔽靜音通知的彈窗甚至是手機的通知指示燈。
發(fā)送一個通知
private int i = 0;
private NotificationManager mNotificationManager;
private static final String GROUP_NAME = "com.heima.notification_type";
//[1]獲取一個NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]創(chuàng)建一個Notification
//[2.1]需要給這個Notification對象指定icon,標題,內(nèi)容,
final Notification builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle(getString(R.string.app_name))
.setContentText("這是一個消息通知")
.setAutoCancel(true)
.setGroup(GROUP_NAME)
.build();
//[3]發(fā)送一個通知 需要指定一個Notification對象和一個id,這個id必須是唯一的
mNotificationManager.notify(i++, builder);
updateNotificationSummary();
多個通知放入到一個組內(nèi)
//[4]創(chuàng)建一個notification組
String notificationContent = "傳智播客" + i;
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setStyle(new NotificationCompat.BigTextStyle()
.setSummaryText(notificationContent))
.setGroup(GROUP_NAME)
.setGroupSummary(true);
final Notification notification = builder.build();
//[5]發(fā)送這個notification組
mNotificationManager.notify(101, notification);
可以回復(fù)的通知
private NotificationManager mNotificationManager;
//[1]獲取一個NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]創(chuàng)建remoteInput對象,這個對象指定了這個notification的標題和一個key
String replyLabel = getResources().getString(R.string.app_name);
RemoteInput remoteInput = new RemoteInput.Builder("heima")
.setLabel(replyLabel)
.build();
//[3]創(chuàng)建一個Action對象 可以指定用戶一個友好的輸入提示斑响,可以指定跳轉(zhuǎn)意圖,
Intent deleteIntent = new Intent("");
Notification.Action action =
new Notification.Action.Builder(R.mipmap.ic_launcher,
"請輸入內(nèi)容", PendingIntent.getActivity(this, 10002, deleteIntent, 0))
.addRemoteInput(remoteInput)
.build();
//[3]創(chuàng)建一個Notification對象
Notification notification =
new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle("傳智播客")
.setContentText("消息通知")
.addAction(action)
.build();
//[4]發(fā)送這個notification
mNotificationManager.notify(1, notification);
public class MainActivity extends Activity {
private int i = 0;
private NotificationManager mNotificationManager;
private static final String GROUP_NAME = "com.heima.notification_type";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendNotification(View v){
//[1]獲取一個NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]創(chuàng)建一個Notification
//[2.1]需要給這個Notification對象指定icon,標題,內(nèi)容,
final Notification builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle(getString(R.string.app_name))
.setContentText("這是一個消息通知")
.setAutoCancel(true)
.setGroup(GROUP_NAME)
.build();
//[3]發(fā)送一個通知 需要指定一個Notification對象和一個id,這個id必須是唯一的
mNotificationManager.notify(i++, builder);
}
public void sendGroup(View v){
//[1]獲取一個NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]創(chuàng)建一個Notification
//[2.1]需要給這個Notification對象指定icon,標題,內(nèi)容,
final Notification builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle(getString(R.string.app_name))
.setContentText("這是一個消息通知")
.setAutoCancel(true)
.setGroup(GROUP_NAME)
.build();
//[3]發(fā)送一個通知 需要指定一個Notification對象和一個id,這個id必須是唯一的
mNotificationManager.notify(i++, builder);
//[4]創(chuàng)建一個notification組
String notificationContent = "傳智播客" + i;
final NotificationCompat.Builder builder1 = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setStyle(new NotificationCompat.BigTextStyle()
.setSummaryText(notificationContent))
.setGroup(GROUP_NAME)
.setGroupSummary(true);
final Notification notification = builder1.build();
//[5]發(fā)送這個notification組
mNotificationManager.notify(101, notification);
}
public void send(View v){
//[1]獲取一個NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]創(chuàng)建remoteInput對象,這個對象指定了這個notification的標題和一個key
String replyLabel = getResources().getString(R.string.app_name);
RemoteInput remoteInput = new RemoteInput.Builder("heima")
.setLabel(replyLabel)
.build();
//[3]創(chuàng)建一個Action對象 可以指定用戶一個友好的輸入提示吗讶,可以指定跳轉(zhuǎn)意圖,
Intent deleteIntent = new Intent(this,MainActivity.class);
Notification.Action action =
new Notification.Action.Builder(R.mipmap.ic_launcher,
"請輸入內(nèi)容", PendingIntent.getActivity(this, 10002, deleteIntent, 0))
.addRemoteInput(remoteInput)
.build();
//[3]創(chuàng)建一個Notification對象
Notification notification =
new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle("傳智播客")
.setContentText("消息通知")
.addAction(action)
.build();
//[4]發(fā)送這個notification
mNotificationManager.notify(1, notification);
}
}
http://android.xsoftlab.net/guide/topics/ui/notifiers/notifications.html#CustomNotification
http://android.xsoftlab.net/design/patterns/notifications.html
自定義Notification
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自定義的notification" />
<ProgressBar
android:id="@+id/progressBar1"
android:max="100"
android:progress="50"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
實現(xiàn)代碼
public class DemoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void click(View view){
System.out.println("haha");
//1.創(chuàng)建notification 的管理器
NotificationManager manager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
//2 .創(chuàng)建notification的實例
Notification notification = new Notification();
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.icon = R.drawable.ic_launcher;
notification.tickerText="自定義notification";
//notification.contentView;
//遠程的view 我們的view對象 是要顯示在另外一個進程里面 另外一個程序里面 所以就需要一個remote view
RemoteViews rv = new RemoteViews(getPackageName(), R.layout.custom_notification);
rv.setTextViewText(R.id.textView1, "textview 自定義notification");
rv.setProgressBar(R.id.progressBar1, 100, 50, false);
notification.contentView = rv;
Intent intent = new Intent(this,DemoActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
notification.contentIntent = pendingIntent;
manager.notify(2, notification);
}
}
源碼位置
https://github.com/JiangHaiYang01/NotificationDemo