Notification的基本用法以及使用RemoteView實現自定義佈局

Notification的做用android

Notification是一種全局效果的通知,在系統的通知欄中顯示。既然做爲通知,其基本做用有:併發

  •   顯示接收到短消息、即時信息等
  •   顯示客戶端的推送(廣告、優惠、新聞等)
  •   顯示正在進行的事物(後臺運行的程序,如音樂播放進度、下載進度)

 

Notification的基本操做:app

Notification的基本操做主要有建立、更新和取消三種。一個Notification的必要屬性有三項,若是不設置的話在運行時會拋出異常:ide

  1. 小圖標,經過setSmallIcon方法設置
  2. 標題,經過setContentTitle方法設置
  3. 內容,經過setContentText方法設置。

除了以上三項,其餘均爲可選項,不過通常而言,通知須要有交互的功能,因此通常Notification具備Action屬性,這樣就能跳轉到App的某一個Activity、啓動一個service或者發送一個Broadcast。佈局

當系統受到通知時,能夠經過震動、鈴聲、呼吸燈等多種方式進行提醒。ui

 

下面就從Notification的基本操做逐條介紹:this

  1. Notification的建立

Notification的建立過程主要涉及到Notification.Builder、Notification、NotificationManagerspa

Notification.Builder:code

         使用建造者模式構建Notification對象。因爲Notification.Builder僅支持Android4.1及以後的版本,爲了解決兼容性的問題,使用V4兼容庫中的NotifivationCompat.Builder類。對象

Notification:通知對應類,保存通知相關的數據。NotificationManager向系統發送通知時會用到。

NotificationManager:通知管理類,調用NotificationManager的notify方法能夠向系統發送通知。

獲取 NotificationManager 對象:

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

前面講到,Notification有三個必要屬性以及一個頗有必要的屬性Action。下面咱們就建立一個簡單的Notification,主要有如下三步:

  1. 獲取NotificationManager實例
  2. 實例化NotificationCompat.Builder並設置相關屬性
  3. 經過builder.build方法來生成Notification對象,併發送通知
private void sendNotification(){

    Intent intent = new Intent(this,SettingsActivity.class);

    PendingIntent mPendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);

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

    NotificationCompat.Builder builder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)

            //設置小圖標

            .setSmallIcon(R.mipmap.ic_launcher)

            //點擊後自動清除

            .setAutoCancel(true)

            //設置通知標題

            .setContentTitle("最簡單的通知")

            //設置通知內容

            .setContentText("真的很簡單很簡單很簡單")

            //設置通知的動做

            .setContentIntent(mPendingIntent)

            //設置通知時間,默認爲系統發出通知的時間

            .setWhen(System.currentTimeMillis());

            //第一個參數爲Notification的id

    notificationManager.notify(2,builder.build());

}

 

 

其中爲了實現Action屬性,咱們須要建立Intent、PendingIntent和setContentIntent()這幾步。

不難發現,其中的PendingIntent的設置纔是其中的關鍵。

 

PendingIntent支持三種待定的意圖:啓動Activity,啓動Service和發送Broadcast。對應於它的三個接口方法。

static PendingIntent

getActivity(Context context,int requestCode,Intent intent,int flags)

獲取一個PendingIntent,該意圖發生時,至關於Context.startActivity(Intent)

static PendingIntent

getService (Context context,int requestCode,Intent intent,int flags)

獲取一個PendingIntent,該意圖發生時,至關於Context.startService (Intent)

static PendingIntent

getBroadcast(Context context,int requestCode,Intent intent,int flags)

獲取一個PendingIntent,該意圖發生時,至關於Context.sendBroadcast(Intent)

其中context和intent不須要講,主要說一下requestCode和flags。其中requestCode是PendingIntent發送發的請求碼,多數狀況下設置爲0便可,requestCode會影響到flags的效果。

PendingIntent相同:Intent相同且requestCode也相同。(Intent相同須要ComponentName和intent-filter相同)

flags的常見類型有:

FLAG_ONE_SHOT:只能被使用一次,而後就會被自動cancel,若是後續還有相同的PendingIntent。那麼他們的send方法就會調用失敗。
FLAG_NO_CREATE:若是當前系統中不存在相同的PendingIntent對象,系統不會建立該PendingIntent對象,而是直接返回null。(不多使用)

FLAG_CANCEL_CURRENT:若是當前系統中已經存在一個相同的 PendingIntent 對象,那麼就將先將已有的 PendingIntent 取消,而後從新生成一個 PendingIntent 對象。

FLAG_UPDATE_CURRENT:當前描述的PendingIntent若是已經存在,那麼它們會被更新,即Intent中的Extras會被替換到最新的。

 

  1. Notification的更新

更新通知的操做很簡單,只須要再次發送一次相同ID的通知便可,若是以前的通知尚未被取消,則會直接更新該通知相關的屬性;若是以前的通知已經被取消,則會從新建立一個新的通知。

更新通知和發送通知採用一樣的方法。

 

  1. Notification的取消

取消通知的方式主要有如下5種:

  1. 點擊通知欄的清除按鈕,會清除全部可清除的通知
  2. 設置了setAutoCancel()或者設置了flags爲FLAG_AUTO_CANCEL的通知,點擊通知時會自動清除。
  3. 經過NotificationManager調用cancel(int id)來取消指定id的通知
  4. 經過NotificationManager調用cancel(String tag,int id)方法清除指定Tag和ID的通知。
  5. 經過NotificationManager調用cancelAll()清除全部該應用以前發送的通知

若是是經過NotificationManager.notify(String tag, int id, Notification notify) 方法建立的通知,那麼只能經過 NotificationManager.cancel(String tag, int id) 或cancelAll()方法才能清除對應的通知,調用NotificationManager.cancel(int id) 無效。

 

  1. Notification的通知效果

前面提到了Notification的通知效果,有了通知效果更能提醒用戶去查看Notification。

Notification的通知效果有震動、呼吸燈、鈴聲三種,能夠經過builder中的setDefaults(int defaults)方法來設置,屬性有如下四種,一旦設置了默認效果,自定義效果就會失效。

//添加默認震動效果,須要申請震動權限

//<uses-permission android:name="android.permission.VIBRATE" />

Notification.DEFAULT_VIBRATE

//添加系統默認聲音效果,設置此值後,調用setSound()設置自定義聲音無效

Notification.DEFAULT_SOUND

//添加默認呼吸燈效果,使用時須與 Notification.FLAG_SHOW_LIGHTS 結合使用,不然無效

Notification.DEFAULT_LIGHTS

//添加上述三種默認提醒效果

Notification.DEFAULT_ALL

鈴聲:

//調用系統默認響鈴,設置此屬性後setSound()會無效

//.setDefaults(Notification.DEFAULT_SOUND)

//調用系統多媒體褲內的鈴聲

//.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"));

//調用本身提供的鈴聲,位於 /res/values/raw 目錄下

.setSound(Uri.parse("android.resource://com.littlejie.notification/" + R.raw.sound))

 

震動:

long[] vibrate = new long[]{0, 500, 1000, 1500};
 

//使用系統默認的震動參數,會與自定義的衝突

//.setDefaults(Notification.DEFAULT_VIBRATE)

//自定義震動效果

.setVibrate(vibrate);

 

呼吸燈

//ledARGB 表示燈光顏色、 ledOnMS 亮持續時間、ledOffMS 暗的時間

.setLights(0xFF0000, 3000, 3000);

 

另外一種方式:

Notification notification = builder.build();

//只有在設置了標誌符Flags爲Notification.FLAG_SHOW_LIGHTS的時候,才支持呼吸燈提醒。

notify.flags = Notification.FLAG_SHOW_LIGHTS;

//設置lights參數的另外一種方式

//notify.ledARGB = 0xFF0000;

//notify.ledOnMS = 500;

//notify.ledOffMS = 5000;

還能夠經過如下幾種Flag來設置通知效果

 //提醒效果經常使用 Flag
//三色燈提醒,在使用三色燈提醒時候必須加該標誌符

        Notification.FLAG_SHOW_LIGHTS

//發起正在運行事件(活動中)

        Notification.FLAG_ONGOING_EVENT

//讓聲音、振動無限循環,直到用戶響應 (取消或者打開)

        Notification.FLAG_INSISTENT



//發起Notification後,鈴聲和震動均只執行一次

        Notification.FLAG_ONLY_ALERT_ONCE

//用戶單擊通知後自動消失

        Notification.FLAG_AUTO_CANCEL


//只有調用NotificationManager.cancel()時纔會清除

        Notification.FLAG_NO_CLEAR

//表示正在運行的服務

        Notification.FLAG_FOREGROUND_SERVICE

上面講到的Notification的佈局都是系統默認的,固然有時候處於需求,咱們可能須要自定義Notification的佈局。

那如何實現Notification的自定義佈局呢?

這裏就須要提出一個新的知識點RemoteView,望文生義,即遠程View。

RemoteView表示的是一種View結構,它能夠在其餘進程中顯示(具體來說是SystemServer進程),因爲它是在其餘進程中顯示,爲了更新它的界面,咱們不能簡單地使用普通View的那一套方法,RemoteView提供了一系列Set方法用於更新界面。

下面就是一個簡單的示例;

package com.pignet.remoteviewtest;

import android.app.Notification;

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.content.Context;

import android.content.Intent;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.RemoteViews;

public class MainActivity extends AppCompatActivity {


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Button btnNotification = (Button) findViewById(R.id.btn_notification);

        btnNotification.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                sendNotification();

            }

        });

    }

    private void sendNotification(){

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

        Notification notification =new Notification();

        notification.icon=R.mipmap.ic_launcher;

        notification.when=System.currentTimeMillis();

        notification.flags=Notification.FLAG_AUTO_CANCEL;

        //跳轉意圖

        Intent intent = new Intent(this,SettingsActivity.class);

        //創建一個RemoteView的佈局,並經過RemoteView加載這個佈局

        RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.layout_notification);

        //爲remoteView設置圖片和文本

        remoteViews.setTextViewText(R.id.message,"第一條通知");

        remoteViews.setImageViewResource(R.id.image,R.mipmap.ic_launcher_round);

        //設置PendingIntent

        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);

        //爲id爲openActivity的view設置單擊事件

        remoteViews.setOnClickPendingIntent(R.id.openActivity,pendingIntent);

        //將RemoteView做爲Notification的佈局

        notification.contentView =remoteViews;

        //將pendingIntent做爲Notification的intent,這樣當點擊其餘部分時,也能實現跳轉

        notification.contentIntent=pendingIntent;

        notificationManager.notify(1,notification);

    }

}
 

有圖:

相關文章
相關標籤/搜索