1、在计算机网络中,在一个IP网络范围内最大的IP地址是被保留作为广播地址来使用的。广播数据包会被发送到同一网络上的所有端口,这样在网络中的每台主机都将会收到这条广播。为了方便于进行系统级别的消息通知,Android也引入了一套类似的广播消息机制。

2、在Android中,每一个应用程序都可以对自己感兴趣的广播进行注册,那么每个应用程序只会接收到自己感兴趣的广播。这些广播可能是来自于系统,也可能来自于其他应用程序。发送广播借助Intent, 接收广播依靠Broadcast Receiver。

3、Android中的广播分为两种类型:

(1)标准广播:异步,所有的人同一时间都能收到广播,没有顺序概念,无法被拦截。

(2)有序广播:同步,每一时刻都是一个人接收到广播,利用完之后继续广播下去。可以截断广播。

4、Android内置了很多系统级别的广播:开机,电量变化,时间变化等。

5、注册广播的方式有两种,通过代码注册的动态注册,通过配置文件注册的静态注册

(1)动态注册

public class MainActivity extends Activity {

	private IntentFilter intentFilter;
	private NetworkChangeReceiver networkChangeReceiver;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		intentFilter = new IntentFilter();
		intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
		//网络发生变化时,系统会发出一条android.net.conn.CONNECTIVITY_CHANGE的广播,所以此处增加的action为这个
		networkChangeReceiver = new NetworkChangeReceiver();
		registerReceiver(networkChangeReceiver, intentFilter);
	}

	protected void onDestroy(){
		super.onDestroy();
		unregisterReceiver(networkChangeReceiver);
	}
	
	class NetworkChangeReceiver <strong>extends BroadcastReceiver</strong>{
		@Override
		public void onReceive(Context arg0, Intent arg1) {
			//重写该onReceive方法
			ConnectivityManager connecManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
			//获取系统服务类,该服务类专门用于管理网络连接
			NetworkInfo networkInfo = connecManager.getActiveNetworkInfo();
			if(networkInfo != null && networkInfo.isAvailable()){
				Toast.makeText(arg0, "动态注册:network can be used", Toast.LENGTH_SHORT).show();
			}else{
				Toast.makeText(arg0, "动态注册:network can not be used", Toast.LENGTH_SHORT).show();
			}
		}
		
	}

}

因为代码中涉及到获取系统关键信息,所以需要在配置文件中配置好权限信息:

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

(2)静态注册

动态注册至少得在活动创建后才能启动。那么如果程序还没启动呢,就想获取广播,那么就适合用静态注册方法。静态注册,需要单独写一个接收器类:

public class BootCompleteReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context arg0, Intent arg1) {
		Toast.makeText(arg0, "静态注册:boot complete", Toast.LENGTH_SHORT).show();
	}

}

然后在配置文件中配置如下:

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
       <strong> <receiver android:name=".BootCompleteReceiver">
            <intent-filter >
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver></strong>
        
        <activity>
           ...
        </activity>
    </application>

其实从静态注册和动态注册中就可以看出,还是filter,action这一套内容。

6、发送自定义广播

广播分为两种类型:标准广播和有序广播

(1)标准广播

首先还得写一个接收器:

public class MyBroadCastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context arg0, Intent arg1) {
		Toast.makeText(arg0, "receive in mybroadcast receiver", Toast.LENGTH_SHORT).show();
	}

}

然后在配置文件中配置接收器:

<receiver android:name=".MyBroadCastReceiver">
            <intent-filter >
                <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>

在代码中增加一个按钮,然后按钮触发发送广播事件:

Button button = (Button)findViewById(R.id.button);
		button.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
				<strong>sendBroadcast(intent);</strong>
				
			}
		});


(2)有序广播

创建两外一个项目project2,在project2中编写接收器,并且在配置文件中配置好接收 com.example.broadcasttest.MY_BROADCAST广播,在上面的项目中点击按钮的时候,会报出两个提示,因为两个项目都能同时收到广播。如果将上一个项目中的

<strong>sendBroadcast(intent); 修改为</strong>
<strong></strong><pre name="code" class="java"><strong>sendOrderedBroadcast(intent,null); //第二个参数与权限相关</strong>

在其配置文件中,修改器配置文件为:

<receiver android:name=".MyBroadCastReceiver">
            <intent-filter<strong> android:prioriy="100"</strong>>
                <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>


其优先级设置很高,那么就会先收到广播信息,可以在其接收器上面加上代码来截断广播:

public class MyBroadCastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context arg0, Intent arg1) {
		Toast.makeText(arg0, "receive in mybroadcast receiver", Toast.LENGTH_SHORT).show();   <strong>abortBroadcast();</strong>
	}

}

注意,不要再广播onReceive中做太复杂的事情,因为在此只能实现单线程,如果消耗时间太长,容易报错。所以广播接收器的作用一般用于直接启动两外一个程序或者服务。

7、本地广播

现在提到的广播都是全局范围内的广播,那么就非常烦人了,如果有人刻意的发广播或者拦截广播就不太好了。 为了安全性,引入了本地广播。该广播只能在应用程序内部进行传递。

编写接收器类没有区别,只是现在只有动态的注册方法,代码如下:

class LocalReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context arg0, Intent arg1) {
			// TODO Auto-generated method stub
			
		}
		
	}

private LocalReceiver localReceive;
		private LocalBroadcastManager localBroadcastManager;
		localBroadcastManager = LocalBroadcastManager.getInstance(this);
		button.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
				localBroadcastManager.sendBroadcast(intent);
				
			}
		});
		intentFilter = new IntentFilter();
		intentFilter.addAction("android.net.conn.LOCAL_BROADCAST");
		localReceive = new LocalReceiver();
		localBroadcastManager.registerReceiver(localReceive, intentFilter);


8、实际广播应用总结

应用背景是强制下线功能。

(1)通过list记住所有活动,方便活动的集体销毁。写一个baseactivity。记住喔~

(2)可以通过代码弹出警告框等。

(3)在接收器中实现销毁和重启活动