Presentation is loading. Please wait.

Presentation is loading. Please wait.

第9章 BroadcastReceiver的使用

Similar presentations


Presentation on theme: "第9章 BroadcastReceiver的使用"— Presentation transcript:

1 第9章 BroadcastReceiver的使用
QQ号: QQ群: (Android编程入门) 网络资源:

2 主要内容

3 9.1 BroadcastReceiver介绍 广播是一种广泛运用在应用程序之间传输信息的机制,而BroadcastReceiver是对发送出来的广播进行过滤接收并响应的一类组件。 BroadcastReceiver 本质上是一种全局监听器,用于监听系统全局的广播消息,因此它可以非常方便地实现系统中不同组件之间的通信。 BroadcastReceiver用于接收指定的广播,广播的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcat()来实现的。通常一个广播可以被订阅了该Intent的多个广播接收者所接收,如同一个广播台,可以被多位听众收听一样。

4 9.1 BroadcastReceiver介绍 BroadcastReceiver自身并不实现图形用户界面,但是当它收到某个消息后,可以启动Activity作为响应,或者通过NotificationManager提醒用户,或者启动Service等等。 启动BroadcastReceiver通常需要以下两步: 1、创建Intent,指定BroadcastReceiver的特征; 2、调用Context的sendBroadcast()(发送普通广播)或sendOrderedBroadcast()(发送有序广播)方法来发送广播,触发指定的BroadcastReceiver。 当应用程序发出一个广播之后,所有匹配该Intent的BroadcastReceiver都有可能被启动。

5 9.1 BroadcastReceiver介绍 开发自己的BroadcastReceiver与开发其他组件一样,只需要继承Android中的BroadcastReceiver基类,然后实现里面的相关方法即可。 public class MyBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { } 在onReceive()方法中,接收了一个Intent的参数,通过它可以获取广播所携带的数据。

6 9.1 BroadcastReceiver介绍 创建完广播接收者后,并不能马上使用,还必须为它注册一个指定的广播,就如同我们有了收音机后,还必须选择收听哪个频道一样。在Android中为BroadcastReceiver注册广播有两种方式:静态注册和动态注册。 静态注册:是指在AndroidManifest.xml文件中进行注册。 <receiver android:name=".MyBroadcastReceiver"> <intent-filter > <action android:name="iet.jxufe.cn.android.myBroadcastReceiver"> </action> </intent-filter> </receiver>

7 9.1 BroadcastReceiver介绍 动态注册:需要在代码中动态的指定广播地址并注册,通常是在Activity或Service中调用ContextWrapper的registerReceiver(BroadcastReceiver receiver,IntentFilter filter)方法进行注册。 MyBroadcastReceiver myBroadcastReceiver=new MyBroadcastReceiver(); IntentFilter filter=new IntentFilter("iet.jxufe.cn.android.myBroadcastReceiver"); registerReceiver(myBroadcastReceiver, filter);

8 9.1 BroadcastReceiver介绍 注册完成后,即可接收相应的广播消息。一旦广播(Broadcast)事件发生后,系统就会创建对应的BroadcastReceiver实例,并自动触发它的onReceive()方法,onReceive()方法执行完后,BroadcastReceiver的实例就会被销毁。 如果BroadcastReceiver的onReceive()方法不能在10秒内执行完成,Android会认为该程序无响应。所以不要在广播接收者的onReceive()方法里执行一些耗时的操作,否则会弹出ANR(Application No Response)对话框。

9 注意 如果确实需要根据广播来完成一项比较耗时的操作,则可以考虑通过Intent启动一个Service来完成该操作。不应考虑使用新线程去完成耗时的操作,因为BroadcastReceiver本身的生命周期极短,可能出现的情况是子线程可能还没有结束,BroadcastReceiver就已经退出了。 如果广播接收者所在的进程结束了,虽然该进程内还有用户启动的新线程,但由于该进程内不包含任何活动组件,因此系统可能在内存紧张时优先结束线程。这样就可能导致BroadcastReceiver启动的子线程不能执行完成。

10 9.2 发送广播的两种方式 广播接收者注册好了以后,并不会直接运行,必须在接收广播后才会被调用,因此,必须首先发送广播,在Android中提供了两种发送广播的方式,调用Context的sendBroadcast()或sendOrderedBroadcast()方法。  sendBroadcast(Intent intent):用于发送普通广播,其中intent参数表示接收该广播的广播接收者所需要满足的条件,以及广播所传递的数据; sendOrderedBroadcast(Intent intent, String receiverPermission):用于发送有序广播,intent参数同上,receiverPermission表示接收该广播的许可权限。

11 9.2 发送广播的两种方式 普通广播(Normal Broadcast):是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高。但缺点是接收者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的传播。 有序广播(Ordered Broadcast):该广播的接收者将按预先声明的优先级依次接收广播。有序广播接收者可以终止广播的传播(通过调用abortBroadcast()方法),广播的传播一旦终止,后面的接收者就无法接收到广播。另外,广播的接收者可以将数据传递给下一个接收者(通过setResultExtras(Bundle bundle)方法)。

12 发送有序广播示例 编写三个广播接收器类,分别为: ABroadcastReceiver、 BBroadcastReceiver、 CBroadcastReceiver,内容为显示相应提示信息 public class ABroadcastReceiver extends BroadcastReceiver { 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.LENGTH_SHORT).show(); } public class CBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Toast.makeText(context, “C is Invoked!” , Toast.LENGTH_SHORT).show(); }

13 在清单文件中注册广播接收器 <receiver android:name=".ABroadcastReceiver" >
<intent-filter android:priority="100" > <action android:name="iet.jxufe.cn.android.OrderedBroadcastTest" > </action> </intent-filter> </receiver> <receiver android:name=".BBroadcastReceiver" > <intent-filter android:priority="20" > <receiver android:name=".CBroadcastReceiver" > <intent-filter android:priority="50" > 尝试改变优先级大小,观看效果

14 发送普通广播和发送有序广播对比 public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent=new Intent("iet.jxufe.cn.android.OrderedBroadcastTest"); sendBroadcast(intent); } 发送普通广播 public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent=new Intent("iet.jxufe.cn.android.OrderedBroadcastTest"); sendOrderedBroadcast(intent,null); } 发送有序广播

15 有序广播中,广播接收器间传递数据 ABroadcastReceiver广播接收器接收广播后,向其中添加数据。
public class ABroadcastReceiver extends BroadcastReceiver { public void onReceive(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); } BBroadcastReceiver广播接收器接收广播后,获取数据。 public class BBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Bundle bundle=getResultExtras(true); Toast.makeText(context, “B is Invoked!”+“得到的信息”+bundle.getString(“A”), Toast.LENGTH_SHORT).show(); }

16 9.3 案例—音乐播放器 基于Service的音乐播放器
程序的音乐将会由后台运行的Service组件负责播放,当后台的播放状态发生改变时,程序将会通过发送广播通知前台Activity更新界面;当用户单击前台Activity的界面按钮时,系统将通过发送广播通知后台Service来改变播放状态。 此程序中包含两个BroadcastReceiver(广播接收器)和一个Service服务。 一个广播接收器用于接收播放状态发生改变的广播; 一个广播接收器用于接收歌曲播放完成时发送的广播。

17 9.3 案例—音乐播放器

18 9.3 案例—音乐播放器 开发步骤 1、Activity的界面布局,在Activity中内嵌一个广播接收器ActivityReceiver,用于接收来自Service的广播。 2、为相应的按钮添加单击事件,在单击事件中发送广播; 3、开发音乐播放的服务(MusicService),并在服务中内嵌一个广播接收器ServiceReceiver,用于接收来自Activity的广播; 4、分别编写广播接收器的业务逻辑处理;

19 案例分析

20 9.3 音乐播放器示例 在MainActivity中执行一些初始化的操作,例如获取界面控件、添加事件处理、注册广播接收器、启动服务等。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); stop = (ImageButton) findViewById(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);//为播放和停止按钮添加事件监听 activityReceiver = new ActivityReceiver();//创建广播接收器 IntentFilter intentFilter = new IntentFilter( "iet.jxufe.cn.ActivityReceiver");//广播接收器接收广播的过滤条件 registerReceiver(activityReceiver, intentFilter);//注册广播接受器 Intent intent = new Intent(MainActivity.this, MusicService.class);//显式调用服务 startService(intent);//启动服务 }

21 音乐播放器示例 Activity中的广播接收器,用于改变界面中播放按钮的背景图片,以及显示的歌曲的信息。
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.setText(titles[current]);//显示歌曲信息 author.setText(authors[current]);//显示演唱者信息 } switch (update) {//判断音乐播放状态 case 0x11://处于未开始状态,则显示播放按钮 play.setImageResource(R.drawable.play); break; case 0x12://处于播放状态,则显示暂停按钮 play.setImageResource(R.drawable.pause); case 0x13://处于暂停状态,则显示播放按钮 default: 音乐播放器示例 Activity中的广播接收器,用于改变界面中播放按钮的背景图片,以及显示的歌曲的信息。

22 音乐播放器示例 播放和停止按钮的事件处理监听器。
private class MyListener implements OnClickListener {//播放和停止按钮的事件处理 public void onClick(View v) { Intent intent = new Intent(“iet.jxufe.cn.ServiceReceiver”); //广播所触发的接收器的条件 switch (v.getId()) { case R.id.play://单击的播放按钮 intent.putExtra("control", 1);//传递值为1 break; case R.id.stop://单击停止按钮 intent.putExtra("control", 2);//传递值为2 default: } sendBroadcast(intent);//发送广播

23 音乐播放器示例 音乐播放服务类必须实现的方法,以及初始化。
public IBinder onBind(Intent intent) {//继承服务基类的抽象方法 return null; } public void onCreate() {//执行服务的初始化操作 serviceReceiver = new ServiceReceiver();//创建广播接收器 IntentFilter intentFilter = new IntentFilter( "iet.jxufe.cn.ServiceReceiver");//广播接收器触发的条件 registerReceiver(serviceReceiver, intentFilter);//注册广播接收器 super.onCreate();

24 音乐播放器示例 Service中的广播接收器,用于控制音乐的播放、暂停以及停止。
public class ServiceReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { int control = intent.getIntExtra("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||status==0x13){//如果处于播放或暂停状态 mediaPlayer.stop();//停止音乐播放 status=0x11;//改变音乐当前的状态 default: break; } Intent sendIntent=new Intent("iet.jxufe.cn.ActivityReceiver"); sendIntent.putExtra("update",status);//传递当前状态值 sendIntent.putExtra("current",current);//传递当前播放的音乐的序号 sendBroadcast(sendIntent);//发送广播 音乐播放器示例 Service中的广播接收器,用于控制音乐的播放、暂停以及停止。

25 音乐播放器示例 public void prepareAndPlay(int index){//准备和播放音乐 try{
mediaPlayer=MediaPlayer.create(this,musics[index]);//创建媒体播放器 mediaPlayer.setOnCompletionListener(new OnCompletionListener() { //监听音乐播放结束事件 public void onCompletion(MediaPlayer mp) { current++;//播放下一首 if(current==musics.length){//如果已是最后一首,则播放第一首 current=0; } Intent sendIntent=new Intent("iet.jxufe.cn.ActivityReceiver"); sendIntent.putExtra("current",current);//传递当前播放的音乐序号 sendBroadcast(sendIntent);//发送广播 prepareAndPlay(current);//准备和播放当前歌曲 }); if(mediaPlayer!=null){ mediaPlayer.stop(); mediaPlayer.prepare(); mediaPlayer.start();//播放音乐 }catch(Exception ex){ ex.printStackTrace(); 音乐播放器示例

26 案例分析

27 音乐播放器示例 注意事项 1、音乐播放存在三种状态:未开始、正在播放、暂停,可以使用常量进行标记,0x11代表未开始;0x12代表正在播放;0x13代表暂停。 2、需在清单文件中对播放音乐的服务进行注册; 3、为了使广播接收器能够方便的访问Activity或Service中的成员,建议将广播接收器作为它们的内部类; 4、音乐播放需要使用到MediaPlayer类;

28


Download ppt "第9章 BroadcastReceiver的使用"

Similar presentations


Ads by Google