Android Notification的基本使用和點擊跳轉中的註意事項

1、Android 中通知欄的基本使用

Notification,是一種具有全局效果的通知,可以在系統的通知欄中顯示。當 APP 向系統發出通知時,它將先以圖標的形式顯示在通知欄中。用戶可以下拉通知欄查看通知的詳細信息。通知欄和抽屜式通知欄均是由系統控制,用戶可以隨時查看。
首先創建通知,需要一個NotificationManager來對通知進行管理,可以調用Context的getSystemService()方法獲取到。getSystemService()方法接收一個字符串參數用於確定獲取系統的哪個服務,這裡傳入Context.NOTIFICATION_SERVICE即可。因此,獲取NotificationManager的實例可以寫成:

 NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

由於Notification用的是建造者模式,所以接下來需要使用一個Builder構造器來創建Notification對象,由於不同版本的Android系統對通知這部分進行部分功能的修改,這裡建議使用support庫中提供的兼容Api,support-v4庫中有一個NotificationCompat類,使用這個類的構造器來創建Notification對象,就可以保證我們的程序在所有Android系統版本上都能正常工作瞭,代碼如下:

 Notification notification = new NotificationCompat.Builder(context).build();

當然上面創建的一個空的Notification對象,更常用的是我們通過一系列的鏈式操作,來對這個對象進行一些屬性的設置;
常見的使用方式如下:

public class NotificationUtils {

    /**
     * 顯示一個普通的通知
     *
     * @param context 上下文
     */
    public static void showNotification(Context context, String msgContent, int id) {

        Intent intent = new Intent(context, StuMainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra("xxxABC",true);
        Bundle bundle = new Bundle();
        bundle.putSerializable("xxxEFG", xxxEFG);
        intent.putExtras(bundle);
        Notification notification = new NotificationCompat.Builder(context)
                /**設置通知左邊的大圖標**/
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.logo))
                /**設置通知右邊的小圖標**/
                .setSmallIcon(R.mipmap.logo)
                /**通知首次出現在通知欄,帶上升動畫效果的**/
                .setTicker("應用名")
                /**設置通知的標題**/
                .setContentTitle(msgContent)
                /**設置通知的內容**/
                .setContentText(msgContent)
                /**通知產生的時間,會在通知信息裡顯示**/
                .setWhen(System.currentTimeMillis())
                /**設置該通知優先級**/
                .setPriority(Notification.PRIORITY_DEFAULT)
                /**設置這個標志當用戶單擊面板就可以讓通知將自動取消**/
                .setAutoCancel(true)
                /**設置他為一個正在進行的通知。他們通常是用來表示一個後臺任務,用戶積極參與(如播放音樂)或以某種方式正在等待,因此占用設備(如一個文件下載,同步操作,主動網絡連接)**/
                .setOngoing(false)
                /**向通知添加聲音、閃燈和振動效果的最簡單、最一致的方式是使用當前的用戶默認設置,使用defaults屬性,可以組合:Notification.DEFAULT_ALL就是3種全部提醒**/
                .setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS)
                .setContentIntent(PendingIntent.getActivity(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT))
                .build();
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        /**發起通知**/
        notificationManager.notify(id, notification);
    }
}

註意:
1、上面的這個傳瞭的一個id值,這個是用於標記通知的,表示是不同的通知。
2、setSmallIcon()方法用於設置通知的小圖標,註意隻能使用純alpha圖層的圖片來進行設置,小圖標會顯示在系統狀態欄上,setLargeIcon()方法用於設置通知的大圖標,下拉系統欄時,就可以看到大圖標瞭。
 

2、點擊通知欄跳轉

當我們要實現點擊通知欄的跳轉時,這個時候需要用到PendingIntent瞭,PendingIntent從名字上就可以看出和Intent有點類似,其實他們直接確實有不少的共同點,比如都可以指明某一個“意圖”,都可以啟動活動、服務、廣播等,不同的是Intent更加傾向於去立即執行某個獲取,而PendingIntent更加傾向於在某個合適的時機去執行某個動作。簡單點可以這麼理解,PendingIntent為延遲執行的Intent。

PendingIntent用法比較簡單,它主要提供瞭幾個靜態方法用於獲取PendingIntent的實例,可以根據需求來選擇使用getActivity()、getBroadcast()、getService()幾個方法的參數是相同的。

  //獲取一個用於啟動 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)

第一個參數是Context
第二個參數是一個標志位,用戶標記不同的pendingIntent.
第三個參數是一個Intent對象,可以通過這個對象構建出PendingIntent的“意圖”
第四個參數用戶確定PendingIntent的行為,有4個flag值供選擇.

flags: May be FLAG_ONE_SHOT,LAG_NO_CREATE,LAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens.

目前為止隻提供FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT這四個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_ONE_SHOT獲取的PendingIntent隻能使用一次,即使再次利用上面三個方法重新獲取,再使用PendingIntent也將失敗。

FLAG_NO_CREATE:if the described PendingIntent does not already exist, then simply return null instead of creating it.
利用FLAG_NO_CREAT獲取的PendingIntent,若描述的Intent不存在則返回NULL值.

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.
如果描述的PendingIntent已經存在,則在產生新的Intent之前會先取消掉當前的。你可用使用它去檢索新的Intent,如果你隻是想改變Intent中的額外數據的話。通過取消先前的Intent,可用確保隻有最新的實體可用啟動它。如果這一保證不是問題,考慮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.
最經常使用的是FLAG_UPDATE_CURRENT,因為描述的Intent有 更新的時候需要用到這個flag去更新你的描述,否則組件在下次事件發生或時間到達的時候extras永遠是第一次Intent的extras。

註意:
上面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。
此外還需要註意參數:
int requestCode : Private request code for the sender (currently not used).

PendingIntent contentIntent = PendingIntent.getActivity(context,
num, intent, PendingIntent.FLAG_UPDATE_CURRENT);

對於FLAG_UPDATE_CURRENT,如果上面的requestCode 為常量,則對於先後出現的若幹Notification,則所有對應的Intent裡面的extra被更新為最新的,就是全部同一為最後一次的。
相反,如果num每次不一樣,則裡面的Inent的數據沒被更新。
對於FLAG_CANCEL_CURRENT,則隻響應最前面的第一條Notifiacation,後面所有的不響應….

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *