Android 監聽簡訊2種方式:Broadcast和ContentObserver

來源:互聯網
上載者:User

標籤:android   簡訊   broadcast   contentobserver   listener   

1. 基於Broadcast接受簡訊1.1 原理Android收到簡訊後系統會發送一個android.provider.Telephony.SMS_RECEIVED廣播。把它放在Bundle(intent.Extras)中,Bundle可以理解為一個Map,簡訊採用"pdus"作為鍵,pdus應該是protocol description units的簡寫,也就是一組簡訊。Android不是一接收到簡訊就立刻發出廣播的,他會有一定的延遲,所以就有可能會有多條簡訊,所以才會用數組來存放。
1.2 實現方法一原理已經清楚,那麼實現是通過重寫BroadcastReceiver.onReceive(Context context, Intent intent)函數,關鍵代碼如下:
Bundle bundle = intent.getExtras(); Object messages[] = (Object[]) bundle.get("pdus");SmsMessage smsMessage[] = new SmsMessage[messages.length];smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);sender = smsMessage[n].getOriginatingAddress();// 擷取簡訊的寄件者  content = smsMessage[n].getMessageBody();// 擷取簡訊的內容  

完整實現為:
public class EventReceiver extends BroadcastReceiver {    private Context mContext;    private static final String TAG = "REC_TEST";    @Override    public void onReceive(Context context, Intent intent) {        Bundle bundle = intent.getExtras();        SmsMessage[] smsMessages = null;        Object[] pdus = null;        if (bundle != null) {            pdus = (Object[]) bundle.get("pdus");        }        if (pdus !=null){            smsMessages = new SmsMessage[pdus.length];            String sender = null;            String content = null;            for (int i=0; i<pdus.length; i++){                smsMessages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);                sender = smsMessages[i].getOriginatingAddress();                content = smsMessages[i].getMessageBody();                Log.v(TAG, "SMS:"+sender+content);                //ShowToast(sender + " 簡訊", R.drawable.ic_dialog_email);                Toast.makeText(context, sender + "," + content, Toast.LENGTH_LONG).show();            }//for smsMessages        }//if pdus    }}

1.3 註冊Receiver

1.3.1 靜態註冊

在AndroidManifest.xml的application裡面定義receiver並設定要接收的action。
receiver需要放在application標籤之中
        <receiver android:name=".EventReceiver">            <intent-filter>                <action android:name="android.provider.Telephony.SMS_RECEIVED" />            </intent-filter>        </receiver>

1.3.2 動態註冊
在activity裡面調用函數來註冊,和靜態內容差不多。一個形參是receiver,另一個是IntentFilter,其中裡面是要接收的action。
private BroadcastReceiver receiver;            @Override         protected void onStart() {                 super.onStart();                 receiver = new CallReceiver();                 registerReceiver(receiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));         }         @Override         protected void onStop() {                 unregisterReceiver(receiver);                 super.onStop();         } 


2. 基於ContentObserver監聽簡訊2.1 原理

原理是通過監聽簡訊資料庫,操作簡訊內容。

下面是文獻[3]對ContentObserver的介紹:

“ContentObserver——內容觀察者,目的是觀察(捕捉)特定Uri引起的資料庫的變化,繼而做一些相應的處理,它類似於資料庫技術中的觸發器(Trigger),當ContentObserver所觀察的Uri發生變化時,便會觸發它。觸發器分為表觸發器、行觸發器,相應地ContentObserver也分為“表“ContentObserver、“行”ContentObserver,當然這是與它所監聽的Uri MIME Type有關的。”

先不深究更加底層的內容,從表面上我們可以知道ContentObserver可以擷取Uri引起的資料庫的變化,簡訊的Uri為:

傳送簡訊:content://sms/outbox

接收簡訊:content://sms/inbox

知道Uri後我們就可以擷取到簡訊的內容了。


2.2 實現

實現的方法就是重載ContentObserver.onChange()方法即可

具體代碼如下:

private 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()){StringBuilder sb = new StringBuilder();sb.append("address="+cursor.getString(cursor.getColumnIndex("address")));sb.append(", body="+cursor.getString(cursor.getColumnIndex("body")));sb.append(", date="+cursor.getString(cursor.getColumnIndex("date")));Log.i("Observer", sb.toString());}cursor.close();super.onChange(selfChange);}}

2.3 註冊Listener

getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new SmsObserver(new Handler()));

3. 設定許可權要接收某些action,需要在AndroidManifest.xml裡面添加相應的許可權。
<uses-permission android:name="android.permission.RECEIVE_SMS" />

4. 參考文獻

[1] BroadCastReceiver 簡介 http://www.cnblogs.com/alwaysyouare/archive/2011/11/17/2252397.html

[2] Android電話、簡訊監聽 http://blog.163.com/[email protected]/blog/static/1032422412013112343930567/

[3] Android中內容觀察者的使用---- ContentObserver類詳解  http://www.cnblogs.com/slider/archive/2012/02/14/2351702.html

Android 監聽簡訊2種方式:Broadcast和ContentObserver

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.