Android:攔截系統BroadcastReceiver

來源:互聯網
上載者:User

 系統中的廣播

  在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     @Override19     public void onReceive(Context context, Intent intent) {20         // 判斷當前接收到的Broadcast是否是收到簡訊的action21         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                             // 發現黑名單關鍵字,則標記為true36                             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     @Override10     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             // 把新號碼增加到返回結果資料中,用於傳遞給後面的Receiver18             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>

  效果展示:

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.