歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android廣播和短信廣播詳解----使用廣播接收者竊聽短信

當系統收到短信時,會發出一個action名稱為Android.provier.Telephony.SMS_RECEIVED的廣播Intent,該Intent存放了接收到的短信內容,使用名稱 “pdus”即可從Intent中獲取短信內容。

pdus是一個object類型的數組,每一個object都是一個byte[]字節數組,每一項為一條短信。

Object[] pduses= (Object[])intent.getExtras().get("pdus");

       for(Objectpdus: pduses){

           byte[] pdusmessage = (byte[])pdus;

           SmsMessage sms = SmsMessage.createFromPdu(pdusmessage);

           String mobile = sms.getOriginatingAddress();//發送短信的手機號碼

           String content = sms.getMessageBody(); //短信內容

           Date date = new Date(sms.getTimestampMillis());

           SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

           String time = format.format(date);  //得到發送時間

          

       }

 

廣播接收者(BroadcastReceiver)用於接收廣播Intent,廣播Intent的發送是通過調用Context.sendBroadcast()、Context.sendOrdeedBroadcast()、context.sendStickyBroadcast()來實現的,通常一個廣播Intent可以被訂閱了此Intent的多個廣播接收者所接收,這個特性跟JMS中的Topic消息接收者類似,要實現一個廣播接收者方法如下:

第一步,繼承BroadcastReceiver,並重寫onReceive()方法

public class SMSBroadcastReceiver extends BroadcastReceiver{

    @Override

    public void onReceive(Context context, Intent intent) {

      

    }

}

onReceive的生命周期為10秒,所以裡面的操作不能超過10秒

 

第二步,訂閱感興趣的廣播Intent,訂閱方法有兩種:

       第一種:使用代碼進行訂閱

SMSBroadcastReceiver receiver = new SMSBroadcastReceiver();

IntentFilter filter = new IntentFilter();

       filter.addAction("android.provider.Telephony.SMS_RECEIVED");

       context.registerReceiver(receiver,filter);

       第二種:在AndroidManifest.xml文件中的<application>節點裡進行訂閱

<receiver android:name=".SMSBroadcastReceiver">

           <intent-filter>

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

           </intent-filter>

       </receiver>

 

第三步,增加接收短信權限

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

</uses-permission>

 

廣播被分為兩種不同的類型,“普通廣播(Normal broadcasts)”和“有序廣播(Ordered broadcasts)”。普通廣播是完全異步的,可以在同一時刻(邏輯上)被所有接收者接收到,消息傳遞的效率比較高,但缺點是:接收者不能將處理結果傳遞給下一個接收者,並且無法終止廣播Intent的傳播;然而有序廣播是按照接收者聲明的優先級別(聲明在intent-filter元素的android:priority屬性中,數據大優先級別越高,取值范圍:-1000到1000也可以調用IntentFilter對象的setPriority()進行設置),被接收者依次接收廣播。如:A的級別高於B,B的級別高於C,那麼,廣播先傳給A,再傳給B,最後傳給C。A得到廣播後,可以往廣播裡存入數據,當廣播傳給B時,B可以從廣播中得到A存入的數據。

 

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

Context.sendOrderedBroadcast()發送的是有序廣播,系統會根據接收者聲明的優先級別按順序逐個執行接收者,前面的接收者有權終止廣播(BroadcastReceiver.abortBroadcast() ),如果廣播被前面的接收者終止,後面的接收者就再也無法獲取到廣播。對於有序廣播,前面的接收者可以將處理結果存進廣播Intent,然後傳給下一個接收者。

sendStickyBroadcast() 意思只要是如果發送廣播之後才執行registerReceiver(BroadcastReceiver,IntentFilter).這個方法依然可以接受到。換句話說,在ReceiverActivity裡是通過代碼來注冊Recevier而不是在Manifest裡面注冊的。sendStickyBroadcast發出的最後一個Intent會被保留,當下次Recevier處於活躍的時候,又會接受到它。需要加BROADCAST_STICKY權限,否則會拋SecurityException

 

接收電池電量變化廣播:

<action android:name="android.intent.action.BATTERY_CHANGED"/>

 

接收開機啟動廣播

<action android:name="android.intent.action.BOOT_COMPLETED"/>

並在進行權限聲明

<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED”/>

 

在Android中,程序的響應(Responsive)被活動管理器(Activity Manager)和窗口管理器(Window Manager)這兩個系統服務所監視,當BroadcastReceiver在10秒內沒有執行完畢,Android會認為該程序無響應,所以在BroadcastReceiver裡不能做一些比較耗時的操作,否則會彈出ANR(Application No Response)的對話框。如果需要完成一項比較耗時的工作,應該通過發送Intent給Service,由Service來完成,而不是使用子線程的方法來解決,因為BroadcastReceiver的生命周期很短(在onReceive()執行後BroadcastReceiver的實例就會被銷毀),子線程可能還沒有結束BroadcastReceiver就先結束了。如果BroadcastReceiver結束了,它的宿主進程還在運行,那麼子線程還會繼續執行。但宿主進程此時很容易在系統需要內在時被優先殺死。因為它屬於空進程(沒有任何活動組件的進程)。

每次廣播消息到來時,都會創建BroadcastReceiver實例來執行onReceive()方法。


事例:

 
  1. package com.king.sms;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5.   
  6. import android.content.BroadcastReceiver;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.telephony.SmsMessage;  
  10.   
  11.   
  12.   
  13. public class SMSBroadcastReceiver extends BroadcastReceiver{  
  14.   
  15.     @Override  
  16.     public void onReceive(Context context, Intent intent) {  
  17.         Object[] pduses= (Object[])intent.getExtras().get("pdus");  
  18.         for(Object pdus: pduses){  
  19.             byte[] pdusmessage = (byte[])pdus;  
  20.             SmsMessage sms = SmsMessage.createFromPdu(pdusmessage);  
  21.             String mobile = sms.getOriginatingAddress();//發送短信的手機號碼   
  22.             String content = sms.getMessageBody(); //短信內容   
  23.             Date date = new Date(sms.getTimestampMillis());  
  24.             SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  25.             String time = format.format(date);  //得到發送時間   
  26.               
  27.         }  
  28.     }  
  29.   
  30. }  

//    AndroidManifest.xml

 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.king.sms"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <uses-sdk android:minSdkVersion="8" />  
  7.     <span style="color:#ff0000;"><uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission></span>  
  8.   
  9.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  10.         <receiver android:name=".SMSBroadcastReceiver">  
  11.             <intent-filter>  
  12.                 <action android:name="android.provider.Telephony.SMS_RECEIVED"/>  
  13.             </intent-filter>  
  14.         </receiver>  
  15.   
  16.     </application>  
  17. </manifest>  
Copyright © Linux教程網 All Rights Reserved