Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android通知Notification詳解

Android通知Notification詳解

編輯:關於Android編程

Notification的使用大體步驟:

1、 獲取狀態通知欄管理
2、 實例化通知欄構造器
3、 設置NotificationCompat.Builder
4、 設置PendingIntent
5、 顯示

因為Android的快速發展,而Android的版本也快速的升級導致了一些兼容性的問題。對於Notification而言,Android3.0是一個分水嶺,在其之前構建Notification推薦使用NotificationCompate.Builder,是一個Android向下版本的兼容包,而在Android3.0之後,一般推薦使用Notification.Builder構建。本博客主要介紹的是Android4.x的開發,所以在這裡使用Notification.Builder進行講解演示。

雖然通知中提供了各種屬性的設置,但是一個通知對象,有幾個屬性是必須要設置的,其他的屬性均是可選的,必須設置的屬性如下:
1)、小圖標,使用setSamllIcon()方法設置。
2)、標題,使用setContentTitle()方法設置。
3)、文本內容,使用setContentText()方法設置。

Notification簡介

Notification有兩種視覺風格,一種是標准視圖(Normal View)、一種是大視圖(Big view)。標准視圖在Android中各版本是通用的,但是對於大視圖而言,僅支持Android4.1+的版本。
Notification.flags屬性參數:(是否可以設置多個):
從官方文檔了解到,一個標准視圖顯示的大小保持在64dp高。如下圖所示:
這裡寫圖片描述seo8YnIgLz4NCjahoiDNqNaqyrG85KOs0ruw486qz7XNs8qxvOSjrNKyv8nS1Mq508NzZXRXaGVuKCnJ6NbDoaM8L3A+DQo8cD62+LbU09q088rTzbyjqEJpZyBWaWV3o6m2+NHUo6zL/LXEz7i92sf40/LWu8Tcz9TKvjI1NmRwuN+2yLXExNrI3aOssqLH0ta7ttRBbmRyb2lkNC4xK9auuvO1xMnosbiyxdans9ajrMv8scix6te8ytPNvLK70rvR+bXEtdi3vaOsvvnQ6NKqyrnTw3NldFN0eWxlKCm3vbeoyei2qKOsy/y089bCtcTQp7n7yOfPwqO6PGJyIC8+DQo8aW1nIGFsdD0="這裡寫圖片描述" src="/uploadfile/Collfiles/20160621/20160621091021833.png" title="\" />
Android為我們提供了三個實現類,用於顯示不同的場景。分別是:
Notification.BigPictureStyle, 在細節部分顯示一個256dp高度的位圖。
Notification.BigTextStyle,在細節部分顯示一個大的文本塊。
Notification.InboxStyle,在細節部分顯示一段行文本

Notification.FLAG_SHOW_LIGHTS //三色燈提醒,在使用三色燈提醒時候必須加該標志符
Notification.FLAG_ONGOING_EVENT //發起正在運行事件(活動中)
Notification.FLAG_INSISTENT //讓聲音、振動無限循環,直到用戶響應 (取消或者打開)
Notification.FLAG_ONLY_ALERT_ONCE //發起Notification後,鈴聲和震動均只執行一次
Notification.FLAG_AUTO_CANCEL //用戶單擊通知後自動消失
Notification.FLAG_NO_CLEAR //只有全部清除時,Notification才會清除 ,不清楚該通知(QQ的通知無法清除,就是用的這個。還有百度通知欄裡面的搜索框也是這個)。
使用方法:在設置完屬性後,設置
Notification notification = builder.build();
notification.flags = Notification.FLAG_ONLY_ALERT_ONCE;<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMiBpZD0="pendingintent簡介">PendingIntent簡介

對於一個通知而言,它顯示的消息是有限的,一般僅用於提示一些概要信息。但是一般簡短的消息,並不能表達需要告訴用戶的全部內容,所以需要綁定一個意圖,當用戶點擊通知的時候,調用一個意圖展示出一個Activity用來顯示詳細的內容。而Notification中,並不使用常規的Intent去傳遞一個意圖,而是使用PendingIntent。
先來說說Intent和PendingIntent的區別,PendingIntent可以看做是對Intent的包裝,通過名稱可以看出PendingIntent用於處理即將發生的意圖,而Intent用來用來處理馬上發生的意圖。而對於通知來說,它是一系統級的全局通知,並不確定這個意圖被執行的時間。當在應用外部執行PendingIntent時,因為它保存了觸發應用的Context,使得外部應用可以如在當前應用中一樣,執行PendingIntent裡的Intent,就算執行的時候響應通知的應用已經被銷毀了,也可以通過存在PendingIntent裡的Context照常執行它,並且還可以處理Intent說帶來的額外信息。
PendingInteng.getBroadcast(contex, requestCode, intent, flags)
PendingInteng.getService(contex, requestCode, intent, flags)
PendingInteng.getActivity(contex, requestCode, intent, flags)
PendingInteng.getActivities(contex, requestCode, intent, flags)
其中flags屬性參數:
FLAG_ONE_SHOT 表示返回的PendingIntent僅能執行一次,執行完後自動消失
FLAG_NO_CREATE 表示如果描述的PendingIntent不存在,並不創建相應的PendingIntent,而是返回NULL
FLAG_CANCEL_CURRENT 表示相應的PendingIntent已經存在,則取消前者,然後創建新的PendingIntent
FLAG_UPDATE_CURRENT 表示更新的PendingIntent,如果構建的PendingIntent已經存在,則替換它,常用。

使用RemoteViews自定義Notification

需要使用RemoteViews.RemoteViews描述了一個視圖層次的結構,可以顯示在另一個進程。RemoteViews提供了多個構造函數,一般使用RemoteViews(String packageName,int layoutId)。第一個參數為包的名稱,第二個為layout資源的Id。當獲取到RemoteViews對象之後,可以使用它的一系列setXxx()方法通過控件的Id設置控件的屬性。最後使用NotificationCompat.Builder.setContent(RemoteViews)方法設置它到一個Notification中。
remoteViews.setOnClickPendingIntent(viewId, pendingIntent);可以進入不同的Activity。如:
remoteViews.setOnClickPendingIntent(R.id.titleTV, PendingIntent.getActivity(context, 0,
new Intent(context, ScrollingActivity.class), PendingIntent.FLAG_UPDATE_CURRENT));

更新與移除通知

在使用NotificationManager.notify()發送通知的時候,需要傳遞一個標識符,用於唯一標識這個通知。對於有些場景,並不是無限的添加新的通知,有時候需要更新原有通知的信息,這個時候可以重寫構建Notification,而使用與之前通知相同標識符來發送通知,這個時候舊的通知就被被新的通知所取代,起到更新通知的效果。
對於一個通知,當展示在狀態欄之後,但是使用過後,如何取消呢?Android為我們提供兩種方式移除通知,一種是Notification自己維護,使用setAutoCancel()方法設置是否維護,傳遞一個boolean類型的數據。另外一種方式使用NotificationManager通知管理器對象來維護,它通過notify()發送通知的時候,指定的通知標識Id來操作通知,可以使用cancel(int)來移除一個指定的通知,也可以使用cancelAll()移除所有的通知。
使用NotificationManager移除指定通知示例:

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(0);

設定提示響應

對於有些通知,需要調用一些設備的資源,使用戶能更快的發現有新通知,一般可設定的響應有:鈴聲、閃光燈、震動。對於這三個屬性,NotificationCompat.Builder提供了三個方法設定:
setSound(Uri sound):設定一個鈴聲,用於在通知的時候響應。傳遞一個Uri的參數,格式為“file:///mnt/sdcard/Xxx.mp3”。
setLights(int argb, int onMs, int offMs):設定前置LED燈的閃爍速率,持續毫秒數,停頓毫秒數。
setVibrate(long[] pattern):設定震動的模式,以一個long數組保存毫秒級間隔的震動。
大多數時候,我們並不需要設定一個特定的響應效果,只需要遵照用戶設備上系統通知的效果即可,那麼可以使用setDefaults(int)方法設定默認響應參數,在Notification中,對它的參數使用常量定義了,我們只需使用即可:
DEFAULT_ALL:鈴聲、閃光、震動均系統默認。
DEFAULT_SOUND:系統默認鈴聲。
DEFAULT_VIBRATE:系統默認震動。
DEFAULT_LIGHTS:系統默認閃光。
設置震動,需要權限:android.permission.VIBRATE
設置閃光燈,需要權限:android.permission.FLASHLIGHT

附錄

下面是我封裝的一個通知工具類:

package com.test.testandroid;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.widget.RemoteViews;

/**
 * Created by Administrator on 2016-6-19.
 * notification builder android
 */
public class NotificationUtil {
    private Context context;
    private NotificationManager notificationManager;
    public NotificationUtil(Context context) {
        this.context = context;
        notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    /**
     * 普通的Notification
     */
    public void postNotification() {
        Notification.Builder builder = new Notification.Builder(context);
        Intent intent = new Intent(context, MainActivity.class);  //需要跳轉指定的頁面
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pendingIntent);
        builder.setSmallIcon(R.mipmap.ic_launcher);// 設置圖標
        builder.setContentTitle("標題");// 設置通知的標題
        builder.setContentText("內容");// 設置通知的內容
        builder.setWhen(System.currentTimeMillis());// 設置通知來到的時間
        builder.setAutoCancel(true); //自己維護通知的消失
        builder.setTicker("new message");// 第一次提示消失的時候顯示在通知欄上的
        builder.setOngoing(true);
        builder.setNumber(20);

        Notification notification = builder.build();
        notification.flags = Notification.FLAG_NO_CLEAR;  //只有全部清除時,Notification才會清除
        notificationManager.notify(0,notification);
    }

    /**
     * 使用下載的Notification,在4.0以後才能使用<p></p>
     * Notification.Builder類中提供一個setProgress(int max,int progress,boolean indeterminate)方法用於設置進度條,
     * max用於設定進度的最大數,progress用於設定當前的進度,indeterminate用於設定是否是一個確定進度的進度條。
     * 通過indeterminate的設置,可以實現兩種不同樣式的進度條,一種是有進度刻度的(true),一種是循環流動的(false)。
     */
    public void postDownloadNotification() {
        final Notification.Builder builder = new Notification.Builder(context);
        builder.setSmallIcon(R.mipmap.ic_launcher)
                .setTicker("showProgressBar").setContentInfo("contentInfo")
                .setOngoing(true).setContentTitle("ContentTitle")
                .setContentText("ContentText");
        // 模擬下載過程
        new Thread(new Runnable() {
            @Override
            public void run() {
                int progress ;
                for (progress = 0; progress < 100; progress += 5) {
                    // 將setProgress的第三個參數設為true即可顯示為無明確進度的進度條樣式
                    builder.setProgress(100, progress, false);
                    notificationManager.notify(0, builder.build());
                    try {
                        Thread.sleep(1 * 1000);
                    } catch (InterruptedException e) {
                        System.out.println("sleep failure");
                    }
                }
                builder.setContentTitle("Download complete")
                        .setProgress(0, 0, false).setOngoing(false);
                notificationManager.notify(0, builder.build());
            }
        }).start();
    }

    /**
     * 大視圖通知在4.1以後才能使用,BigTextStyle<p></p>
     * ****************************************************<p></p>
     * Helper class for generating large-format notifications that include a lot of text.
     *
     * Here's how you'd set the <code>BigTextStyle</code> on a notification:
     * <pre class="prettyprint">
     * Notification notif = new Notification.Builder(mContext)
     *     .setContentTitle(&quot;New mail from &quot; + sender.toString())
     *     .setContentText(subject)
     *     .setSmallIcon(R.drawable.new_mail)
     *     .setLargeIcon(aBitmap)
     *     .setStyle(new Notification.BigTextStyle()
     *         .bigText(aVeryLongString))
     *     .build();
     * </pre>
     *
     * @see Notification#bigContentView
     */
    public void postBigTextNotification() {
        Notification.BigTextStyle textStyle = new Notification.BigTextStyle();
        textStyle.setBigContentTitle("大標題")
                // 標題
                .setSummaryText("SummaryText")
                .bigText("Helper class for generating large-format notifications" +
                        " that include a lot of text;  !!!!!!!!!!!" +
                        "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        Notification.Builder builder2 = new Notification.Builder(
                context);
        builder2.setSmallIcon(R.mipmap.ic_launcher);// 小圖標
        // 大圖標
        builder2.setLargeIcon(BitmapFactory.decodeResource(
                context.getResources(), R.mipmap.ic_launcher));  //R.mipmap.close
        builder2.setTicker("showBigView_Text")
                .setContentInfo("contentInfo");
        builder2.setStyle(textStyle);
        builder2.setAutoCancel(true);

        notificationManager.notify(0, builder2.build());
    }

    /**
     * 大布局通知在4.1以後才能使用,大布局圖片
     */
    public void postBigPictureNotification() {
        Notification.BigPictureStyle bigPictureStyle = new Notification.BigPictureStyle();
        bigPictureStyle.bigPicture(BitmapFactory.decodeResource(context.getResources(),
                R.mipmap.ic_launcher));  //R.drawable.back

        Notification.Builder builder = new Notification.Builder(
                context);
        builder.setSmallIcon(R.mipmap.ic_launcher);// 小圖標
        // 大圖標
        builder.setLargeIcon(BitmapFactory.decodeResource(
                context.getResources(), R.drawable.ic_stop));
        builder.setTicker("showBigView_Picture")
                .setContentInfo("contentInfo");
        builder.setStyle(bigPictureStyle);
        builder.setAutoCancel(true);

        notificationManager.notify(0, builder.build());
    }

    /**
     * 大布局通知在4.1以後才能使用,InboxStyle
     */
    public void postInboxNotification() {
        Notification.InboxStyle inboxStyle = new Notification.InboxStyle();
        inboxStyle.setBigContentTitle("InboxStyle");
        inboxStyle.setSummaryText("Test");
        for(int i = 0 ; i < 10; i++){
            inboxStyle.addLine("new:" + i);
        }

        Notification.Builder builder5 = new Notification.Builder(
                context);
        builder5.setSmallIcon(R.mipmap.ic_launcher);// 小圖標
        // 大圖標
        builder5.setLargeIcon(BitmapFactory.decodeResource(
                context.getResources(), R.drawable.ic_stop));
        builder5.setTicker("showBigView_InboxStyle")
                .setContentInfo("contentInfo");
        builder5.setStyle(inboxStyle);
        builder5.setAutoCancel(true);

        notificationManager.notify(0, builder5.build());
    }

    /**
     * 自定義通知<p></p>
     *
     * 不設置notification.contentIntent = pendingIntent;則報如下異常:
     * android.app.RemoteServiceException:
     * Bad notification posted from package com.test.testandroid: Couldn't expand RemoteViews for: StatusBarNotification(
     * pkg=com.test.testandroid user=UserHandle{0} id=0 tag=null score=0 key=0|com.test.testandroid|0|null|10168|0: Notification
     * (pri=0 contentView=com.test.testandroid/0x7f040038 vibrate=null sound=null defaults=0x0 flags=0x10 color=0xff00aeff vis=PRIVATE))
     */
    public void postCustomNotification() {
        RemoteViews contentViews = new RemoteViews(context.getPackageName(),
                R.layout.mynotification);
        contentViews.setImageViewResource(R.id.imageNotifi,R.mipmap.ic_launcher);
        contentViews.setTextViewText(R.id.titleTV,"自定義通知標題");
        contentViews.setTextViewText(R.id.textTV,"自定義通知內容");
        Intent intent = new Intent(context, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        Notification.Builder builder = new Notification.Builder(context);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentTitle("custom notification");
        builder.setContentText("custom test");
        builder.setTicker("custom ticker");
        builder.setAutoCancel(true);
        builder.setContentIntent(pendingIntent);  //
        builder.setContent(contentViews);

        Notification notification = builder.build();
        notification.contentIntent = pendingIntent;
        notificationManager.notify(0,builder.build());
    }

    public void cancelById() {
        notificationManager.cancel(0);  //對應NotificationManager.notify(id,notification);第一個參數
    }

    public void cancelAllNotification() {
        notificationManager.cancelAll();
    }
}

使用方法:

CustomNotification customNotification = new CustomNotification(this);
//        customNotification.postNotification();
//        customNotification.postDownloadNotification();
//        customNotification.postBigTextNotification();
//        customNotification.postBigPictureNotification();
        customNotification.postInboxNotification();

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved