- 内容提纲:
在本节课当中,我会继续为大家讲解Android的广播机制,重点内容有以下的两个方面:
a) 在应用程序当中注册BroadcastReceiver的方法
b) Android内置的Broadcast Actions的使用方法
- 2. 课程内容:
a)
BroadcastReceiver的注册方法
在上节课当中,我们已经讨论过BroadcastReceiver的运行机制和基本使用方法,如果要使监听器能够接受到广播所发送Intent,就必须将这个BroadcastReceiver注册到系统当中,在manifest文件注册的方法如下:
但是使用这样的方法进行注册之后,即使你的应用程序没有启动,或者已经被关闭,这个BroadcastReceiver依然会继续运行,这样的运行机制可能会给软件的用户造成困扰。所以作为程序的开发者,我们希望能够有一种灵活的机制完成BroadcastReceiver的绑定和解除绑定操作。Android当然也考虑到了这些问题,所以在Context这个类当中提供了如下两个函数:
i.
registerReceiver(receiver,filter);
这个函数的作用就是将一个BroadcastReceiver注册到应用程序当中,这个函数接收两个参数,第一个参数是需要注册的BroadcastReceiver对象,第二个是一个IntentFilter。第一个参数是非常容易理解的,第二个参数的作用是定义了哪些Intent才能触发这个注册的BroadcastReceiver对象。类似于前面所讲解的
<intent-filter>标签的作用;
ii.
unregisterReceiver(receiver);
这个方法就非常的简单了,用于解除BroadcastReceiver的绑定状态。一旦解除完成,响应的BroadcastReceiver就不会再接收系统所广播的Intent了。
b)
两种注册BroadcastReceiver方法的比较:
现在我们了解了两种注册BroadcastReceiver的方法之后,需要考虑一下这两种方法适用的场合:
i. 第一种注册的方法可以保证在应用程序安装之后,BroadcastReceiver始终处于活动状态,通常用于监听系统状态的改变,比如说手机的电量,wifi网卡的状态(当然,监视这些东西也是取决于软件的需求)。对于这样的BroadcastReceiver,通常是在产生某个特定的系统事件之后,进行相应的操作,比如说wifi网卡打开时,给用户一个提示;
ii. 第二种注册方法相对第一种要灵活的多,这样注册的BroadcastReceiver通常用于更新UI的状态。一般来说,都是在一个Activity启动的时候使用这样的方法注册BroadcastReceiver,一旦接收到广播的事件,就可以在onReceive方法当中更新当前的这个Activity当中的控件。但是需要注意的是如果这个Activity不可见了,就应该调用unregisterReceiver方法来解除注册;
Android系统当中自带的Broadcast Action:
我们使用BroadcastReceiver的目的多半是为了监听系统当中所发生的各种各样事件(当然也不排除有的时候我们自己的程序也会广播事件),所以就有必要了解一下在Android系统当中,究竟有哪些事件会被广播出来,关于这个问题Android SDK的文档上面有着详细的解释:
除了以上的这些Actions之外,Anroid系统还会将一些应用程序级别的时间广播出来,例如收到短消息等等。
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mars.testbc2" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".TestBC2Activity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!--<receiver android:name="SMSReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>--> </application> <uses-sdk android:minSdkVersion="4" /> <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission> </manifest>
SMSReceiver.java:
package mars.testbc2; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.SmsMessage; public class SMSReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub System.out.println("receive message"); //接受Intent对象当中的数据 Bundle bundle = intent.getExtras(); //在Bundle对象当中有一个属性名为pdus,这个属性的值是一个Object数组 Object[] myOBJpdus = (Object[]) bundle.get("pdus"); //创建一个SmsMessage类型的数组 SmsMessage[] messages = new SmsMessage[myOBJpdus.length]; System.out.println(messages.length); for (int i = 0; i<myOBJpdus.length; i++) { //使用Object数组当中的对象创建SmsMessage对象 messages[i] = SmsMessage.createFromPdu((byte[]) myOBJpdus[i]); //调用SmsMessage对象的getDisppalyMessageBody()方法,就可以得到消息的内容 System.out.println(messages[i].getDisplayMessageBody()); } try { Thread.sleep(30 * 1000); System.out.println("-------------------------------"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
TestBC2Activity.java:
package mars.testbc2; import android.app.Activity; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class TestBC2Activity extends Activity { /** Called when the activity is first created. */ private Button registerButton = null; private Button unregisterButton = null; private SMSReceiver smsReceiver = null; private static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); registerButton = (Button)findViewById(R.id.register); registerButton.setOnClickListener(new RegisterReceiverListener()); unregisterButton = (Button)findViewById(R.id.unregister); unregisterButton.setOnClickListener(new UnRegisterReceiverListener()); } class RegisterReceiverListener implements OnClickListener{ @Override public void onClick(View v) { //生成一个BroiadcastReceiver对象 smsReceiver = new SMSReceiver(); //生成一个IntentFilter对象 IntentFilter filter = new IntentFilter(); //为IntentFilter添加一个Action filter.addAction(SMS_ACTION); //将BroadcastReceiver对象注册到系统当中 TestBC2Activity.this.registerReceiver(smsReceiver, filter); } } class UnRegisterReceiverListener implements OnClickListener{ @Override public void onClick(View v) { //解除BroadcastReceiver对象的注册 TestBC2Activity.this.unregisterReceiver(smsReceiver); } } }
在Emulator Control中SendMessage,绑定之后将可以接收消息然后打印出来。