android手機短信攔截的實現【精華轉載】

以前剛開始接觸android時對諸如短信攔截之類的功能很感興趣,網上很多文章都介紹了使用廣播接收android.provider.Telephony.SMS_RECEIVED的動作,從而接收到SMS信息,不過當時也不知道怎麼樣把這個廣播刪掉,從而實現一個類似短信黑名單的功能。後來在網上看到可以使用abortBroadcast來屏蔽廣播,我測試了一下,可行。


先上源碼:


AndroidManifest.xml的代碼:



<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

     package="com.study.sms"

     android:versionCode="1"

     android:versionName="1.0">

   <application android:icon="@drawable/icon" android:label="@string/app_name">

<receiver android:name=".smsReceiver">

<intent-filter android:priority="1000">

<action android:name="android.provider.Telephony.SMS_RECEIVED"/>

</intent-filter>

</receiver>

   </application>

<uses-permission android:name="android.permission.RECEIVE_SMS">

</uses-permission>

</manifest>




smsReceiver的代碼:



package com.study.sms;


import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.telephony.SmsMessage;


public class smsReceiver extends BroadcastReceiver {

public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (SMS_RECEIVED_ACTION.equals(action)){

Bundle bundle = intent.getExtras();

if (bundle != null){

Object[] pdus = (Object[])bundle.get("pdus");

for (Object pdu : pdus){

SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);

String sender = message.getOriginatingAddress();

if ("5556".equals(sender)){

//屏蔽手機號爲5556的短信,這裏還可以時行一些處理,如把這個信息發送到第三人的手機等等。

abortBroadcast();

}

}

}

}

}


}


測試的效果圖:




使用5556給5554發送短信,5554無法收到。同時再起一個5558的avd給5554發送短信,一切正常。


之所以這個程序能實現屏蔽系統短信的功能,是因爲廣播有兩種不同的類型:普通廣播(normal broadcasts)和有序廣播(ordered broadcasts)。普通廣播是完全異步的,可以被所有的接收者接收到,並且接收者無法終止廣播的傳播。然而有序廣播是按照接收者聲明的優先級別,被接收者依次接收到。優先級別聲明在 intent-filter 元素的android:priority 屬性中,數越大優先級別越高,取值範圍:-1000到1000,優先級別也可以調用IntentFilter對象的setPriority()進行設置。有序廣播的接收者可以終止廣播Intent的傳播,廣播Intent的傳播一旦終止,後面的接收者就無法接收到廣播。上面的實例就是將smsReceiver的優先級設爲1000。




Context.sendBroadcast()

發送的是普通廣播,所有訂閱者都有機會獲得並進行處理。

Context.sendOrderedBroadcast()

發送的是有序廣播,系統會根據接收者聲明的優先級別按順序逐個執行接收者。


我查看了一下系統發送android.provider.Telephony.SMS_RECEIVED廣播的源碼SMSDispatcher.java(frameworks/base/telephony/java/com/android/internal/telephony),證實其發送的是有序廣播。


   protected void dispatchPdus(byte[][] pdus) {

       Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);

       intent.putExtra("pdus", pdus);

       dispatch(intent, "android.permission.RECEIVE_SMS");

   }

  public void dispatch(Intent intent, String permission) {        // Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any        // receivers time to take their own wake locks.        mWakeLock.acquire(WAKE_LOCK_TIMEOUT);        mContext.sendOrderedBroadcast(intent, permission, mResultReceiver,                this, Activity.RESULT_OK, null, null);    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章