系統中的廣播
在Android系統中,內置了很多Action產量,在觸發這些Action的時候,均會發布相應的Broadcast。一般而言,查看Android的API文檔中,關於Intent的說明即可找到對應Action的Broadcast,但是列舉的還不是很全,最好還是下載Android的源代碼,通過查看源代碼的方式查看需要攔截的Broadcast。
下面列舉一些常用的廣播:
下面通過兩個例子,來講解如何在Android下,攔截系統Broadcast並對其進行處理。
通過關鍵字攔截短信
從上面列舉的一些動作會發布的Broadcast,可以找到,當系統接收到一條短信的時候,會發布一個“android.provider.Telephony.SMS_RECEIVED”的Broadcast,之前已經介紹過了,一般系統Broadcast都是有序廣播,如果不被高優先級的BroadcastReceiver停止傳遞,會按照優先級順序傳遞下去。
而在這個示例中,通過監聽接收短信的廣播,當其內容有黑名單中的關鍵字的話,則阻止Broadcast繼續傳播,並使用Toast提示,否則正常提示短信信息。
通過上一篇博客了解到,onReceive方法的Intent參數包含了這條廣播傳遞的參數,對於短信信息而言,需要獲取key為"pdus"的數組,取出數組中每一項,它的每一項代表了一個byte[]格式的短信,需要使用SmsMessage類解析短信內容。
當然,攔截短信的Broadcast侵犯了隱私,需要注冊接收短信的權限:
1 <uses-permission android:name="android.permission.RECEIVE_SMS"/>
下面直接展示源代碼了,關鍵注釋已經寫的很清楚了,這裡不再累述:
MessageBroadcast.java:
1 package cn.bgxt.Broadcastdemo.MessageWarn; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 import android.content.BroadcastReceiver; 6 import android.content.Context; 7 import android.content.Intent; 8 import android.os.Bundle; 9 import android.telephony.SmsMessage; 10 import android.widget.Toast; 11 12 public class MessageBroadcast extends BroadcastReceiver { 13 // 在模擬器上,通過DDMS發送短信會產生亂碼,所以使用拼音代替 14 //在真機上不存在亂碼的問題 15 private final String[] blackKeyWord = new String[] { "baoxian", "chuxiao", 16 "jiangjia" }; 17 18 @Override 19 public void onReceive(Context context, Intent intent) { 20 // 判斷當前接收到的Broadcast是否是收到短信的action 21 if (intent.getAction() 22 .equals("android.provider.Telephony.SMS_RECEIVED")) { 23 StringBuilder sb = new StringBuilder(); 24 // 獲取Broadcast傳遞的數據 25 Bundle bundle = intent.getExtras(); 26 if (bundle != null) { 27 Object[] pdus = (Object[]) bundle.get("pdus"); 28 for (Object p : pdus) { 29 byte[] pud = (byte[]) p; 30 // 聲明一個SmsMessage,用於解析短信的byte[]數組 31 SmsMessage message = SmsMessage.createFromPdu(pud); 32 boolean flag = false; 33 for (String str : blackKeyWord) { 34 if (message.getMessageBody().contains(str) ) { 35 // 發現黑名單關鍵字,則標記為true 36 flag = true; 37 break; 38 } 39 } 40 if (flag) { 41 sb.append("發件人:n"); 42 sb.append(message.getOriginatingAddress()); 43 sb.append("n發送時間:n"); 44 Date date = new Date(message.getTimestampMillis()); 45 SimpleDateFormat format = new SimpleDateFormat( 46 "yyyy-MM-dd HH:mm:ss"); 47 sb.append(format.format(date)); 48 sb.append("n短信內容:n"); 49 sb.append(message.getMessageBody()); 50 51 Toast.makeText(context, sb.toString(), 52 Toast.LENGTH_SHORT).show(); 53 // 如果存在黑名單關鍵字內容,停止Broadcast傳播 54 abortBroadcast(); 55 } 56 57 } 58 } 59 } 60 61 } 62 63 }
在AndroidManifest.xml中配置Receiver。
1 <receiver android:name="cn.bgxt.Broadcastdemo.MessageWarn.MessageBroadcast"> 2 <!-- 設置優先級,短信優先級為0,大於0即可 --> 3 <intent-filter android:priority="200"> 4 <action android:name="android.provider.Telephony.SMS_RECEIVED"/> 5 </intent-filter> 6 </receiver>
效果展示,先發送一個包含黑名單中關鍵字的短信,再發送一個正常的短信。
IP撥號
再來看看IP撥號的示例,在Android中,如果觸發撥打電話的Action,則會發布一個"android.intent.action.NEW_OUTGOING_CALL"的Broadcast出來,只需要針對它進行攔截即可,然後在加上IP前綴,把處理過的號碼添加到數據傳遞給下一個Receiver。
處理接收撥打電話的Broadcast,需要對Android增加權限:
1 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
下面直接上代碼了,注釋寫的很清楚,這裡不再累述了。
IpCallPhone.java:
1 package cn.bgxt.Broadcastdemo.IpCall; 2 3 import android.content.BroadcastReceiver; 4 import android.content.Context; 5 import android.content.Intent; 6 7 public class IpCallPhone extends BroadcastReceiver { 8 private final String STARTS="17951"; 9 @Override 10 public void onReceive(Context context, Intent intent) { 11 // 獲取當前撥號的號碼 12 String number=getResultData(); 13 // 此號碼沒有被加IP撥號的前綴 14 if(!number.startsWith(STARTS)){ 15 // 設置加了IP號碼的號碼 16 String newnumber=STARTS+number; 17 // 把新號碼增加到返回結果數據中,用於傳遞給後面的Receiver 18 setResultData(newnumber); 19 } 20 } 21 }
AndroidManifest.xml配置Receiver:
1 <receiver android:name="cn.bgxt.Broadcastdemo.IpCall.IpCallPhone"> 2 <intent-filter android:priority="200"> 3 <action android:name="android.intent.action.NEW_OUTGOING_CALL"/> 4 </intent-filter> 5 </receiver>
效果展示: