Android之監聽短信變化

    通常,在系統的短信發生變化,比如有短信來了,或者要發短信的時候,系統會產生一個廣播,然後廣播出去,今天主要探討一下如何監控是否有新的短信接收到,然後如何處理。

網上有很多如下的處理:

當系統收到短信時,會發出一個action名稱爲android.provier.Telephony.SMS_RECEIVED的廣播Intent,該Intent存放了接收到的短信內容,使用名稱 “pdus”即可從Intent中獲取短信內容。

但是,經過實驗,該方法理論上雖然可以,但是實際操作非常的難。爲何?

原因在於,短信到來的廣播屬於一個有序廣播,所謂有序廣播,指的是系統在發送該廣播時,是使用sendOrderedBroadcast()   進行發送,處理方式是,優先級高的先進行處理,優先級低的後進行處理,同時,優先級高的可以中斷掉該廣播,不讓其向下傳播。所以,一般在安裝有安全類軟件的手機,安全類軟件會以最高優先級獲得該廣播,在其處理後會中斷該廣播,導致我們的程序不能夠對短信的變化做出響應。所以,上面的方法不可行,那麼怎麼樣纔可以穩定運行?這就是我今天要討論的問題。

Android爲了管理短信彩信等,都是建立在數據庫的基礎上,發送箱和接受箱都有對應的數據庫,當接受到短信時,會將接受的短信寫入數據庫,當要發送短信時,只需要將要發送的短信寫入發送數據庫就可以。同時,系統爲用戶暴漏了一個接口,就是,應用程序可以通過觀察者ContentObserver,去監聽短信數據的變化:

//註冊一個observer進行觀察
            getContentResolver().registerContentObserver(Uri.parse("content://sms"),  true, new SmsRecevier(new Handler()));  //當觀察的對象變化是調用SmsReceiver進行處理。

private class SmsRecevier extends ContentObserver{

		
		public SmsRecevier(Handler handler) {
			super(handler);

		}

		@Override
		public void onChange(boolean selfChange) {
			Cursor cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null);
			while(cursor.moveToNext()){
				StringBuilder sb = new StringBuilder();
				int isRead ;
				sb.append("id=").append(cursor.getInt(cursor.getColumnIndex("_id")));  //獲取短信的內容,關於短信數據庫中都有哪些內容,可以參考官方文檔,查看其都實現了哪些接口。
				sb.append(",address=").append(cursor.getString(cursor.getColumnIndex("address")));
				sb.append(";body=").append(cursor.getString(cursor.getColumnIndex("body")));

                sb.append(";time=").append(cursor.getLong(cursor.getColumnIndex("date")));
                isRead = cursor.getInt(cursor.getColumnIndex("read"));
                if(isRead == 0){
                	 System.out.println("sb="+sb.toString());
                }
               
			}
			
			System.out.println("sms database changed");
			super.onChange(selfChange);
		}
		
	}


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