萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> 安卓開發 >> Android:攔截系統BroadcastReceiver

Android:攔截系統BroadcastReceiver

 系統中的廣播

  在Android系統中,內置了很多Action產量,在觸發這些Action的時候,均會發布相應的Broadcast。一般而言,查看Android的API文檔中,關於Intent的說明即可找到對應Action的Broadcast,但是列舉的還不是很全,最好還是下載Android的源代碼,通過查看源代碼的方式查看需要攔截的Broadcast。

  下面列舉一些常用的廣播:

  • android.intent.action.TIME_SET:系統時間被修改。
  • android.intent.action.DATE_CHANGED:系統日期被修改。
  • android.intent.action.BOOT_COMPLETED:系統啟動完成。
  • android.intent.action.BATTERY_CHANGED:設備電量改變。
  • android.intent.action.BATTERY_LOW:設備電量低。
  • android.intent.action.ACTION_POWER_CONNECTED:設備連接電源。
  • android.intent.action.ACTION_POWER_DISCONNECTED:設備斷開電源。
  • android.provider.Telephony.SMS_RECEIVED:系統收到短信。
  • android.intent.action.NEW_OUTGOING_CALL:撥打電話。

  下面通過兩個例子,來講解如何在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>

  效果展示,先發送一個包含黑名單中關鍵字的短信,再發送一個正常的短信。

Android:攔截系統BroadcastReceiver 三聯 

 

 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>

  效果展示:

 

copyright © 萬盛學電腦網 all rights reserved