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即可。

程序清单:

[java]  view plain copy
  1. public class LaunchWithSys extends BroadcastReceiver {      
  2.          @Override  
  3.          public void onReceive(Context context, Intent intent) {  
  4.                    // TODO Auto-generated method stub  
  5.                    Intent launchService=new Intent(context, LaunchService.class);  
  6.                    //启动指定Service  
  7.                    context.startActivity(launchService);  
  8.          }  
  9. }    

         从上面看该LaunchWithSys非常简单,只需要启动指定的Service即可,接下来需要注册用于监听系统开机广播的BroadcastReceiver:因此需要在AndroidManifest.xml注册一个下面的接收器: [java]  view plain copy
  1.   
  2.   
  3.           
  4.   
  5.   

除此之外,为了能够让程序访问开机启动事件,需要为程序添加如下的权限: [java]  view plain copy
  1. "code" class="html">
  2.            

实例二:短息提醒

     在Android中当系统收到短信后会发出一个有序的广播,该广播的Intent的Action为android.provider.Telephony.SMS_RECEIVED。因此只需要在程序中开发一个对应的BroadcastReceiver即可监听到系统接收到的短信。

程序清单:

[java]  view plain copy
  1. public class SmsReceiver extends BroadcastReceiver {  
  2.          @Override  
  3.          public void onReceive(Context context, Intent intent) {  
  4.                    // TODO Auto-generated method stub  
  5.                    //如果收到短信  
  6.                    if (intent.getAction().equals(“android.provider.Telephony.SMS_RECEIVED”)) {  
  7.                             //取消这条有序广播(取消后会让其它应用收不到短信)  
  8.                             abortBroadcast();  
  9.                             Bundle bundle=intent.getExtras();  
  10.                             if (bundle!=null) {//如果数据不为空  
  11.                                      //获得收到的短信数据  
  12.                                      Object[] objArray=(Object[]) bundle.get(“pdus”);  
  13.                                      //根据objArray的大小创建一个SmsMessage数组,用于封装短信内容  
  14.                                      SmsMessage []smsMessage=new SmsMessage[objArray.length];  
  15.                                      StringBuffer sb=new StringBuffer();  
  16.                                      sb.append(“时间:”+new DateFormat().format(“yyyy-MM-dd hh.mm.ss”, new Date()));  
  17.                                      //遍历smsMessage数组取出所有短信  
  18.                                      for (int i = 0; i < smsMessage.length; i++) {  
  19.                                                //将每条字节类型的短信数据转换成SmsMessage对象  
  20.                                                smsMessage[i]=SmsMessage.createFromPdu((byte[])objArray[i]);  
  21.                                                //获取短信发送地址  
  22.                                                sb.append(“发送者:”+smsMessage[i].getOriginatingAddress());  
  23.                                                //获取短信内容  
  24.                                                sb.append(“短信内容:”+smsMessage[i].getDisplayMessageBody()+”\n”);  
  25.                                      }  
  26.                                      Toast.makeText(context, sb.toString(), Toast.LENGTH_LONG).show();  
  27.                             }                            
  28.                    }  
  29.          }         
  30. }  

实例分析:

Ÿ   由于接收到的短信内容是以字节数组形式保存的,为了便于用这些数据,需要使用SmsMessage.createFromPdu方法将这些字节数组形式的数据转换成SmsMessage对象。

Ÿ   由于接收器可能收到多条短信,因此,通过“pdus”返回了一个短信数组(byte[])所以需要遍历这个数组取出每一条短信。

由于需要监测系统发出的接收短信的广播,所以在配置文件中需要进行如下配置: 

[java]  view plain copy
  1.   
  2. 666”>  
  3.   
  4.   
  5.   

另外,由于程序需要接收短信,所以需要赋予程序接收短信的权限。

[html]  view plain copy
  1.          <uses-permission android:name=”android.permission.RECEIVE_SMS”/>  
  2.    
运行效果图:


实例三:手机电量提醒

        当手机电量发生变化是系统会发出,Intent的Action名为ACTION_BATTERY_CHANGED的广播,当手机电量过低时系统会发出Intent的Action名为ACTION_BATTRY_LOW的广播。所以,只需监测对应Intent的BroadcastReceiver便可实现手机低电量提醒的应用。

程序清单:

[java]  view plain copy
  1. public class MianActivity extends Activity {  
  2.          TextView show;  
  3.          @Override  
  4.          protected void onCreate(Bundle savedInstanceState) {  
  5.                    super.onCreate(savedInstanceState);  
  6.                    setContentView(R.layout.mian);  
  7.                    show=(TextView)findViewById(R.id.show);  
  8.                    ShowPowerReceiver showPowerReceiver=new ShowPowerReceiver();  
  9.                    IntentFilter filter=new IntentFilter();  
  10.                    filter.addAction(Intent.ACTION_BATTERY_CHANGED);  
  11.                    //注册showPowerReceiver  
  12.                    registerReceiver(showPowerReceiver, filter);  
  13.          }  
  14.          /** 
  15.           * Describe:
     
  16.           * 手机电量提醒 
  17.           * */  
  18.          class ShowPowerReceiver extends BroadcastReceiver {  
  19.                    @Override  
  20.                    public void onReceive(Context context, Intent intent) {  
  21.                             // TODO Auto-generated method stub  
  22.                             //判断接收到的是否为电量变化的BroadCast Action  
  23.                             if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {  
  24.                                      //当前电量  
  25.                                      int level=intent.getIntExtra("level"0);  
  26.                                      //总电量  
  27.                                      int scale=intent.getIntExtra("scale"100);  
  28.                                      int current=level*100/scale;  
  29.                                      show.setText("当前电量:"+current+"%");  
  30.                             }  
  31.                    }  
  32.          }  
  33. }  

程序运行效果图:


实例四:来去电提醒

       当通话状态改变时候系统会发出,Intent的Action名为ACTION _PHONE_STAT的广播,当手机播出电话时系统会发出Intent的Action名为ACTION_NEW_OUTGOING_CALL的广播。所以,只需监测对应Intent的BroadcastReceiver便可实现来去电提醒的应用。

程序清单:

[java]  view plain copy
  1. 来电提醒  
  2. public class InCallReceiver extends BroadcastReceiver  
  3. {  
  4.          private static Object obj;          
  5.          /** 
  6.           * 创建一个永不关闭的Toast 
  7.           * @param context Context context上下文 
  8.           * @param msg String msg 消息提示信息 
  9.           * */  
  10.          public static void showToast(Context context, String msg)  
  11.          {  
  12.                    //创建一个Toast对象  
  13.                    Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);  
  14.                    //设置Toast的显示位置  
  15.                    toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 00);  
  16.                    try  
  17.                    {  
  18.                             //从toast对象中获取mTN对象  
  19.                             Field field = toast.getClass().getDeclaredField("mTN");  
  20.                             field.setAccessible(true);  
  21.                             obj = field.get(toast);  
  22.                             //从TN对象中获得show方法  
  23.                             Method method = obj.getClass().getDeclaredMethod("show"null);  
  24.                             //调用TN对象的show方法来显示Toast信息提示框  
  25.                             method.invoke(obj, null);  
  26.                    }  
  27.                    catch (Exception e)  
  28.                    {  
  29.                    }  
  30.          }  
  31.          /** 
  32.           * 关闭Toast 
  33.           * */  
  34.          public static void closeToast()  
  35.          {  
  36.                    if (obj != null)  
  37.                    {  
  38.                             try  
  39.                             {  
  40.                                      Method method = obj.getClass().getDeclaredMethod("hide"null);  
  41.                                      method.invoke(obj, null);  
  42.                             }  
  43.                             catch (Exception e)  
  44.                             {  
  45.                             }  
  46.                    }  
  47.          }  
  48.          @Override  
  49.          public void onReceive(final Context context, final Intent intent)  
  50.          {  
  51.                    //获取电话管理服务  
  52.                    TelephonyManager tm = (TelephonyManager) context  
  53.                                      .getSystemService(Service.TELEPHONY_SERVICE);  
  54.    
  55.                    switch (tm.getCallState())  
  56.                    {  
  57.                             case TelephonyManager.CALL_STATE_RINGING://响铃  
  58.                                      String incomingNumber = intent  
  59.                                                         .getStringExtra("incoming_number");  
  60.                                      showToast(context, incomingNumber);  
  61.                                      break;  
  62.                             case TelephonyManager.CALL_STATE_OFFHOOK://接听电话  
  63.                                      Log.d("call_state""offhook");  
  64.                                      break;  
  65.    
  66.                             case TelephonyManager.CALL_STATE_IDLE://挂断电话  
  67.                                      closeToast();  
  68.                    }  
  69.          }  
  70. }  
  71.    
  72. //去电提醒  
  73. public class OutCallReceiver extends BroadcastReceiver  
  74. {        @Override  
  75.          public void onReceive(Context context, Intent intent)  
  76.          {  
  77.                    //获取去电的电话号码  
  78.                    String outcomingNumber = intent  
  79.                                      .getStringExtra(Intent.EXTRA_PHONE_NUMBER);  
  80.                    InCallReceiver.showToast(context, outcomingNumber);  
  81.          }  
  82.    
  83. }  

配置文件:AndroidManifest.xml

[html]  view plain copy
  1.   
  2. <uses-permission android:name="android.permission.READ_PHONE_STATE" />  
  3.            
  4. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />  
  5.    
  6.   
  7. <receiver android:name=".InCallReceiver" android:enabled="true">  
  8.          <intent-filter>  
  9.                    <action android:name="android.intent.action.PHONE_STATE" />  
  10.          intent-filter>  
  11. receiver>  
  12.    
  13. <receiver android:name=".OutCallReceiver" android:enabled="true">  
  14.          <intent-filter>  
  15.                    <action android:name="android.intent.action.NEW_OUTGOING_CALL" />  
  16.          intent-filter>  
  17. receiver>          
  18.            
程序运行效果图:


       最后:由于在接收广播的时候,系统会为每一次接收广播单独创建一个广播接收器,即使是同一个广播的多次接收。因此,当电话处于不同的通话状态时,实际上是在不同的接收器对象中发生的,所以需要使用静态变量来保存Toast对象,不然closeTost我无法获取在上一个状态创建的Toast对象,也就无法关闭Toast信息框了。

更多相关文章

  1. Android四大基本组件介绍与生命周期
  2. Android小心有坑之网络状态监听
  3. android键盘的回车键修改和监听
  4. [Android]文本框实现搜索和清空效果
  5. Android(安卓)第七天重置版_BroadCastReceiver
  6. Android(安卓)利用广播实现黑名单【指定号码】的短信的拦截 附源
  7. Android常用控件总结
  8. Android(安卓)显示系统键盘搜索按键,实现搜索功能
  9. Android(安卓)Broadcast receiver使用入门

随机推荐

  1. Android 提示框
  2. 在Android中使用Gradle
  3. Mac os Android 源码开发环境搭建
  4. unity游戏在安卓按home或者锁屏键后不能
  5. android 实现拖动效果
  6. getActionBar() return null
  7. android 通过构造创建进度对话框
  8. android 设置应用程序装在T卡的方法
  9. Android中使用自定义view实现轮播图
  10. Android 跳转到应用市场,评价App