Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之接收系統廣播消息

Android開發之接收系統廣播消息

編輯:關於Android編程

BroadcastReceiver除了接收用戶所發送的廣播消息之外,還有一個重要的用途:接收系統廣播。如果應用需要在系統特定時刻執行某些操作,就可以通過監聽系統廣播來實現。Android的大量系統事件都會對外發送標准廣播。以下是Android常見的廣播Action常量(詳請參考Android API文檔中關於Intent的說明)。

Action常量

說明

ACTION_TIME_CHANGED

系統時間被改變。

ACTION_DATE_CHANGED

系統日期被改變。

ACTION_TIMEZONE_CHANGED

系統時區被改變。

ACTION_BOOT_COMPLETED

系統啟動完成。

ACTION_PACKAGE_ADDED

新的應用程序被安裝。

ACTION_PACKAGE_CHANGED

應用程序被改變。

ACTION_PACKAGE_REMOVED

應用程序被卸載。

ACTION_PACKAGE_RESTARTED

應用程序被重新啟動。

ACTION_PACKAGE_DATA_CLEARED

應用程序數據被清理。

ACTION_BATTERY_CHANGED

電池電量改變。

ACTION_SHUTDOWN

系統被關閉。

ACTION_BATTRY_LOW

電池電量低。

ACTION_POWER_CONNECTED

外接電源被連通。

ACTION_POWER_DISCONNECTED

外接電源被斷開。

ACTION_SHUTDOWN

系統關閉。

ACTION_NEW_OUTGOING_CALL

播出電話。

ACTION _PHONE_STATE

系統通話狀態改變。

通過 來監聽特殊的廣播,即可以實現應用跟隨系統執行特定的某些操作。

實例一:開機自動運行的Service

在實際應用總往往會讓一些應用跟隨系統啟動,比如一個黑名單來電自動攔截的APP,監聽垃圾短信的APP... ...等等。為了讓Service能跟隨系統啟動,我們需要讓BroadcastReceiver監聽Action名為:ACTION_BOOT_COMPLETED常量的Intent,然後在BroadcastReceiver啟動特定的Service即可。

程序清單:

public class LaunchWithSys extends BroadcastReceiver {    
         @Override
         public void onReceive(Context context, Intent intent) {
                   // TODO Auto-generated method stub
                   Intent launchService=new Intent(context, LaunchService.class);
                   //啟動指定Service
                   context.startActivity(launchService);
         }
}  

從上面看該LaunchWithSys非常簡單,只需要啟動指定的Service即可,接下來需要注冊用於監聽系統開機廣播的BroadcastReceiver:因此需要在AndroidManifest.xml注冊一個下面的接收器:



        


除此之外,為了能夠讓程序訪問開機啟動事件,需要為程序添加如下的權限:



實例二:短息提醒

在Android中當系統收到短信後會發出一個有序的廣播,該廣播的Intent的Action為android.provider.Telephony.SMS_RECEIVED。因此只需要在程序中開發一個對應的BroadcastReceiver即可監聽到系統接收到的短信。

程序清單:

public class SmsReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
                   // TODO Auto-generated method stub
                   //如果收到短信
                   if (intent.getAction().equals(“android.provider.Telephony.SMS_RECEIVED”)) {
                            //取消這條有序廣播(取消後會讓其它應用收不到短信)
                            abortBroadcast();
                            Bundle bundle=intent.getExtras();
                            if (bundle!=null) {//如果數據不為空
                                     //獲得收到的短信數據
                                     Object[] objArray=(Object[]) bundle.get(“pdus”);
                                     //根據objArray的大小創建一個SmsMessage數組,用於封裝短信內容
                                     SmsMessage []smsMessage=new SmsMessage[objArray.length];
                                     StringBuffer sb=new StringBuffer();
                                     sb.append(“時間:”+new DateFormat().format(“yyyy-MM-dd hh.mm.ss”, new Date()));
                                     //遍歷smsMessage數組取出所有短信
                                     for (int i = 0; i < smsMessage.length; i++) {
                                               //將每條字節類型的短信數據轉換成SmsMessage對象
                                               smsMessage[i]=SmsMessage.createFromPdu((byte[])objArray[i]);
                                               //獲取短信發送地址
                                               sb.append(“發送者:”+smsMessage[i].getOriginatingAddress());
                                               //獲取短信內容
                                               sb.append(“短信內容:”+smsMessage[i].getDisplayMessageBody()+”\n”);
                                     }
                                     Toast.makeText(context, sb.toString(), Toast.LENGTH_LONG).show();
                            }                          
                   }
         }       
}

實例分析:

Ÿ 由於接收到的短信內容是以字節數組形式保存的,為了便於用這些數據,需要使用SmsMessage.createFromPdu方法將這些字節數組形式的數據轉換成SmsMessage對象。

Ÿ 由於接收器可能收到多條短信,因此,通過“pdus”返回了一個短信數組(byte[])所以需要遍歷這個數組取出每一條短信。

由於需要監測系統發出的接收短信的廣播,所以在配置文件中需要進行如下配置:





另外,由於程序需要接收短信,所以需要賦予程序接收短信的權限。


 
運行效果圖:

短消息提醒

實例三:手機電量提醒

當手機電量發生變化是系統會發出,Intent的Action名為ACTION_BATTERY_CHANGED的廣播,當手機電量過低時系統會發出Intent的Action名為ACTION_BATTRY_LOW的廣播。所以,只需監測對應Intent的BroadcastReceiver便可實現手機低電量提醒的應用。

程序清單:

public class MianActivity extends Activity {
         TextView show;
         @Override
         protected void onCreate(Bundle savedInstanceState) {
                   super.onCreate(savedInstanceState);
                   setContentView(R.layout.mian);
                   show=(TextView)findViewById(R.id.show);
                   ShowPowerReceiver showPowerReceiver=new ShowPowerReceiver();
                   IntentFilter filter=new IntentFilter();
                   filter.addAction(Intent.ACTION_BATTERY_CHANGED);
                   //注冊showPowerReceiver
                   registerReceiver(showPowerReceiver, filter);
         }
         /**
          * Describe:
* 手機電量提醒 * */ class ShowPowerReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub //判斷接收到的是否為電量變化的BroadCast Action if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) { //當前電量 int level=intent.getIntExtra("level", 0); //總電量 int scale=intent.getIntExtra("scale", 100); int current=level*100/scale; show.setText("當前電量:"+current+"%"); } } } }

程序運行效果圖:

手機電量提醒

實例四:來去電提醒

當通話狀態改變時候系統會發出,Intent的Action名為ACTION _PHONE_STAT的廣播,當手機播出電話時系統會發出Intent的Action名為ACTION_NEW_OUTGOING_CALL的廣播。所以,只需監測對應Intent的BroadcastReceiver便可實現來去電提醒的應用。

程序清單:

來電提醒
public class InCallReceiver extends BroadcastReceiver
{
         private static Object obj;        
         /**
          * 創建一個永不關閉的Toast
          * @param context Context context上下文
          * @param msg String msg 消息提示信息
          * */
         public static void showToast(Context context, String msg)
         {
                   //創建一個Toast對象
                   Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
                   //設置Toast的顯示位置
                   toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
                   try
                   {
                            //從toast對象中獲取mTN對象
                            Field field = toast.getClass().getDeclaredField("mTN");
                            field.setAccessible(true);
                            obj = field.get(toast);
                            //從TN對象中獲得show方法
                            Method method = obj.getClass().getDeclaredMethod("show", null);
                            //調用TN對象的show方法來顯示Toast信息提示框
                            method.invoke(obj, null);
                   }
                   catch (Exception e)
                   {
                   }
         }
         /**
          * 關閉Toast
          * */
         public static void closeToast()
         {
                   if (obj != null)
                   {
                            try
                            {
                                     Method method = obj.getClass().getDeclaredMethod("hide", null);
                                     method.invoke(obj, null);
                            }
                            catch (Exception e)
                            {
                            }
                   }
         }
         @Override
         public void onReceive(final Context context, final Intent intent)
         {
                   //獲取電話管理服務
                   TelephonyManager tm = (TelephonyManager) context
                                     .getSystemService(Service.TELEPHONY_SERVICE);
 
                   switch (tm.getCallState())
                   {
                            case TelephonyManager.CALL_STATE_RINGING://響鈴
                                     String incomingNumber = intent
                                                        .getStringExtra("incoming_number");
                                     showToast(context, incomingNumber);
                                     break;
                            case TelephonyManager.CALL_STATE_OFFHOOK://接聽電話
                                     Log.d("call_state", "offhook");
                                     break;
 
                            case TelephonyManager.CALL_STATE_IDLE://掛斷電話
                                     closeToast();
                   }
         }
}
 
//去電提醒
public class OutCallReceiver extends BroadcastReceiver
{        @Override
         public void onReceive(Context context, Intent intent)
         {
                   //獲取去電的電話號碼
                   String outcomingNumber = intent
                                     .getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                   InCallReceiver.showToast(context, outcomingNumber);
         }
 
}

配置文件:AndroidManifest.xml



         

 


         
                   
         

 

         
                   
         
        
         
程序運行效果圖:

來去電提醒
最後:由於在接收廣播的時候,系統會為每一次接收廣播單獨創建一個廣播接收器,即使是同一個廣播的多次接收。因此,當電話處於不同的通話狀態時,實際上是在不同的接收器對象中發生的,所以需要使用靜態變量來保存Toast對象,不然closeTost我無法獲取在上一個狀態創建的Toast對象,也就無法關閉Toast信息框了。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved