Broadcast机制(二)

  1. 内容提纲:
    在本节课当中,我会继续为大家讲解Android的广播机制,重点内容有以下的两个方面:

a)         在应用程序当中注册BroadcastReceiver的方法

b)         Android内置的Broadcast Actions的使用方法

  1. 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,绑定之后将可以接收消息然后打印出来。

原文地址:https://www.cnblogs.com/leihupqrst/p/3178900.html