广播机制

所谓广播,最大的特点就是广播向外发送消息,但是发送方不关心接收方是否接收到数据,也不关心接收方如何处理数据。生活中只要有广播接收器,就能接收广播信息,但是只有特定的人群可以对广播的消息进行处理,因为对于其他人来说广播的消息可能是无用的,比如在广播的时候播放了一段交通路况,某某路段交通堵塞,那么司机师傅就会对自己的行驶路线进行相应的调整,而对于其他人来说,这条消息是无用的,也不必做出任何处理。


Android中广播的是操作系统当中所产生的各种各样的事件,比如手机接收到一条短消息或者电话就会产生一个事件,操作系统就会像所有的广播接收器广播事件,对于广播接收器是否关心事件以及如何处理由广播接收器来决定。


我们要做的就是开发广播接收器,将其注册到操作系统当中,当系统产生一个事件时,就会通知所有注册的广播接收器BroadcastReceiver(用于事件(Intent)的监听),这些注册的接收器会判断接收的事件是否是自己所需要的事件,如果是,就会对事件进行相对的处理。

比如:手机拍照,在拍照结束后,就会产生一个事件,去通知那些已经注册的广播接收器,然后做出一些处理,如:是否保存,或者进行添加边框特效等处理



广播接收器的注册有两种方式:

方式一:

在AndroidMainfest.xml文件中进行注册:

<!--<receiver android:name="SMSReceiver">
		<!—决定receiver最终接收什么样的事件-->
			<intent-filter>
				<action android:name="android.provider.Telephony.SMS_RECEIVED" />
			</intent-filter>
		</receiver>-->


特点:这样的注册,即使应用程序没有启动,或者被kill掉之后,也始终会处于活动状态


方式二:

在代码当中进行注册

registerReceiver(receiver,filter);

取消注册

UnregisterReceiver(receiver)

 

建议:

如果一个BroadcastReceiver用于更新UI,那么通常会使用这种方法进行注册,在Activity启动的时候注册,在Activity不可见以后取消注册。


两种注册BroadcastReceiver方法的比较:

              现在我们了解了两种注册BroadcastReceiver的方法之后,需要考虑一下这两种方法适用的场合:


AndroidMainfest.xml文件中注册:

可以保证在应用程序安装之后,BroadcastReceiver始终处于活动状态,通常用于监听系统状态的改变,比如说手机的电量,wifi网卡的状态(当然,监视这些东西也是取决于软件的需求)。对于这样的BroadcastReceiver,通常是在产生某个特定的系统事件之后,进行相应的操作,比如说wifi网卡打开时,给用户一个提示;

 

在应用程序的代码中注册:

相对上面一种要灵活的多,这样注册的BroadcastReceiver通常用于更新UI的状态。一般来说,都是在一个Activity启动的时候使用这样的方法注册BroadcastReceiver,一旦接收到广播的事件,就可以在onReceive方法当中更新当前的这个Activity当中的控件。但是需要注意的是如果这个Activity不可见了,就应该调用unregisterReceiver方法来解除注册;



BroadcastReceiver的生命周期:

A BroadcastReceiver object is only valid for the duration of thecall to onReceive(Context,Intent). Once your code returns from this function,the system considers the object to be finished and no longer active.

在调用onReceive方法结束后,生命周期就结束了,所以每次接收广播,都会生成一个新的已继承BroadcastReceiver的子类对象。

 

一个广播的完整实现过程:

要实现广播接收,需要创建一个类继承BroadcastReceiver,然后在AndroidMainfest.xml文件中进行注册,intent-filter是事件过滤器,所以要想发送广播,首先要有一个Intent对象。然后设置Intent的action属性,接着sendBroadcast(intent)发送广播,之后会对每一个BroadcastReceiver的Intent-filter对象和AndroidMainfest.xml文件中注册的action 是否一致,如果一致就会调用已继承BroadcastReceiver的子类的构造函数生成一个BroadcastReceiver对象,接着调用onReceive方法,所以主要处理事件的方法就写在onReceive()当中。


示例:在应用程序代码中进行注册

说明:

    1、在AndroidMainfest.xml 文件中对短信接收许可进行注册

    2、需要一个BroadcastReceiver对象,所以创建一个BroadcastReceiver子类,并在onReceive方法中进行事件的处理

    3、创建一个IntentFilter类型的对象filter,filter需要添加action,以便决定BroadcastReceiver可以接收什么样的请求,

       广播的事件是以Intent对象的形式广播出来的,所以如果IntentFilter的filter能够匹配上,那么receiver就可以接收到广播,

    4、在activity不可见的时候进行取消注册。


效果图示:



在AndroidMainfest中对短信接收许可进行注册

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


布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/registerButton"
        android:text="绑定监听器"
        
        />
    <Button 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/unregisterButton"
        android:layout_below="@id/registerButton"
        android:text="解除监听器绑定"
        />
</RelativeLayout>


Activity代码

package com.example.mybroadcastreceiver;

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 BroadcastReceiver extends Activity {

	private Button registerButton = null;
	private Button unregisterButton = null;
	private SMSReceiver receiver = null;
	private static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED"; 
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.broadcast_receiver);
        
        unregisterButton = (Button) findViewById(R.id.unregisterButton);
        registerButton = (Button) findViewById(R.id.registerButton);
        registerButton.setOnClickListener(new registerListener());
        unregisterButton.setOnClickListener(new unregisterListener());
        
    }

    private final class registerListener implements OnClickListener{
    	
    	public void onClick(View v) {
    		/*receiver = new SMSReceiver();
    		IntentFilter filter = new IntentFilter();
    		filter.addAction(SMS_ACTION);
    		BroadcastReceiver.this.registerReceiver(receiver, filter);*/
    		
    		//生成一个BroiadcastReceiver对象
			receiver = new SMSReceiver();
			//生成一个IntentFilter对象
			IntentFilter filter = new IntentFilter();
			//为IntentFilter添加一个Action
			filter.addAction(SMS_ACTION);
			//将BroadcastReceiver对象注册到系统当中
			BroadcastReceiver.this.registerReceiver(receiver, filter);
    	}
    	
    }
    private final class unregisterListener implements OnClickListener{

		public void onClick(View v) {
			//解除BroadcastReceiver对象的注册
			BroadcastReceiver.this.unregisterReceiver(receiver);
		}
    	
    }
    
}


获取BroadcastReceiver对象并处理事件代码:

package com.example.mybroadcastreceiver;

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) {
		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];
		
		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());
		}
		
	}

}