Android RemoteViews的基本使用(上)之通知欄

 一,寫在前面

        這篇文章介紹Android中RemoteViews的基本使用,使用有這樣的兩個場景:通知欄,窗口小部件。下面會介紹如何實現向通知欄發送一個通知包括:系統默認樣式的通知,自定義樣式的通知;以及如何實現窗口小部件,並更新界面。值得一提的是,在開發一個應用的時候,若需要實現向通知欄發送通知,或窗口小部件,會發現我們無法直接通過findViewById來獲取控件從而更新UI,因爲這些界面根本就不在我們開發的應用裏,應用裏只有對應的xml文件。但是,可以通過使用RemoteViews來更新界面,內部實現原理是Binder機制,這樣才能跨進程的處理UI。本篇文章不對RemoteViews的源碼進行分析,只是涉及到RemoteViews的兩個使用場景,後面會碼一篇blog對RemoteViews進行源碼角度的分析,敬請期待!

二,通知欄

       在手機接收到微信消息時,手指沿着手機屏幕往下滑動,在通知欄會收到一條通知,於是通知欄就展現在我們面前了。那麼如何向通知欄發送一條通知呢?
       代碼如下:
package com.example.notificationdemo;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.RemoteViews;

public class MainActivity extends Activity {

	private NotificationManager nm;
	public static int id = 0;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
	}
	
	public void clickButton(View v) {
		switch (v.getId()) {
		//發送默認樣式的通知
		case R.id.btn1:
			Notification notification = new Notification();
			notification.icon = R.drawable.ttnkh;
			//通知到來時,在狀態欄上顯示有動畫的文字(手機廠商定製手機後,可能不顯示tickerText)
			notification.tickerText = "I am tickerText";
			//顯示時間(手機廠商也可能會修改時間展示方式)
			notification.when = System.currentTimeMillis();
			//點擊通知後,通知會消失(默認是不消失)
			notification.flags = Notification.FLAG_AUTO_CANCEL;
			
			Intent intent = new Intent(this, DemoActivity1.class);
			PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
			notification.setLatestEventInfo(this, "I am contentTitle", "I am contentText", pi);
			
			nm.notify(id, notification);
			break;
			
		//發送自定義樣式通知
		case R.id.btn2:
			Notification n = new Notification();
			n.tickerText = "我是tickerText";
			n.when = System.currentTimeMillis();
			n.icon = R.drawable.ic_launcher;
			n.flags = Notification.FLAG_AUTO_CANCEL;
			
			//點擊通知進入頁面DemoActivity1
			PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity1.class), PendingIntent.FLAG_UPDATE_CURRENT);
			n.contentIntent = pendingIntent;
			
			RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.remote_view);
			PendingIntent click_pi = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity2.class), PendingIntent.FLAG_UPDATE_CURRENT);
			//點擊圖片進入頁面DemoActivity2
			remoteViews.setOnClickPendingIntent(R.id.iv_remoteview, click_pi);
			n.contentView = remoteViews;
			
			nm.notify(id, n);
			break;

		default:
			break;
		}
	}

}
        點擊按鈕R.id.btn1,R.id.btn2分別發送默認樣式通知,發送自定義樣式通知。xml佈局文件就不再粘貼了,比較簡單,這裏主要分析點擊兩個按鈕後如何發送通知的。
發送系統默認通知步驟:
        1,獲取NotificationManager對象,一個系統服務;
        2,創建Notification對象,這裏是創建空參對象,有參亦可;
        3,設置Notification一些字段的值,例如:icon,tickerText,when,flags;
        4,調用notification.setLatestEventInfo(Context context,CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent);

點擊按鈕R.id.btn1,通知欄截圖如下:

        步驟3中字段在代碼中都有註釋,比較好理解。這裏主要說一下步驟4,:PendingInent,它是一個需要觸發的intent,這是它和普通的intent的區別。PendingInent對象獲取方式不同,觸發執行的意圖也不同,觸發後的意圖總體來說有三種:進入某一Activity,發送廣播,啓動服務,分別調用PendingIntent.getActivity(...),PendingIntent.getBroadcast(...),PendingIntent.getService(...)。調用notification.setLatestEventInfo方法,會傳入一個PendingIntent,在點擊了通知欄的通知後,會觸摸相應的意圖,可以進入一個Activity,或發送一個廣播,或啓動一個服務。如果想實現一個自定義樣式的通知,怎麼做了?

發送自定義樣式的通知步驟:
       步驟1,2,3同發送系統默認通知步驟1,2,3;
       4:獲取一個PendingIntent對象,給Notification對象的contentIntent 字段設置值:n.contentIntent = pendingIntent;
       5:創建RemoteViews對象,更新控件,設置控件點擊後觸發的意圖;
       6:給Notification對象的contentView字段設置值:n.contentView = remoteViews;
點擊按鈕R.id.btn2,通知欄截圖如下:


       分析:步驟4,n.contentIntent = pendingIntent,是設置點擊通知後觸發的意圖。
步驟5,RemoteViews構造方法中傳入兩個參數:包名,xml佈局文件。這個xml佈局文件對應如上通知中的界面,上面佈局文件比較簡單,客官忍忍,這不是本篇文章重點。

       需要注意的是:在點擊通知後,進入的是頁面DemoActivity1;點擊圖片後,進入頁面DemoActivity2,它們分別對應不同的PendingIntent。

三,另外

       如果需要更新通知的界面,就需要操作RemoteViews,調用該對象的相關方法實現,這裏不再一一講解方法,查下API還是比較好理解的。但是要注意,RemoteViews並不能操作所有的View類型,支持的View類型如下:
佈局:   LinearLayout,RelativeLayout,FrameLayout,GridLayout
控件:   AnalogClock,Button,Chronometer,ImageButton,ImageView,ProgressBar,TextView,ViewFlipper,ListView,GridView,StackView,                 AdapterViewFlipper
 注:只支持這些View,不包括其子類,以及自定義的View。

四,最後

        RemoteViews在通知欄上的使用,就是實現一個自定義界面的通知。下篇文章將討論RemoteViews的另一個使用場景-“窗口小部件”,

     這篇文章就分享到這裏啦,有疑問可以留言,亦可糾錯,亦可補充,互相學習...^_^


      






發佈了47 篇原創文章 · 獲贊 28 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章