標籤:android開發之監聽發出的簡訊 監聽手機發出的簡訊 cotentobserver contentprovider的資料的改
運行:預備知識:
為了監聽指定的ContentProvider的資料的改變,需要通過ContentResolver向指定Uri註冊CotentObserver監聽器。ContentResolver提供了如下方法來註冊監聽器:
publicfinal void registerContentObserver(Uriuri, boolean notifyForDescendents, ContentObserver observer)
參數:uri :該監聽器所監聽的ContentProvider的Uri。
notifyForDescendents :為false 表示精確匹配,即只匹配該Uri,為true 表示可以同時匹配其派生的Uri。
observer:ContentObserver派生的監聽器執行個體。
取消註冊監聽器:
public finalvoid unregisterContentObserver(ContentObserver observer)
功能:取消對給定Uri的觀察
參數: observer ContentObserver的衍生類別執行個體。
ContentObserver——內容觀察者,目的是觀察(捕捉)特定Uri引起的資料庫的變化,繼而做一些相應的處理,它類似於資料庫技術中的觸發器(Trigger),當ContentObserver所觀察的Uri發生變化時,便會觸發它。觸發器分為表觸發器、行觸發器,相應地ContentObserver也分為“表“ContentObserver、“行”ContentObserver,當然這是與它所監聽的Uri MIME Type有
關的。
ContentObserver類介紹:
接收回調的更改內容。必須由被添加到一個ContentObservable對象實現。
構造方法:
Public Constructors |
ContentObserver(Handler handler) onChange() will happen on the provider Handler. |
說明:所有 ContentObserver的衍生類別都需要調用該構造方法
參數:handler Handler對象。可以是主線程Handler(這時候可以更新UI 了),也可以是任何Handler對象。
常用方法:
Public Methods |
boolean |
deliverSelfNotifications() Returns true if this observer is interested in notifications for changes made through the cursor the observer is registered with. |
final void |
dispatchChange(boolean selfChange) |
void |
onChange(boolean selfChange) This method is called when a change occurs to the cursor that is being observed. |
說明:
void onChange(booleanselfChange)
功能:當觀察到的Uri發生變化時,回調該方法去處理。所有ContentObserver的衍生類別都需要重載該方法去處理邏輯。
參數:selfChange 回調後,其值一般為false,該參數意義不大(我也不懂,理解方法最重要)。
觀察特定Uri的步驟如下:
1、 建立我們特定的ContentObserver衍生類別,必須重載父類構造方法,必須重載onChange()方法去處理回調後的功能實現
2、 利用context.getContentResolover()獲得ContentResolove對象,接著調用registerContentObserver()方法去註冊內容觀察者
如://為content://sms的資料改變註冊監聽器getContentResolver().registerContentObserver(Uri.parse
("content://sms"), true,new SmsObserver(new Handler()));
3、 由於ContentObserver的生命週期不同步於Activity和Service等,因此,在不需要時,需要手動的調用unregisterContentObserver()去取消註冊。
簡訊相關許可權:<!-- 發送訊息-->
<uses-permission android:name="android.permission.SEND_SMS"/>
<!-- 閱讀訊息-->
<uses-permission android:name="android.permission.READ_SMS"/>
<!-- 寫入訊息-->
<uses-permission android:name="android.permission.WRITE_SMS" />
<!-- 接收訊息 -->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
相關的協議: content://sms/inbox 收件匣
content://sms/sent 已發送
content://sms/draft 草稿
content://sms/outbox 寄件匣
content://sms/failed 發送失敗
content://sms/queued 待發送列表
資料庫中sms相關的欄位及說明:
欄位 |
說明 |
_id |
簡訊序號,如100 |
thread_id |
對話的序號,如100,與同一個手機號互發的簡訊,其序號是相同的 |
address |
寄件者地址,即手機號,如+86138138000 |
person |
寄件者,如果寄件者在通訊錄中則為具體姓名,陌生人為null |
date |
日期,long型,如1346988516,可以對日期顯示格式進行設定 |
protocol |
協議0SMS_RPOTO簡訊,1MMS_PROTO多媒體訊息 |
read |
是否閱讀0未讀,1已讀 |
status |
簡訊狀態-1接收,0complete,64pending,128failed |
type |
簡訊類型1是接收到的,2是已發出 |
body |
簡訊具體內容 |
service_center |
簡訊服務中心號碼編號,如+8613800755500 |
應用執行個體:
package com.jph.monitorsms;import java.text.SimpleDateFormat;import java.util.Date;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.widget.TextView;import android.widget.Toast;import android.app.Activity;import android.database.ContentObserver;import android.database.Cursor;/** * Describe:</br> * 擷取使用者正在發送的簡訊 * 本執行個體通過為content://sms的資料改變註冊監聽器來 * 擷取手機正在發送的訊息。 * @author JPH * Date:2014.07.20 * */public class MonitorSms extends Activity {TextView txtView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);txtView=(TextView)findViewById(R.id.txtView);//為content://sms的資料改變註冊監聽器getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new SmsObserver(new Handler()));}//一個繼承自ContentObserver的監聽器類class SmsObserver extends ContentObserver{public SmsObserver(Handler handler) {super(handler);// TODO Auto-generated constructor stub}@Overridepublic void onChange(boolean selfChange) {// TODO Auto-generated method stub//查詢發送向箱中的簡訊Cursor cursor=getContentResolver().query(Uri.parse("content://sms/outbox"), null, null, null, null);//遍曆查詢結果擷取使用者正在發送的簡訊while (cursor.moveToNext()) {StringBuffer sb=new StringBuffer();//擷取簡訊的發送地址sb.append("發送地址:"+cursor.getString(cursor.getColumnIndex("address")));//擷取簡訊的標題sb.append("\n標題:"+cursor.getString(cursor.getColumnIndex("subject")));//擷取簡訊的內容sb.append("\n內容:"+cursor.getString(cursor.getColumnIndex("body")));//擷取簡訊的發送時間Date date=new Date(cursor.getLong(cursor.getColumnIndex("date")));//格式化以秒為單位的日期SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 hh時mm分ss秒");sb.append("\n時間:"+sdf.format(date));System.out.println("查詢到的正在發送的簡訊:"+sb.toString());Toast.makeText(MonitorSms.this, sb.toString(), Toast.LENGTH_LONG).show();txtView.setText(sb.toString());}super.onChange(selfChange);}}}
Android開發之監聽發出的簡訊