信息提醒之Notification,兼容全部SDK-更新中
概述
Notification與對話框、Toast無論從外觀上還是從使用方法上有本質的區別。
Notification是Android中很理想的提示方法,Notification可以在Android桌面上最上方的狀態欄顯示提示信息,還可以顯示圖像,甚至可以將控件加載到上面,而且只要用戶不清空,這些信息可以永久的保留在狀態欄,除了這些還有其他更吸引人的特性,讓我們一起發掘下吧。
本篇博文中使用的創建Notification 是通過一個兼容全部SDK的工具類創建的,因為setLatestEventInfo方法在API11中不建議使用了,而且谷歌在API23 (Android6.0)中徹底廢棄了該方法。
所以本篇博文中會提供一個創建Notification的工具類,來兼容所有額SDK版本~
NotificationUtils.java
import android.annotation.TargetApi; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.os.Build;import com.apkfuns.logutils.LogUtils;import java.lang.reflect.Method;/*** 兼容所有SDK的NotificationUtil** @author Mr.Yang on 2016-02-18 20:34.* @version 1.0* @desc*/ public class NotificationUtil {public static Notification createNotification(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {Notification notification;if (isNotificationBuilderSupported()) {LogUtils.d("isNotificationBuilderSupported");notification = buildNotificationWithBuilder(context, pendingIntent, title, text, iconId);} else {// 低于API 11 HoneycombLogUtils.d("buildNotificationPreHoneycomb");notification = buildNotificationPreHoneycomb(context, pendingIntent, title, text, iconId);}return notification;}public static boolean isNotificationBuilderSupported() {try {return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) && Class.forName("android.app.Notification.Builder") != null;} catch (ClassNotFoundException e) {return false;}}@SuppressWarnings("deprecation")private static Notification buildNotificationPreHoneycomb(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {Notification notification = new Notification(iconId, "", System.currentTimeMillis());try {// try to call "setLatestEventInfo" if availableMethod m = notification.getClass().getMethod("setLatestEventInfo", Context.class, CharSequence.class, CharSequence.class, PendingIntent.class);m.invoke(notification, context, title, text, pendingIntent);} catch (Exception e) {// do nothing}return notification;}@TargetApi(Build.VERSION_CODES.HONEYCOMB)@SuppressWarnings("deprecation")private static Notification buildNotificationWithBuilder(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {android.app.Notification.Builder builder = new android.app.Notification.Builder(context).setContentTitle(title).setContentText(text).setContentIntent(pendingIntent).setSmallIcon(iconId);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {return builder.build();} else {return builder.getNotification();}}}在狀態欄上顯示通知信息
Notification需要使用NotificationManager來管理,一般來講創建并顯示Notification需要以下5個步驟:
上述代碼中的
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, getIntent(), 0);返回一個PendingIntent對象,這個對象與一個Activity對象關聯,這個案例中與當前的Activity關聯。將Android狀態欄滑下來后,單擊Notification,就會顯示關聯的這個Activity。如果Activity已經顯示,仍然會顯示一個新的Activity,并覆蓋當前顯示的Activity。不過這些顯示的Activity都是一樣的,除了getActivity方法之外,還可以getBroacast和getService方法。 這兩個方法用于單擊Notification后發出一條廣播或者啟動一個服務。
設置默認發聲、震動、Light效果
// 使用默認的聲音notification.defaults = Notification.DEFAULT_SOUND;// 使用默認的震動 需要添加uses-permission android.permission.VIBRATEnotification.defaults = Notification.DEFAULT_VIBRATE;// 使用默認的Lightnotification.defaults = Notification.DEFAULT_LIGHTS;// 所有的都是用默認值notification.defaults = Notification.DEFAULT_ALL;注意事項:
- defaults屬性必須在調用notify方法之前調用,否則不起作用
- 設置震動效果需要在AndroidManifest.xml中添加權限
- <uses-permission android:name="android.permission.VIBRATE" />
清除指定的Notification
如果要清除某個消息可以使用NotificationManager.cancel方法,該方法只有一個參數,表示要清除的Notification的ID。
清除全部的Notification
使用cancelAll()可以清除當前NotificationManager對象中的所有的Notification。
清除Notification后觸發的善后工作
當我們將狀態欄下拉下來之后都會看到在屏幕的右上角有一個“清除“按鈕或者圖標,單擊該按鈕可以清除所有的Notification, 那么在清除后,往往需要做一些善后的工作,這個就需要通過Notification.deleteIntent來完成。
deleteIntent也需要設置一個PendingIntent類型的變量,由于在清除所有的Notification時調用,可以將這個動作和Activity、Broadcast、Service關聯。
private void notificationDeleteIntent() {// 通過getSystemservice獲取NotificationManagernotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);// PendingIntent --getAct ,getBrc ,getSev等等PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity_.class), 0);// NotificationNotification notification = NotificationUtil.createNotification(this, pendingIntent, "Title", "text", R.drawable.tag_blue);notification.when = System.currentTimeMillis();notification.tickerText = "清除Notificaiton的善后工作";// 清除通知,觸發的操作,這里將清除Notification觸發的deleteIntent設置為跳轉到ToastDemoListAct,當然了也可以啟動廣播 服務等等PendingIntent deleteIntent = PendingIntent.getActivity(this, 0, new Intent(this, ToastDemoListAct.class), 0);notification.deleteIntent = deleteIntent;notificationManager.notify(R.drawable.tag_blue, notification);}如果想響應刪除動作的Activity傳遞數據,可以利用被PendingIntent封裝的intent。例如
...... Intent intent = new Intent(this,Main.class); //傳遞數據 intent.putExtra("msg","what r u doing ?");PendingIntent pendingIntent = PendingIntent.getActivity(this,0.intent,0); .......這樣在Activity中(一般在onCreate方法中)接收解即可
String msg = getIntent().getStringExtra("msg"); .........永久存在的Notification
我們發現單擊”清除“按鈕,有些Notification并沒有被清除掉,這樣無法被清除的Notification被稱為永久Notification,這些Notification只能通過他們的程序 來清除。
實現這樣的效果很簡單,只需要設置Notification.flag即可。
/*** FLAG_SHOW_LIGHTS //控制閃光* <p/>* FLAG_ONGOING_EVENT //顯示在”正在運行的“一欄中* <p/>* FLAG_INSISTENT //重復發出聲音,直到用戶響應此通知* <p/>* FLAG_ONLY_ALERT_ONCE //標記聲音或者震動一次* <p/>* FLAG_AUTO_CANCEL //在通知欄上點擊此通知后自動清除此通知* <p/>* FLAG_NO_CLEAR //將flag設置為這個屬性那么通知欄的那個清楚按鈕就不會出現* <p/>* FLAG_FOREGROUND_SERVICE//前臺服務標記* <p/>* https://developer.android.com/intl/zh-cn/reference/android/app/Notification.html#FLAG_GROUP_SUMMARY* <p/>* FLAG_GROUP_SUMMARY* <p/>* FLAG_LOCAL_ONLY*/private void permanentNotification() {// 通過getSystemService獲取NotificationManagernotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);// PendingIntentPendingIntent pendingIntent = PendingIntent.getActivity(this, 0, getIntent(), 0);// NotificationNotification notification = NotificationUtil.createNotification(this, pendingIntent, "Title", "Content", R.drawable.face);notification.tickerText = "清除不掉的Notification";notification.when = System.currentTimeMillis();notification.flags = Notification.FLAG_NO_CLEAR;// 展示NotificationnotificationManager.notify(R.drawable.face, notification);}自定義Notification
我們可以通過Notification.contentView 來自定義Notification。
contentView 并不是一個View,而是RemoteViews類型。
RemoteView只支持有限的幾個控件和布局,如下所示
RemoteView支持的布局
- FrameLayout
- LinearLayout
- RelativeLayout
RemoteView支持的控件
- AnalogClock
- Button
- Chronometer
- ImageButton
- ImageView
- ProgressBar
- TextView
如果使用其他控件,會拋出異常。
實現步驟
activity_custom_notification.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><TextView android:id="@+id/textview"android:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center"android:text="自定義內容"android:textColor="#F00"android:textSize="20sp" /><ImageView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:src="@drawable/tag_green" /></LinearLayout> private void customNotification() {// 通過getSystemService()獲取NotificationManagernotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);//PendingIntentPendingIntent pendingIntent = PendingIntent.getActivity(this,0,getIntent(),0);// NotificationNotification notification = NotificationUtil.createNotification(this,pendingIntent,"Title","text",R.drawable.flag_mark_yellow);// 設置屬性...notification.tickerText="自定義Notification";notification.when = System.currentTimeMillis();//自定義Notification布局RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.activity_custom_notification);remoteViews.setTextViewText(R.id.textview,"666666666");notification.contentView = remoteViews ;// notifiynotificationManager.notify(R.drawable.flag_mark_yellow,notification);}運行效果
大拿總結的,可以參考
總結
以上是生活随笔為你收集整理的信息提醒之Notification,兼容全部SDK-更新中的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信息提醒之对话框(AlertDialog
- 下一篇: Translucent System B