一、概念
Notification,是一種具有全局效果的通知,可以在系統(tǒng)的通知欄中顯示。當(dāng)App向系統(tǒng)發(fā)出通知時(shí),它將先以圖標(biāo)的形式顯示在通知欄中。用戶可以下拉通知欄查看通知的詳細(xì)信息。通知欄和抽屜式通知欄均是由系統(tǒng)控制,用戶可以隨時(shí)查看。
二、使用
Notification的基本操作主要有創(chuàng)建、更新、取消這三種。
一個(gè) Notification的必要屬性有三項(xiàng),如果不設(shè)置則在運(yùn)行時(shí)會(huì)拋出異常:
小圖標(biāo),通過 setSmallIcon() 方法設(shè)置;
標(biāo)題,通過 setContentTitle() 方法設(shè)置;
內(nèi)容,通過 setContentText() 方法設(shè)置。
除了以上三項(xiàng),其它均為可選項(xiàng)??梢越o Notification設(shè)置一個(gè) Action ,這樣就可以直接跳轉(zhuǎn)到App的某個(gè)Activity、啟動(dòng)一個(gè) Service或者發(fā)送一個(gè)Broadcast。當(dāng)系統(tǒng)接收到通知時(shí),可以通過震動(dòng)、響鈴、呼吸燈等多種方式進(jìn)行提醒。
1.創(chuàng)建Notification
import android.support.v4.app.NotificationCompat;
private void testNotification() {
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//獲取NotificationManager實(shí)例
NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//實(shí)例化NotificationCompat.Builde并設(shè)置相關(guān)屬性
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
//設(shè)置小圖標(biāo)
.setSmallIcon(R.mipmap.ic_launcher)
//設(shè)置通知標(biāo)題
.setContentTitle("最簡(jiǎn)單的Notification")
//設(shè)置通知內(nèi)容
.setContentText("只有小圖標(biāo)、標(biāo)題、內(nèi)容")
//設(shè)置pendingIntent
.setContentIntent(pendingIntent)
//點(diǎn)擊通知后自動(dòng)清除
.setAutoCancel(true);
//通過builder.build()方法生成Notification對(duì)象,并發(fā)送通知,id=1
notifyManager.notify(1, builder.build());
}
2.更新Notification
更新通知只需要再次發(fā)送相同ID的通知即可,如果之前的通知還未被取消,則會(huì)直接更新該通知相關(guān)的屬性,如果之前的通知已經(jīng)被取消,則會(huì)重新創(chuàng)建一個(gè)新通知。
3.取消Notification
取消通知有以下幾種方式:
1.點(diǎn)擊通知欄的清除按鈕,會(huì)清除所有可清除的通知;
2.設(shè)置了setAutoCancel()或FLAG_AUTO_CANCEL的通知,點(diǎn)擊該通知時(shí)會(huì)清除它;
3.通過NotificationManager調(diào)用cancel(int id)方法清除指定ID的通知;
4.通過NotificationManager調(diào)用cancel(String tag, int id)方法清除指定TAG和ID的通知;
5.通過NotificationManager調(diào)用cancelAll()方法清除所有該應(yīng)用之前發(fā)送的通知。
如果是通過NotificationManager.notify(String tag, int id, Notification notify)方法創(chuàng)建的通知,那么只能通過NotificationManager.cancel(String tag, int id)方法才能清除對(duì)應(yīng)的通知,調(diào)用NotificationManager.cancel(int id) 無效。
4.設(shè)置Notification的通知效果
Notification有震動(dòng)、響鈴、呼吸燈三種通知效果,可以通過setDefaults(int defualts)方法來設(shè)置。Default屬性有以下四種,一旦設(shè)置了Default效果,自定義的效果就會(huì)失效。
默認(rèn)通知效果:
//<uses-permission android:name="android.permission.VIBRATE" />
Notification.DEFAULT_VIBRATE
//添加系統(tǒng)默認(rèn)聲音效果,設(shè)置此值后,調(diào)用setSound()設(shè)置自定義聲音無效
Notification.DEFAULT_SOUND
//添加默認(rèn)呼吸燈效果,使用時(shí)須與Notification.FLAG_SHOW_LIGHTS結(jié)合使用,否則無效
Notification.DEFAULT_LIGHTS
//添加上述三種默認(rèn)提醒效果
Notification.DEFAULT_ALL
常用通知效果:
//三色燈提醒,在使用三色燈提醒時(shí)候必須加該標(biāo)志符
Notification.FLAG_SHOW_LIGHTS
//發(fā)起正在運(yùn)行事件(活動(dòng)中)
Notification.FLAG_ONGOING_EVENT
//讓聲音、振動(dòng)無限循環(huán),直到用戶響應(yīng)(取消或者打開)
Notification.FLAG_INSISTENT
//發(fā)起Notification后,鈴聲和震動(dòng)均只執(zhí)行一次
Notification.FLAG_ONLY_ALERT_ONCE
//用戶單擊通知后自動(dòng)消失
Notification.FLAG_AUTO_CANCEL
//只有調(diào)用NotificationManager.cancel()時(shí)才會(huì)清除
Notification.FLAG_NO_CLEAR
//表示正在運(yùn)行的服務(wù)
Notification.FLAG_FOREGROUND_SERVICE
設(shè)置方法:
NotificationCompat.Builder#setDefaults
NotificationCompat.Builder#setSound
NotificationCompat.Builder#setVibrate
NotificationCompat.Builder#setLights
notification.defaults
notification.sound
notification.vibrate
notification.ledARGB
notification.ledOnMS
notification.ledOffMS
notification.flags
三、適配Android 8.0通知
-
AndroidManifest.xml
<receiver android:name=".TestBroadcastReceiver"> <intent-filter> <action android:name="com.tomorrow.intent.action.test"/> </intent-filter> </receiver> -
strings.xml
<string name="one_notification">OneNotification</string> <string name="two_notification">TwoNotification</string> <string name="three_notification">ThreeNotification</string> -
NotificationChannelController
public class NotificationChannelController { public static final String CHANNEL_ID_ONE_NOTIFICATION = "CHANNEL_ID_ONE_NOTIFICATION"; public static final String CHANNEL_ID_TWO_NOTIFICATION = "CHANNEL_ID_TWO_NOTIFICATION"; public static final String CHANNEL_ID_THREE_NOTIFICATION = "CHANNEL_ID_THREE_NOTIFICATION"; @RequiresApi(api = Build.VERSION_CODES.O) private enum Channel { ONE_NOTIFICATION(CHANNEL_ID_ONE_NOTIFICATION, R.string.one_notification, NotificationManager.IMPORTANCE_LOW, true), TWO_NOTIFICATION(CHANNEL_ID_TWO_NOTIFICATION, R.string.two_notification, NotificationManager.IMPORTANCE_DEFAULT, false), THREE_NOTIFICATION(CHANNEL_ID_THREE_NOTIFICATION, R.string.three_notification, NotificationManager.IMPORTANCE_HIGH, true); private final String id; private final int nameResId; private final int importance; private final boolean showBadge; Channel(String id, @StringRes int nameResId, int importance, boolean showBadge) { this.id = id; this.nameResId = nameResId; this.importance = importance; this.showBadge = showBadge; } public String getId() { return id; } public int getNameResId() { return nameResId; } public int getImportance() { return importance; } public boolean canShowBadge() { return showBadge; } } public static void createChannels(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); List<NotificationChannel> channelList = new ArrayList<>(); for (Channel channel : Channel.values()) { NotificationChannel notificationChannel = new NotificationChannel(channel.getId(), context.getString(channel.getNameResId()), channel.getImportance()); notificationChannel.setShowBadge(channel.canShowBadge()); channelList.add(notificationChannel); } if (notificationManager != null) { notificationManager.createNotificationChannels(channelList); } } } } -
MainActivity
import android.app.PendingIntent; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationManagerCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private TestBroadcastReceiver mReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "zwm, onCreate"); //適配Android 8.0, 創(chuàng)建通知渠道 NotificationChannelController.createChannels(getApplicationContext()); Intent intent = new Intent("com.tomorrow.intent.action.test"); intent.setPackage(getPackageName()); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NotificationChannelController.CHANNEL_ID_THREE_NOTIFICATION); builder.setShowWhen(true) .setContentTitle("notification title") .setContentText("notification content") .setLargeIcon(bitmap) .setSmallIcon(R.mipmap.ic_launcher) .setStyle(new NotificationCompat.BigTextStyle().bigText("BigTextStyle content")) .setContentIntent(pendingIntent) .setAutoCancel(true); NotificationManagerCompat.from(this).notify(99, builder.build()); } } -
TestBroadcastReceiver
public class TestBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "TestBroadcastReceiver"; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "zwm, onReceive, action: " + intent.getAction()); } } -
打印日志
2020-03-26 13:26:30.397 20445-20445/com.tomorrow.architetest D/MainActivity: zwm, onCreate 2020-03-26 13:26:50.909 20445-20445/com.tomorrow.architetest D/TestBroadcastReceiver: zwm, onReceive, action: com.tomorrow.intent.action.test