Android 之 Notification 必須掌握知識點

code小生發表於2019-03-04

本文同步我的 CSDN 部落格
轉載請註明出處
blog.csdn.net/wufeng55/ar…

建立併傳送一個系統通知

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.mu_16jj.notificationdemo.MainActivity">
    <TextView
        android:id="@+id/tv_send_notification"
        android:layout_width="wrap_content"
        android:layout_height="35dp"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:background="@color/colorAccent"
        android:text="send notification"
        android:textSize="16sp" />
</RelativeLayout>複製程式碼

很簡單的佈局,就一個 TextView 利用其點選事件來傳送通知。

建立 Notification

private void createNotification() {
        notification = new NotificationCompat.Builder(MainActivity.this)
                .setContentTitle("Notification title")
                .setTicker("Ticker method function...")
                .setContentText("Notification content text")
                .setSubText("subtext...")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.large_icon))
                .build();
    }複製程式碼

通過 NotificationCompat.Build 來構建一個 Notification 物件,並設定一系列屬性(每個屬性對應的效果後面展示)。

傳送按鈕監聽

notificationManager.notify(1, notification);複製程式碼

這裡需要說明的是,Notification 的傳送還是由 NotificationManager 來管理的,第一個引數用來標識一個唯一的 Notification;第二個引數就是需要傳送的 Notification 物件。我們在 onCreate 方法中通過以下程式碼初始化了通知管理器物件:

notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);複製程式碼

執行效果

Android 之 Notification 必須掌握知識點
通知效果

Android 之 Notification 必須掌握知識點
屬性介紹

建立通知時的一些基本屬性就利用效果圖解釋完了,其中的 setTicker 需要真機執行才可以看到效果。
可是,這個時候我們點選這條通知後,該通知一直在系統狀態列,既沒有消失,也沒有頁面跳轉,這並不是我們想要的效果,所以下面就來實現點選通知跳轉頁面,這裡以系統提供的登入 Activity 為目的介面。

  • 實現點選跳轉介面

修改我們建立通知的方法

private void createNotification() {
        Intent intent = new Intent(this, LoginActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        notification = new NotificationCompat.Builder(MainActivity.this)
                .setContentTitle("Notification title")
                .setContentText("Notification content text")
                .setSubText("subtext...")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.large_icon))
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                .build();
    }複製程式碼

可以看到,這裡增加了一個 setContentIntent 方法,該方法接收一個 PendingIntent 引數,而獲取該例項則可以有三種途徑:getActivity(),getBroadcast(),getService();這幾個方法所接收的引數都是相同的,第一個是上下文,第二個引數一般很少使用,傳 0 即可,第三個引數便是點選通知需要跳轉的 Intent 意圖物件(LoginActivity直接使用 AS 提供的模板),第四個引數用於確定 PendingIntent 的行為,有 4 種植可選:FLAG_ONE_SHOT,FLAG_NO_CREATE,CANCEL_CURRENT 和 FLAG_UPDATE_CURRENT。

執行效果

Android 之 Notification 必須掌握知識點
pendingintent

主要常量
FLAG_CANCEL_CURRENT:如果當前系統中已經存在一個相同的 PendingIntent 物件,那麼就將先前已有的 PendingIntent 取消,然後重新生成一個 PendingIntent 物件。
FLAG_NO_CREATE:如果當前系統中不存在相同的 PendingIntent 物件,系統將不會建立該 PendingIntent 物件而是直接返回 null。
FLAG_ONE_SHOT:該 PendingIntent 只作用一次。在該 PendingIntent 物件通過send() 方法觸發過後,PendingIntent 將自動呼叫 cancel() 進行銷燬,那麼如果你再呼叫 send() 方法的話,系統將會返回一個 SendIntentException。
FLAG_UPDATE_CURRENT:如果系統中有一個和你描述的 PendingIntent 對等的PendingInent,那麼系統將使用該 PendingIntent 物件,但是會使用新的 Intent 來更新之前 PendingIntent 中的 Intent 物件資料,例如更新 Intent 中的 Extras。

PendingIntent 和 Intent
PendingIntent 是一個特殊的 Intent,主要區別是 intent 是立馬執行,PendingIntent 是待確定的 Intent。PendingIntent 的操作實際上是傳入的 intent 的操作。使用 pendingIntent 的目的主要是用於所包含的 intent 執行是否滿足某些條件。

  • 實現點選通知後,這條通知從系統狀態列消失

有兩種辦法,一種是給 Notification 設定

setAutoCancel(true)複製程式碼

另一種是通過通知管理器呼叫 cancel 方法,該方法有一個引數,就是我們前面傳送的時候設定的唯一標識。

通知,設定特效

我們常見的手機 APP 當有推送訊息或者電話之類的通知時,我們的手機 LED 燈會亮起來,而且顏色也會不一樣,有時候還會有聲音,或者震動之類的,下面就來學習這些方法,這裡我通過監聽手機鎖屏的廣播來傳送通知(效果會更好),不再使用上面的按鈕來傳送(鎖屏速度快的話效果還是可以看到的)。

建立通知程式碼

private void createNotification() {
        Intent intent = new Intent(this, LoginActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        notification = new NotificationCompat.Builder(MainActivity.this)
                .setContentTitle("Notification title")
                .setContentText("Notification content text")
                .setSubText("subtext...")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.large_icon))
                // 跳轉介面 系統狀態列通知消失
                .setContentIntent(pendingIntent)
                .setAutoCancel(true)
                // 收到通知時播放聲音並震動
                .setDefaults(NotificationCompat.DEFAULT_SOUND) // 預設通知聲音
//                .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")))
                .setVibrate(new long[]{0, 1000, 1000, 1000})
                // LED 燈顏色
                .setLights(Color.RED, 1000, 1000)
                // 根據手機的當前環境使用預設
//                .setDefaults(NotificationCompat.DEFAULT_ALL)
                .build();
    }複製程式碼

這裡的註釋已經很清楚了,需要注意的是震動是需要許可權的:

<uses-permission android:name="android.permission.VIBRATE" />複製程式碼

廣播接收器

/**
     * 監聽手機鎖屏
     */
    public class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                notificationManager.notify(1, notification);
            }
        }
    }複製程式碼

關注註冊廣播問題,請看《Android 廣播介紹以及使用示例

  1. 高階之 setStyle() 和 setPriority() 方法

    • 通知內容支援長文字

      .setStyle(new NotificationCompat.BigTextStyle().bigText("The failures and reverses which await men - and one after another sadden the brow of youth - add a dignity to the prospect of human life, which no Arcadian success would do. -- Henry David Thoreau"))複製程式碼

      執行效果

Android 之 Notification 必須掌握知識點
bigtext

  • 通知內容支援大圖片
    .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.large_icon)))複製程式碼

    執行效果

Android 之 Notification 必須掌握知識點
bigpucture

  • 通知優先順序
    通知的優先順序共有五個常量值可選:PRIORITY_DEFAULT(預設);PRIORITY_MIN 最低優先順序,系統可能在特定場景才會顯示這條通知,比如使用者下拉狀態列;PRIORITY_LOW 較低優先順序,系統可能會將這類通知縮小,或改變其顯示的順序,將其排在更重要的通知之後;PRIORITY_HIGH 表示較高優先順序,系統可能會將這類通知放大、改變其顯示的順序,將其排在靠前的位置; PRIORITY_MAX 表示最高的重要通知,這類通知必須要讓使用者立刻看到,甚至需要使用者做出響應操作。
    .setPriority(NotificationCompat.PRIORITY_MAX)複製程式碼

執行效果(PRIORITY_MAX)

Android 之 Notification 必須掌握知識點
PRIORITY_MAX

自定義佈局通知
我們在已有的介面基礎上再增加一個 TextView 用它的點選事件來傳送自定義通知,自定義通知程式碼如下:

/**
     * 建立自定義佈局通知
     */
    private void createCustomNotification() {
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
        remoteViews.setImageViewResource(R.id.iv_cus_notification, R.mipmap.ic_launcher);
        remoteViews.setTextViewText(R.id.tv_cus_notification, "Notification of Android");
        remoteViews.setTextViewText(R.id.btn_cus_notification, "Button");

        cusNotification = new NotificationCompat.Builder(MainActivity.this)
                // 切記,一定要設定,否則通知顯示不出來
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContent(remoteViews)
                .setTicker("Custom Notification")
                .setAutoCancel(true)
                .setDefaults(NotificationCompat.DEFAULT_ALL)
                .build();
    }複製程式碼

可以看到,相比系統通知的建立,這裡多了一個新的 API——RemoteViews. 我們的自定義佈局就是通過它來載入,通過它的一系列 setXXX 方法可以給我們的佈局中控制元件設定相關屬性,然後通過 Builder 的 setContent 方法將其設定上去,這樣我們的自定義通知效果就實現了。

點選事件

notificationManager.notify(2, cusNotification);複製程式碼

執行效果

Android 之 Notification 必須掌握知識點
自定義佈局通知

關於通知的自定義佈局從效果就可以看到,很簡單,這裡不貼出。

注意點
自定義通知佈局的可用高度取決於通知檢視。普通檢視佈局限制為 64 dp,擴充套件檢視佈局限制為 256 dp。
無論是系統通知還是自定義佈局通知,smallIcon 是必須設定的。


Android 之 Notification 必須掌握知識點
技術公眾號.jpg

相關文章