Android的Broadcast Receiver组件

        Broadcast Receiver顾名思义是指广播接收器,它和事件处理机制类似,只不过事件处理机制是程序组件级别的,而广播事件处理机制是系统级别的。我们可以使用Intent来启动一个程序组件,我们可以通过使用sendBroadcast()方法来发起一个系统级别的事件广播来传递消息。我们可以在应用程序中实现Broadcast Receiver来监听和响应这些广播的Intent。

        事件的广播比较简单,同样还是构建Intent对象,然后调用sendBroadcast()方法将广播发出。事件的接收是通过定义一个继承BroadcastReceiver的类来实现的,继承该类后覆盖其onReceive()方法,在该方法中响应事件。

1、系统广播事件

        Android系统中定义了很多标准的Broadcast Action来响应系统广播事件。例如,ACTION_TIME_CHANGED(时间改变时触发)、ACTION_BOOT_COMLETED(系统启动完成后触发)这些广播是系统自动发出的,我们直接定义事件接收器进行接收就可以使用这些系统消息。常见的标准广播Action常量如下表:

常量名称

常量值

意义

ACTION_BOOT_COMLETED

android.intent.action. BOOT_COMLETED

系统启动完成后触发

ACTION_TIME_CHANGED

android.intent.action. ACTION_TIME_CHANGED

时间改变

ACTION_DATE_CHANGED

android.intent.action. ACTION_DATE_CHANGED

日期改变

ACTION_TIMEZONE_CHANGED

android.intent.action.ACTION_TIMEZONE_CHANGED

时区改变

ACTION_BATTERY_LOW

android.intent.action. ACTION_BATTERY_LOW

电量低

ACTION_MEDIA_EJECT

android.intent.action. ACTION_MEDIA_EJECT

插入或拔出外部媒体

ACTION_MEDIA_BUTTON

android.intent.action. ACTION_MEDIA_BUTTON

按下媒体按钮

ACTION_PACKAGE_ADDED

android.intent.action. ACTION_PACKAGE_ADDED

添加包

ACTION_PACKAGE_REMOVED

android.intent.action. ACTION_PACKAGE_REMOVED

删除包

        我们可以通过接收系统启动完成(ACTION_BOOT_COMPLETED)广播来测试系统广播事件。接收系统发出的广播,我们只需定义接收器就可以了。

/**
 * 显示系统启动完成广播接收器
 */
public class MyReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context arg0, Intent arg1) {
		//显示接收到的广播
		Log.i("MyReceiver","BOOT_COMPLETED-----------------------");
	}
}
        在AndroidManifest.xml配置文件中注册该接收器,注意这里<intent-filter>中的<action>属性必须是“android.intent.action. BOOT_COMLETED”才能接收系统启动完成广播事件。

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

2、自定广播事件

        自定义一个广播是比较简单的,首先在程序组件里构件所有广播的Intent,使用sendBroadcast方法发送出去。其次定义一个广播接收器,该接收器类继承BroadcastReceiver,并覆盖onReceiver方法来响应事件。最后注册该广播接收器,我们可以在使用动态方式注册(在代码中注册),也可以使用静态方式注册(在AndroidManifest.xml配置文件中注册)。

静态注册
        静态注册是在AndroidManifest.xml文件中配置的,我们就来为MyReceiver注册一个广播地址:

        <receiver android:name=".MyReceiver">
            <intent-filter >
                <action android:name="android.intent.action.MY_BROADCAST"/>
                <category android:name="android.intent.category.DEFAULT" /> 
            </intent-filter>
        </receiver>
配置了以上信息之后,只要是android.intent.action.MY_BROADCAST这个地址的广播,MyReceiver都能够接收的到。注意,这种方式的注册是常驻型的,也就是说当应用关闭后,如果有广播信息传来,MyReceiver也会被系统调用而自动运行。
动态注册
        动态注册需要在代码中动态的指定广播地址并注册,通常我们是在Activity或Service注册一个广播,一般是在Activity的onResume()方法中使用registerReceiver()方法来注册一个广播,在Activity的onPause()方法中使用unregisterReceiver()方法来注销一个广播接收器。下面我们就来看一下注册的代码:

public class TestReceiverActivity  extends Activity{
	private MyReceiver receiver;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}
	@Override
	protected void onResume() {
		super.onResume();
		//实例化Receiver
		receiver = new MyReceiver();
        //实例化IntentFilter
		IntentFilter filter = new IntentFilter();
		filter.addAction("android.intent.action.MY_BROADCAST");
		//注册Receiver       
		registerReceiver(receiver, filter);
	}
	@Override
	protected void onPause() {
		super.onPause();
		//注销Receiver
		unregisterReceiver(receiver);
	}
}
这种注册方式与静态注册相反,不是常驻型的,也就是说广播会跟随程序的生命周期。

有序广播(Ordered Broadcast)
        有序广播比较特殊,它每次只发送到优先级较高的接收者那里,然后由优先级高的接受者再传播到优先级低的接收者那里,优先级高的接收者有能力终止这个广播。

public class TestReceiverActivity  extends Activity{
	private Button btnButton;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		btnButton= (Button) findViewById(R.id.btnButton);
		btnButton.setOnClickListener(new OnClickListener() {		
			@Override
			public void onClick(View v) {
				//发送广播  
		        Intent intent = new Intent

("com.igood.broadcastreceiver.test.MY_BROADCAST");  
		        intent.putExtra("msg", "TestReceiverActivity");  
		      //发送有序广播
		        sendOrderedBroadcast(intent, null);  	        
		        /*sendBroadcast(intent); //发送普通广播(无序广播)*/
			}
		});
	}
}
//FirstReceiver.java
public class FirstReceiver extends BroadcastReceiver {
	private static final String TAG = "orderedBroadcast"; 
	@Override
	public void onReceive(Context context, Intent intent) {
		String msg = intent.getStringExtra("msg");
		//显示接收到的广播
		Log.d(TAG, "FirstReceiver: " + msg);
		Bundle bundle = new Bundle();
		bundle.putString("msg", msg+" add FirstReceiver");//重新修改消息内容
		setResultExtras(bundle);
	}
}
//SecondReceiver.java
public class SecondReceiver extends BroadcastReceiver {
	private static final String TAG = "orderedBroadcast"; 
	@Override
	public void onReceive(Context context, Intent intent) {
		Bundle bundle = this.getResultExtras(false);//true:前一个广播没有结果时创建新的Bundle;false:不创建Bundle  
		String msg = bundle.getString("msg");
		//显示接收到的广播
		Log.d(TAG, "SecondReceiver: " + msg);
		bundle.putString("msg", msg+" add SecondReceiver");//重新修改消息内容
		setResultExtras(bundle);
		//停止广播,优先级比SecondReceiver低的广播接收器将收不到此广播
		abortBroadcast();
	}
}
//ThirdReceiver.java
public class ThirdReceiver extends BroadcastReceiver {
	private static final String TAG = "orderedBroadcast"; 
	@Override
	public void onReceive(Context context, Intent intent) {
		Bundle bundle = this.getResultExtras(false);//true:前一个广播没有结果时创建新的Bundle;false:不创建Bundle
		String msg = bundle.getString("msg");
		//显示接收到的广播
		Log.d(TAG, "ThirdReceiver: " + msg);
		bundle.putString("msg", msg+" add ThirdReceiver");//重新修改消息内容
		setResultExtras(bundle);
	}
}

        我们注意到,在FirstReceiver和SecondReceiver中最后都使用了setResultExtras方法将一个Bundle对象设置为结果集对象,传递到下一个接收者那里,这样以来,优先级低的接收者可以用getResultExtras获取到最新的经过处理的信息集合。
我们需要在AndroidMainfest.xml文件里为三个接收者注册广播:

        <receiver android:name=".FirstReceiver">
            <intent-filter android:priority="100">
                <action android:name="com.igood.broadcastreceiver.test.MY_BROADCAST"/>
                <category android:name="android.intent.category.DEFAULT" /> 
            </intent-filter>
        </receiver>
        
        <receiver android:name=".SecondReceiver">
            <intent-filter android:priority="90">
                <action android:name="com.igood.broadcastreceiver.test.MY_BROADCAST"/>
                <category android:name="android.intent.category.DEFAULT" /> 
            </intent-filter>
        </receiver>
        <receiver android:name=".ThirdReceiver">
            <intent-filter android:priority="80">
                <action android:name="com.igood.broadcastreceiver.test.MY_BROADCAST"/>
                <category android:name="android.intent.category.DEFAULT" /> 
            </intent-filter>
        </receiver>
        我们看到,现在这三个接收者的<intent-filter>多了一个android:priority属性,并且依次减小。这个属性的范围在-1000到1000,数值越大,优先级越高。优先级高的广播接收器先执行。(这里先执行FirstReceiver再执行SecondReceiver,最后执行ThirdReceiver)。在前一个执行的广播中设置结果值,传给下一个广播。也可以通过BroadcastReceiver.abortBroadcast()终止广播,后面的广播接收器不会得到执行。

运行效果如下:

由于在SecondReceiver里调用了abortBroadcast方法将广播进行终止,因此优先级比SecondReceiver低的ThirdReceiver接收器接收不到这条广播。

3、Notification和NotificationManager的使用

        Broadcast Receiver组件并没有提供可视化界面来显示广播信息。这里我们可以使用Notification和NotificationManager来实现可视化的信息显示。通过使用它们我们可以显示广播信息的内容、图标、声音以及震动等信息。

        使用Notification和NotificationManager比较简单,一般获得系统级的服务NotificationManager,然后实例化Notification,设置其属性,通过NotificationManager发出通知就可以了。

        我们下面定义一个TestReceiverActivity发出广播,顶一个MyReceiver类接收广播,当接收到广播后,启动一个服务DisplayService,在该类中使用Notification和NotificationManager来可视化显示广播通知。

//TestReceiverActivity.java
public class TestReceiverActivity  extends Activity{
	private Button btnButton;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		btnButton= (Button) findViewById(R.id.btnButton);
		btnButton.setOnClickListener(new OnClickListener() {		
			@Override
			public void onClick(View v) {
				//发送广播  
		        Intent intent = new Intent("com.igood.broadcastreceiver.test.MY_BROADCAST");  
		        intent.putExtra("msg", "TestReceiverActivity");  
		        //发送广播
		        sendBroadcast(intent, null);  	        
			}
		});
	}
}
//MyReceiver.java
public class MyReceiver extends BroadcastReceiver {
	private static final String TAG = "MyReceiver"; 
	@Override
	public void onReceive(Context context, Intent intent) {
		//显示接收到的广播
		Log.d(TAG, "MyReceiver----------------- ");
		Intent ien = new Intent();
		ien.putExtra("msg", "MyReceiver接收到广播,我有一个秘密告诉你.........");
		ien.setAction("com.igood.test.DisplayService");
		//启动Service
		context.startService(ien);
	}
}
//DisplayService.java
public class DisplayService extends Service{
	private Notification notify;
	private NotificationManager nm;
	public static final int ID = 1;
	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		//获得NotificationManager实例
		nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
		//实例化Notification
		notify = new Notification();
		//设置显示图标,该图标会在状态栏显示
		notify.icon = R.drawable.ic_launcher;
		//设置显示提示信息,该信息会在状态栏显示
		notify.tickerText = "你有新的消息";
		//显示时间
		notify.when = System.currentTimeMillis();
		
		Intent i = new Intent(this,TestReceiverActivity.class);
		PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
		//设置事件信息
		notify.setLatestEventInfo(this, "MyReceiver接收到广播.....",  intent.getStringExtra("msg"), pi);
		//发出通知
		nm.notify(ID,notify);
	}
	@Override
	public void onCreate() {
	}
	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}
}

        AndroidManifest.xml清单如下:

<activity android:name=".TestReceiverActivity"
	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=".MyReceiver">
	<intent-filter>
		<action android:name="com.igood.broadcastreceiver.test.MY_BROADCAST"/>
		<category android:name="android.intent.category.DEFAULT" /> 
	</intent-filter>
</receiver>
<service android:name=".DisplayService">
	<intent-filter>
		<action android:name="com.igood.test.DisplayService"/>
	</intent-filter>
</service>

运行效果如下:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值