1、第6章 Android广播接收器 (BroadcastReceiver),网络资源:http:/ BroadcastReceiver介绍,广播是一种广泛运用在应用程序之间传输信息的机制,而BroadcastReceiver是对发送出来的广播进行过滤接收并响应的一类组件。,BroadcastReceiver 本质上是一种全局监听器,用于监听系统全局的广播消息,因此它可以非常方便地实现系统中不同组件之间的通信。,BroadcastReceiver用于接收指定的广播,广播的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcat()来实现的
2、。通常一个广播可以被订阅了该Intent的多个广播接收者所接收,如同一个广播台,可以被多位听众收听一样。,6.1 BroadcastReceiver介绍,BroadcastReceiver自身并不实现图形用户界面,但是当它收到某个消息后,可以启动Activity作为响应,或者通过NotificationManager提醒用户,或者启动Service等等。,启动BroadcastReceiver通常需要以下两步:1、创建Intent,指定BroadcastReceiver的特征;2、调用Context的sendBroadcast()(发送普通广播)或sendOrderedBroadcast()(
3、发送有序广播)方法来发送广播,触发指定的BroadcastReceiver。当应用程序发出一个广播之后,所有匹配该Intent的BroadcastReceiver都有可能被启动。,6.1 BroadcastReceiver介绍,开发自己的BroadcastReceiver与开发其他组件一样,只需要继承Android中的BroadcastReceiver基类,然后实现里面的相关方法即可。,public class MyBroadcastReceiver extends BroadcastReceiver public void onReceive(Context context, Intent
4、intent) ,在onReceive()方法中,接收了一个Intent的参数,通过它可以获取广播所携带的数据。,6.1 BroadcastReceiver介绍,创建完广播接收者后,并不能马上使用,还必须为它注册一个指定的广播,就如同我们有了收音机后,还必须选择收听哪个频道一样。在Android中为BroadcastReceiver注册广播有两种方式:静态注册和动态注册。,静态注册:是指在AndroidManifest.xml文件中进行注册。,6.1 BroadcastReceiver介绍,MyBroadcastReceiver myBroadcastReceiver=new MyBroadc
5、astReceiver(); IntentFilter filter=new IntentFilter(“.android.myBroadcastReceiver“); registerReceiver(myBroadcastReceiver, filter);,动态注册:需要在代码中动态的指定广播地址并注册,通常是在Activity或Service中调用ContextWrapper的registerReceiver(BroadcastReceiver receiver,IntentFilter filter)方法进行注册。,6.1 BroadcastReceiver介绍,注册完成后,即可接收
6、相应的广播消息。一旦广播(Broadcast)事件发生后,系统就会创建对应的BroadcastReceiver实例,并自动触发它的onReceive()方法,onReceive()方法执行完后,BroadcastReceiver的实例就会被销毁。,如果BroadcastReceiver的onReceive()方法不能在10秒内执行完成,Android会认为该程序无响应。所以不要在广播接收者的onReceive()方法里执行一些耗时的操作,否则会弹出ANR(Application No Response)对话框。,注意,如果确实需要根据广播来完成一项比较耗时的操作,则可以考虑通过Intent启动
7、一个Service来完成该操作。不应考虑使用新线程去完成耗时的操作,因为BroadcastReceiver本身的生命周期极短,可能出现的情况是子线程可能还没有结束,BroadcastReceiver就已经退出了。,如果广播接收者所在的进程结束了,虽然该进程内还有用户启动的新线程,但由于该进程内不包含任何活动组件,因此系统可能在内存紧张时优先结束线程。这样就可能导致BroadcastReceiver启动的子线程不能执行完成。,6.2 发送广播的两种方式,广播接收者注册好了以后,并不会直接运行,必须在接收广播后才会被调用,因此,必须首先发送广播,在Android中提供了两种发送广播的方式,调用Co
8、ntext的sendBroadcast()或sendOrderedBroadcast()方法。 sendBroadcast(Intent intent):用于发送普通广播,其中intent参数表示接收该广播的广播接收者所需要满足的条件,以及广播所传递的数据;sendOrderedBroadcast(Intent intent, String receiverPermission):用于发送有序广播,intent参数同上,receiverPermission表示接收该广播的许可权限。,6.2 发送广播的两种方式,普通广播(Normal Broadcast):是完全异步的,可以在同一时刻(逻辑上)
9、被所有接收者接收到,消息传递的效率比较高。但缺点是接收者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的传播。,有序广播(Ordered Broadcast):该广播的接收者将按预先声明的优先级依次接收广播。有序广播接收者可以终止广播的传播(通过调用abortBroadcast()方法),广播的传播一旦终止,后面的接收者就无法接收到广播。另外,广播的接收者可以将数据传递给下一个接收者(通过setResultExtras(Bundle bundle)方法)。,发送有序广播示例,public class ABroadcastReceiver extends Broa
10、dcastReceiver public void onReceive(Context context, Intent intent) Toast.makeText(context, “A is Invoked!”, Toast.LENGTH_SHORT).show(); ,public class BBroadcastReceiver extends BroadcastReceiver public void onReceive(Context context, Intent intent) Toast.makeText(context, “B is Invoked!” , Toast.LE
11、NGTH_SHORT).show(); ,编写三个广播接收器类,分别为: ABroadcastReceiver、 BBroadcastReceiver、 CBroadcastReceiver,内容为显示相应提示信息,public class CBroadcastReceiver extends BroadcastReceiver public void onReceive(Context context, Intent intent) Toast.makeText(context, “C is Invoked!” , Toast.LENGTH_SHORT).show(); ,在清单文件中注册广
12、播接收器,尝试改变优先级大小,观看效果,public class MainActivity extends Activity public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent=new Intent(“.android.OrderedBroadcastTest“);sendOrderedBroadcast(intent,null); ,发送普通广播和发送有序广播对比,发送有序广
13、播,public class MainActivity extends Activity public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent=new Intent(“.android.OrderedBroadcastTest“);sendBroadcast(intent); ,发送普通广播,public class BBroadcastReceiver extends Broa
14、dcastReceiver public void onReceive(Context context, Intent intent) Bundle bundle=getResultExtras(true);Toast.makeText(context, “B is Invoked!”+“得到的信息”+bundle.getString(“A”), Toast.LENGTH_SHORT).show(); ,有序广播中,广播接收器间传递数据,public class ABroadcastReceiver extends BroadcastReceiver public void onReceive
15、(Context context, Intent intent) Toast.makeText(context, “A is Invoked!“, Toast.LENGTH_SHORT).show();Bundle bundle=new Bundle();bundle.putString(“A”, “the message of A”);/在广播中添加数据setResultExtras(bundle); ,ABroadcastReceiver广播接收器接收广播后,向其中添加数据。,BBroadcastReceiver广播接收器接收广播后,获取数据。,6.3 案例音乐播放器,基于Service的
16、音乐播放器程序的音乐将会由后台运行的Service组件负责播放,当后台的播放状态发生改变时,程序将会通过发送广播通知前台Activity更新界面;当用户单击前台Activity的界面按钮时,系统将通过发送广播通知后台Service来改变播放状态。,此程序中包含两个BroadcastReceiver(广播接收器)和一个Service服务。一个广播接收器用于接收播放状态发生改变的广播;一个广播接收器用于接收歌曲播放完成时发送的广播。,6.3 案例音乐播放器,6.3 案例音乐播放器,开发步骤1、Activity的界面布局,在Activity中内嵌一个广播接收器ActivityReceiver,用于接
17、收来自Service的广播。2、为相应的按钮添加单击事件,在单击事件中发送广播;3、开发音乐播放的服务(MusicService),并在服务中内嵌一个广播接收器ServiceReceiver,用于接收来自Activity的广播;4、分别编写广播接收器的业务逻辑处理;,案例分析,6.3 音乐播放器示例,public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);stop = (ImageButton) findVi
18、ewById(R.id.stop);play = (ImageButton) findViewById(R.id.play);title = (TextView) findViewById(R.id.title);author = (TextView) findViewById(R.id.author);/根据Id找到相应的控件MyListener myListener = new MyListener();play.setOnClickListener(myListener);stop.setOnClickListener(myListener);/为播放和停止按钮添加事件监听activit
19、yReceiver = new ActivityReceiver();/创建广播接收器IntentFilter intentFilter = new IntentFilter(“.ActivityReceiver“);/广播接收器接收广播的过滤条件registerReceiver(activityReceiver, intentFilter);/注册广播接受器Intent intent = new Intent(MainActivity.this, MusicService.class);/显式调用服务startService(intent);/启动服务 ,在MainActivity中执行一些
20、初始化的操作,例如获取界面控件、添加事件处理、注册广播接收器、启动服务等。,音乐播放器示例,public class ActivityReceiver extends BroadcastReceiver public void onReceive(Context context, Intent intent) int update = intent.getIntExtra(“update“, -1);/获取音乐播放状态int current = intent.getIntExtra(“current“, -1);/获取当前播放的音乐的序号if (current = 0) title.setTe
21、xt(titlescurrent);/显示歌曲信息author.setText(authorscurrent);/显示演唱者信息switch (update) /判断音乐播放状态case 0x11:/处于未开始状态,则显示播放按钮play.setImageResource(R.drawable.play);break;case 0x12:/处于播放状态,则显示暂停按钮play.setImageResource(R.drawable.pause);break;case 0x13:/处于暂停状态,则显示播放按钮play.setImageResource(R.drawable.play);break
22、;default:break; ,Activity中的广播接收器,用于改变界面中播放按钮的背景图片,以及显示的歌曲的信息。,音乐播放器示例,private class MyListener implements OnClickListener /播放和停止按钮的事件处理public void onClick(View v) Intent intent = new Intent(“.ServiceReceiver”);/广播所触发的接收器的条件switch (v.getId() case R.id.play:/单击的播放按钮intent.putExtra(“control“, 1);/传递值为1
23、break;case R.id.stop:/单击停止按钮intent.putExtra(“control“, 2);/传递值为2break;default:break;sendBroadcast(intent);/发送广播,播放和停止按钮的事件处理监听器。,音乐播放器示例,public IBinder onBind(Intent intent) /继承服务基类的抽象方法return null; public void onCreate() /执行服务的初始化操作serviceReceiver = new ServiceReceiver();/创建广播接收器IntentFilter intent
24、Filter = new IntentFilter(“.ServiceReceiver“);/广播接收器触发的条件registerReceiver(serviceReceiver, intentFilter);/注册广播接收器super.onCreate(); ,音乐播放服务类必须实现的方法,以及初始化。,音乐播放器示例,public class ServiceReceiver extends BroadcastReceiver public void onReceive(Context context, Intent intent) int control = intent.getIntEx
25、tra(“control“, -1);/获取是播放还是停止的值switch (control) case 1:/如果单击的是播放,则需要判断当前音乐播放的状态if(status=0x11)/如果是未开始状态repareAndPlay(current); status=0x12;else if(status=0x12)/如果是播放状态mediaPlayer.pause(); status=0x13;else if(status=0x13)/如果是暂停状态mediaPlayer.start(); status=0x12; break;case 2:/如果单击的是停止if(status=0x12|s
26、tatus=0x13)/如果处于播放或暂停状态mediaPlayer.stop();/停止音乐播放status=0x11;/改变音乐当前的状态 break;default: break; Intent sendIntent=new Intent(“.ActivityReceiver“); sendIntent.putExtra(“update“,status);/传递当前状态值sendIntent.putExtra(“current“,current);/传递当前播放的音乐的序号sendBroadcast(sendIntent);/发送广播 ,Service中的广播接收器,用于控制音乐的播放、
27、暂停以及停止。,音乐播放器示例,public void prepareAndPlay(int index)/准备和播放音乐trymediaPlayer=MediaPlayer.create(this,musicsindex);/创建媒体播放器mediaPlayer.setOnCompletionListener(new OnCompletionListener() /监听音乐播放结束事件 public void onCompletion(MediaPlayer mp) current+;/播放下一首if(current=musics.length)/如果已是最后一首,则播放第一首current
28、=0;Intent sendIntent=new Intent(“.ActivityReceiver“);sendIntent.putExtra(“current“,current);/传递当前播放的音乐序号sendBroadcast(sendIntent);/发送广播prepareAndPlay(current);/准备和播放当前歌曲);if(mediaPlayer!=null)mediaPlayer.stop();mediaPlayer.prepare();mediaPlayer.start();/播放音乐catch(Exception ex)ex.printStackTrace(); ,案例分析,音乐播放器示例,注意事项1、音乐播放存在三种状态:未开始、正在播放、暂停,可以使用常量进行标记,0x11代表未开始;0x12代表正在播放;0x13代表暂停。2、需在清单文件中对播放音乐的服务进行注册;3、为了使广播接收器能够方便的访问Activity或Service中的成员,建议将广播接收器作为它们的内部类;4、音乐播放需要使用到MediaPlayer类;,
copyright@ 2008-2019 麦多课文库(www.mydoc123.com)网站版权所有
备案/许可证编号:苏ICP备17064731号-1