通知欄的自定義佈局:轉:http://blog.csdn.net/vipzjyno1/article/details/25248021html
這裏要用到RemoteViews這個類。實現如下2種自定義佈局。java
Notification的自定義佈局是RemoteViews,和其餘RemoteViews同樣,在自定義視圖佈局文件中,僅支持FrameLayout、LinearLayout、RelativeLayout三種佈局控件和AnalogClock、Chronometer、Button、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView和AdapterViewFlipper這些顯示控件,不支持這些類的子類或Android提供的其餘控件。不然會引發ClassNotFoundException異常android
步驟以下:app
1)建立自定義視圖ide
2)獲取遠程視圖對象(注:Notification的contentView不能爲空)佈局
3)設置PendingIntent(來響應各類事件)post
4)發起Notification測試
大致4步驟這裏就不詳細說了,下面就把DEMO中的列子拿出來講下字體
樣式:ui
1.自定義帶按鈕通知欄(以下樣式)
正在進行的
「正在進行的」通知使用戶瞭解正在運行的後臺進程。例如,音樂播放器能夠顯示正在播放的音樂。也能夠用來顯示須要長時間處理的操做,例以下載或編碼視頻。「正在進行的」通知不能被手動刪除。
只在通知被展開時顯示
什麼時候展開:通知處在頂端,或者用戶經過收拾展開
收件箱風格的通知:
相比普通視圖,只多出:7. 詳情區域
1.NotificationCompat.BigPictureStyle 大圖片風格:詳情區域包含一個256dp高度的位圖
2.NotificationCompat.BigTextStyle 大文字風格:顯示一個大的文字塊
3.NotificationCompat.InboxStyle 收件箱風格:顯示多行文字
各類風格都具備如下常規視圖不具備的內容選項:
1.大標題:在展開視圖時替代普通視圖的標記
2.總結文字:容許你在詳情區域之下增長一行內容
(注:下面所指的低版本是指2.3及2.3如下版本)
(1)設置對應的flags,讓用戶點擊既被消除:
notification.flags = FLAG_AUTO_CANCEL;
(2) 經過手動消除某項或則所有通知
mNotificationMgr.cancle(NOTIFICATION_ID);//消除對應ID的通知
mNotificationMgr.cancleAll();//消除建立的全部通知
(1)Notification.Builder(this).getNotification()
(2)mNotification.setLatestEventInfo(this, "title", "content", null);
這些方法都已經被啓用,雖然還有效果,但是不建議使用。因此開發過程當中儘可能使用NotificationCompat.Builder(this)的構建方法去建立一個通知類。
(1)錯誤代碼:java.lang.IllegalArgumentException: contentIntent required: pkg=com.example.notifications id=100 notification=Notification(vibrate=default,sound=null,defaults=0x2,flags=0x0)
解決方案:若是在高版本不會出錯,而在2.3上面報了這個錯誤,經過開發文檔中的如下知道你能夠找打:
For this reason, you should always ensure that UI controls in a notification are also available in an Activity
in your app, and you should always start that Activity
when users click the notification. To do this, use the setContentIntent()
method.
你就應該知道,缺乏了setContentIntent()
這個方法,在2.3及更低的版本中,必須給它設置設置contentIntent,若是你點擊沒有意圖,能夠在賦值的的Intent中設置爲new Intent()既可,切記contentIntent不能爲空。
代碼以下:
(2)錯誤代碼:android.app.RemoteServiceException: Bad notification posted from package com.example.notifications: Couldn't expand RemoteViews for: StatusBarNotification(package=com.example.notifications id=101 tag=null notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x2))
解決方法:
在自定義的時候,發現了這個問題,解決:每次更新時都必須把RemoteViews給new出來才行,不能利用已有的notification.contentView直接操做!
解決方法:看其它的應用,好像在低版本都會隱藏掉那些按鈕,就是爲了避免影響用戶體驗,因此應該就這麼解決,判斷版本號在去決定是否如今按鈕。
如右圖:
解決方案:
因爲2.3及以前版本,背景設是白色的那咱們定義字體顏色爲系統預設的顏色:
?android:attr/textColorPrimary
在資源的src/values目錄中的style.xml文件中設置它標題和內容的樣式爲:
在2.3以後的版本中(即API >=9的版本中),在資源文件下的src/values-v9目錄中的style.xml文件中設置它標題和內容的樣式爲:
最後賦給自定義佈局中的對應標題和內容對應的style便可。
對應解決網址:
1.http://stackoverflow.com/questions/6250356/how-to-use-default-notification-style
2.http://stackoverflow.com/questions/4867338/custom-notification-layouts-and-text-colors/7320604#7320604
3.http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView (官方文檔)
http://developer.android.com/about/versions/android-2.2-highlights.html
解決方法:此方法在4.0及之後版本纔有用,若是爲早期版本:須要自定義通知佈局,其中包含ProgressBar視圖
2.3及2.3以前:
經過
方法賦予VIEW。
2.3以後:
經過Builder如下方法賦於自定義佈局。
mBuilder.setContent(view_custom)
這裏就不貼DEMO中的代碼了,你們能夠下個DEMO本身看,裏面也都有註釋的,可能有的地方會有錯誤,忘你們指出,以便及時修改,謝謝。
一個DEMO讓你更懂Notification
轉:http://www.cnblogs.com/zenfly/archive/2012/02/09/2343923.html
Android支持Toast和NotificationManager兩種通知方式,前者至關於一個定時關閉的對話框,後者是在狀態欄上顯示一條消息。Toast和Notification均可以隨時取消。
Toast
A toast is a view containing a quick little message for the user. The toast class helps you create and show those. Toast的使用很簡單:
Toast.makeText(this, "Service destroyed…", Toast.LENGTH_LONG).show();
NotificationManager
NotificationManager負責通知用戶事件的發生。
NotificationManager有三個公共方法:
1. cancel(int id) 取消之前顯示的一個通知.假如是一個短暫的通知,試圖將隱藏,假如是一個持久的通知,將從狀態條中移走.
2. cancelAll() 取消之前顯示的全部通知。
3. notify(int id, Notification notification) 把通知持久的發送到狀態條上.
//初始化NotificationManager:
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification表明着一個通知.
Notification的屬性:
audioStreamType 當聲音響起時,所用的音頻流的類型
contentIntent 當通知條目被點擊,就執行這個被設置的Intent.
contentView 當通知被顯示在狀態條上的時候,同時這個被設置的視圖被顯示.
defaults 指定哪一個值要被設置成默認的.
deleteIntent 當用戶點擊"Clear All Notifications"按鈕區刪除全部的通知的時候,這個被設置的Intent被執行.
icon 狀態條所用的圖片.
iconLevel 假如狀態條的圖片有幾個級別,就設置這裏.
ledARGB LED燈的顏色.
ledOffMS LED關閉時的閃光時間(以毫秒計算)
ledOnMS LED開始時的閃光時間(以毫秒計算)
number 這個通知表明事件的號碼
sound 通知的聲音
tickerText 通知被顯示在狀態條時,所顯示的信息
vibrate 振動模式.
when 通知的時間戳.
Notification的公共方法:
describeContents() Describe the kinds of special objects contained in this Parcelable's marshalled representation.
setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) 設置Notification留言條的參數
writeToParcel(Parcel parcel, int flags) Flatten this notification from a parcel.
toString() …………….
將Notification發送到狀態條上:
Notification notification = new Notification(R.drawable.icon, "Service started", System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Main.class), 0);
// must set this for content view, or will throw a exception
notification.setLatestEventInfo(this, "Test Service", "Service started", contentIntent);
nm.notify(R.string.hello, notification);
Notification的取消
nm.cancel(R.string.hello);
完整代碼實現
public static void addNotificaction(String pId,String pTtitle,String pContent) {
NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// 建立一個Notification
Notification notification = new Notification();
// 設置顯示在手機最上邊的狀態欄的圖標
notification.icon = R.drawable.icon;
// 噹噹前的notification被放到狀態欄上的時候,提示內容
notification.tickerText = pTtitle;
/***
* notification.contentIntent:一個PendingIntent對象,當用戶點擊了狀態欄上的圖標時,該Intent會被觸發
* notification.contentView:咱們能夠不在狀態欄放圖標而是放一個view
* notification.deleteIntent 噹噹前notification被移除時執行的intent
* notification.vibrate 當手機震動時,震動週期設置
*/
// 添加聲音提示
notification.defaults=Notification.DEFAULT_SOUND;
// audioStreamType的值必須AudioManager中的值,表明着響鈴的模式
notification.audioStreamType= android.media.AudioManager.ADJUST_LOWER;
//下邊的兩個方式能夠添加音樂
//notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");
//notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
Intent intent = new Intent(this, AndroidMain.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
// 點擊狀態欄的圖標出現的提示信息設置
notification.setLatestEventInfo(this, pTtitle, pContent, pendingIntent);
manager.notify(id, notification);
}
Pendingintent傳值問題
pendingintent傳值常常獲取到的值是第一次的值或者null,這個跟第二個參數和最後一個參數選擇有關係。
PendingIntent pendingIntent = PendingIntent.getActivity(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
注:若是所要啓動的Activity是單例模式,其傳值方法請看onNewIntent調用時機
總結一下pendingIntent的經常使用FLAG標籤:
FLAG_ONE_SHOT:this PendingIntent can only be used once. If set, after send() is called on it, it will be automatically canceled for you and any future attempt to send through it will fail.
FLAG_NO_CREATE:if the described PendingIntent does not already exist, then simply return null instead of creating it.
FLAG_CANCEL_CURRENT:if the described PendingIntent already exists, the current one is canceled before generating a new one. You can use this to retrieve a new PendingIntent when you are only changing the extra data in the Intent; by canceling the previous pending intent, this ensures that only entities given the new data will be able to launch it. If this assurance is not an issue, consider FLAG_UPDATE_CURRENT.
FLAG_UPDATE_CURRENT: if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.
上面4個flag中最常用的是FLAG_UPDATE_CURRENT,由於描述的Intent有更新的時候須要用到這個flag去更新你的描述,不然組件在下次事件發生或時間到達的時候extras永遠是第一次Intent的extras。使用FLAG_CANCEL_CURRENT也能作到更新extras,只不過是先把前面的extras清除,另外FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT的區別在於可否新new一個Intent,FLAG_UPDATE_CURRENT可以新new一個Intent,而FLAG_CANCEL_CURRENT則不能,只能使用第一次的Intent。另外兩flag就比較少用,利用FLAG_ONE_SHOT獲取的PendingIntent只能使用一次,再使用PendingIntent也將失敗,利用FLAG_NO_CREAT獲取的PendingIntent若描述的Intent不存在則返回NULL值.