欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 之 广播BroadcastReceiver

程序员文章站 2022-05-16 12:22:09
...
BroadcastReceiver

1. 介绍:四大组件之一,本质就是一个全局监听器;
2. 特性:由于为全局监听器,所以可以方便的实现系统中不同组件之间的通信;
3. 器也会随着关闭; BroadcastReceiver 是系统级别的监听器,拥有自己的进程,只要系统中存在着与之匹配的Intent 被广播出来,BroadcastReceiver 总会被激发;说明:BroadcastReceiver 和 事件处理机制相似,事件处理机制是程序级别的监听器,这些监听器运行在指定程序所在的进程中,当程序退出时,监听
4. 启动:程序是通过sendBroadcast() 方法来启动指定的BroadcastReceiver;
5. 实现:
a) 构建要广播的Intent,然后使用sendBroadcast()  进行发送;
b) 定义广播接收器,继承BoradcaseReceiver 类,重写onReceiver() 方法来响应事件;
6. 注册方式:
a) 静态注册:
1) <receiver android:name=”” >
1. <intent-filter>
a) <action android:name=”android.intent.action.MY_BROADCAST”/>
b) <category android:name=”android.intent.category.DEFAULT/>”
2. </intent-filter>
2) </receiver>
3) 提示:这种方式的注册是常驻型的,当应用程序关闭后,如果有广播信息传来,接收者也会被系统调用而自动运行的;
b) 动态注册:在代码中动态的指定广播地址并进行注册,
1) MyReceiver myreceiver = new MyRecevier();
2) IntentFilter intentFilter = new IntentFilter();
3) intentFilter.addAction(“android.intetn.action.MyReceiver”);
4) registerReceiver(myreceiver,intentFilter); //注册
5) unregisterReceiver(myreceiver);  //注销
6) 注意:动态注册和静态注册相反,不是常驻型的,也就是广播会跟随程序的生命周期;
7. 注意:如果onReceiver() 方法不能在10秒内完成的,则提示该程序无响应,会弹出ANR的对话框;
8. 广播的分类:
a) 普通广播:
1) 优点:可以在同一时刻被所有接受者收到,消息传递的效率高;
2) 缺点:接受者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent 的传播;
3) 发送:sendBroadcast();
b) 有序广播:接收者将按预先声明的优先级一次接收Boradcast,优先级 -1000 --- 1000,数值越大优先级别越高;有序广播接收者可以终止Broadcast Intent的传播,一旦终止后面的接收者就不能收到Broadcast;另外,接收者可以将数据传递给下一个接收者;
1) 优先级设置:android:priority=””
2) 代码设置:IntentFilter 对象的setPriority(); 设置
3) 发送:sendOrderedBroadcast();
4) 终止广播:abortBoradcast();
5) 接收者传递信息:setResultExtras(bundle);
6) 下一接收者获取信息:Bundle bundle = getResultExtras(true);
7) 获取Action动作:intent.getAction();
8) 提示:有序广播所有的接收者监控的动作action 相同,优先级决定顺序;
9. 系统广播:系统中定义了很多标准的Broascast Action 来响应系统的广播事件;
a) ACTION_TIME_CHANGED    :  时间改变时触发
b) ACTION_BOOT_COMPLETED  :  系统启动完成后触发,比如开机自启软件;
c) ACTION_PACKAGE_ADDED    :  添加包时触发
d) ACTION_BATTERY_CHANGED  :  电量低时触发;
e) 常量值例如:android.intent.action.BOOT_COMPLETED
f) ACTION_TIME_CHANGED   时间改变
g) ACTION_DATE_CHANGED   日期改变
h) ACTION_MEDIA_EJECT 插入或拔出外部媒体
i) ACTION_MEDIA_BUTTON    按下媒体按钮;
j) ACTION_PACKAGE_REMOVED  删除包



事例如下:
首先看mainfest 配置文件中的配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sun.broadcastreceiver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="10" />

    <!-- 定义:该应用的访问权限 -->
    <permission
        android:name="android.permission.MY_BROADCAST_RECEIVER"
        android:protectionLevel="normal" >
    </permission>
    <!-- 使用:声明使用的权限 -->
    <uses-permission android:name="android.permission.MY_BROADCAST_RECEIVER" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.sun.broadcastreceiver.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 使用静态方式注册广播接收者 , 监听动作:android.sun.MY_BROADCASE_RECEIVER -->
        <receiver android:name=".MyBroadcastReceiver" >
            <intent-filter>

                <!-- 监听的意图 -->
                <action android:name="android.sun.MY_BROADCAST_RECEIVER" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        <!--
             有序广播 :使用 定义优先级:-1000 至 1000 的值,值越大优先级越高,先执行  android:priority="800" 
        	所有的接收者指定相同的意图,才能保证广播的传递
        -->
        <receiver android:name=".MyOrderBroadcastReceiverOne" >
            <intent-filter android:priority="800" >
                <action android:name="android.intent.action.MY_ORDER_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <!-- 优先级为:android:priority="900" -->
        <receiver android:name=".MyOrderBroadcastReceiverTwo" >
            <intent-filter android:priority="900" >
                <action android:name="android.intent.action.MY_ORDER_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <!-- 优先级为:android:priority="700" -->
        <receiver android:name=".MyOrderBroadcastReceiverThree" >
            <intent-filter android:priority="700" >
                <action android:name="android.intent.action.MY_ORDER_BROADCAST" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
    </application>

</manifest>


布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/send"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="普通广播发送" />

    <Button
        android:id="@+id/sendOrder"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="有序广播发送" />


</LinearLayout>



主界面Activity 内容:---------------------------------------------------------


package com.sun.broadcastreceiver;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

/**
 * 功能实现 -- 普通广播 和 有序广播的发送测试
 * 
 * @author Administrator
 * 
 */
public class MainActivity extends Activity {

	private Button send, sendOrder;

	/**
	 * 获取布局文件中控件的对象
	 */
	public void init() {
		Log.i("msg", "init()...调用");
		send = (Button) findViewById(R.id.send);
		sendOrder = (Button) findViewById(R.id.sendOrder);
	}

	// 程序入口
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		init(); // 初始化

		// 设置监听器
		send.setOnClickListener(listener);
		sendOrder.setOnClickListener(listener);
	}
	
	/***************************************************************************/

	/**
	 * 动作,发送普通广播
	 */
	public void sendAction() {
		Intent intent = new Intent();
		intent.setAction("android.sun.MY_BROADCAST_RECEIVER") ;  // 使用隐士意图进行广播的发送
		intent.putExtra("msg", "我是被发送测试普通广播的");
		sendBroadcast(intent, "android.permission.MY_BROADCAST_RECEIVER");
	}

	/**
	 * 动作:发送有序广播
	 */
	public void sendOrderAction() {
		Intent intent = new Intent();
		intent.setAction("android.intent.action.MY_ORDER_BROADCAST");
		intent.putExtra("msg", "首任接收者");
		sendOrderedBroadcast(intent, "android.permission.MY_BROADCAST_RECEIVER");	
	}

	/** 按钮监听器 */
	private android.view.View.OnClickListener listener = new View.OnClickListener() {

		public void onClick(View v) {
			if (v.getId() == R.id.send) {
				sendAction();
				return;
			}
			if (v.getId() == R.id.sendOrder) {
				sendOrderAction();
			}
		}
	};

	/**--------------------------- Start广播:动态注册 与注销------------------------------------------------------*/
	
	/**
	 * 程序结束后注销广播 -- unregisterReceiver();
	 */
	protected void onDestroy() {
		
		super.onDestroy();
		unregisterReceiver(dynamic);
	}

	/**
	 * 程序运行时注册广播 -- registerReceiver();
	 */
	protected void onResume() {
		super.onResume();
		Log.i("msg", "onResume()...");
		
		// 根据意图创建 Intent 过滤器
		IntentFilter intentFilter = new IntentFilter("android.sun.MY_DYNAMIC_BROADCAST_RECEIVER");
		registerReceiver(dynamic, intentFilter); // 注册
		sendDynamicBoradcast();
	}
	
	/**
	 * 动态注册发送广播
	 */
	public void sendDynamicBoradcast(){
		
		// 根据 广播地址 构建Intent 对象
		Intent intent = new Intent("android.sun.MY_DYNAMIC_BROADCAST_RECEIVER");
		
		sendBroadcast(intent);	// 发送广播
	}
	
	//动态注册--- 接收者
	private BroadcastReceiver dynamic = new BroadcastReceiver() {
		
		public void onReceive(Context context, Intent intent) {
			
			Log.i("msg","动态测试意图:"+intent.getAction());
		}
	};
	/**--------------------------- End 广播:动态注册 与注销------------------------------------------------------*/
}

接收者 1:

/**
 * 广播接收者 -- 收到广播后处理动作
 * @author Administrator
 *
 */
public class MyBroadcastReceiver extends BroadcastReceiver {

	public void onReceive(Context context, Intent intent) {

		Log.i("msg","广播已经收到 onReceive()...");
		String action = intent.getAction(); // 得到意图名称
		String msg = intent.getStringExtra("msg"); //得到发送广播传递的数据
		Log.i("msg","意图:"+action+"  信息:"+msg);
	}
}


接收者二:
/**
 * 有序广播测试 -- 接收者 , 级别:android.pro
 * @author Administrator
 *
 */
public class MyOrderBroadcastReceiverOne extends BroadcastReceiver {

	public void onReceive(Context context, Intent intent) {
			
		Log.i("msg", "接收者one ....");
		Bundle bundle = new Bundle();
		bundle.putString("info","我是从one来的");
		this.setResultExtras(bundle); // 此接收者传递数据给下一个接收者
		abortBroadcast(); // 终止广播	
	}
}


接收者三:
public class MyOrderBroadcastReceiverTwo extends BroadcastReceiver {

	public void onReceive(Context context, Intent intent) {
		
		Bundle bundle = getResultExtras(true);
		Log.i("msg","three:"+this.getResultCode()+"  "+bundle.getString("info"));

	}
}


接收者四:
public class MyOrderBroadcastReceiverThree extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		
		Bundle bundle = getResultExtras(true);
		Log.i("msg","two:"+bundle.getString("info"));
	}

}