BroadcastReceiver总结
16lz
2021-01-25
摘要:该文章介绍了LocalBroadManager和BroadcastReceiver,讲解如何使用本地广播,如何监听系统广播,如何创建具有自定义权限的广播,发送广播的方式等。 ============================================ 文章结构 1. BroadcastReceiver介绍 1.1 不跨进程的广播LocalBroadcastManager: 1.2 BroadcastReceiver: 1.2.2 自定义权限的BroadcastReceiver 1.2.3 利用广播开启服务 ============================================ 1. BroadcastReceiver介绍 个人理解: BroadcastReceiver是安卓的四大组件之一,有接受广播机制,相对应就有发送广播机制。安卓下,通过该机制,使得消息能在各个组件间、各个进程间传递,起到邮递员的作用。 1.1 不跨进程的广播LocalBroadcastManager: 当我们 发送的广播不需要跨应用发送时,我们可以 使用LocalBroadcastManager,关于它,官网API的描述是:
(2)在Manifest.xml文件的注册:
当系统有拨号的时候,我们这个广播接收器就可以收到拨号广播,并获取拨号号码。同理,只要监听相对应的系统广播,都可以获得广播里面的数据,比如接收短信等。 1.2.2 自定义权限的BroadcastReceiver 系统的广播有它自己的权限,我们只要知道它的权限就可以进行监听。同样地,我们也可以自定义具有自己权限的广播接收者,建立自己的发送接受广播机制。 实现步骤如下: (1)建立一个继承BroadcastReceiver的类,实现onReceive方法; (2)在Manifest声明一个权限,用 ,并使用该权限,用 ; (3)注册Receiver元素,添加Intent-filter以及其Action(添加权限和优先级自选); (4)在Activity中用sendBroadcast或sendOrderedBroadcast发送广播,广播携带的Intent的action符合自定义的permission标签的name属性则可被收到。 例子: 建立三个广播接收者,分别有不同的优先级,和权限,但是他们的Intent-filter的Action都相同。先发送一个不带权限的广播且符合三者的Action,三者都收到,因为优先级不同,收到的顺序也不同, 优先级越高越快收到。接下来发送带要验证权限,发送带权限的广播,只有符合权限的才收到。 再建立一个FinalReceiver, 发送带FinalReceiver的广播,在FinalReceiver收到中止广播,结果FinalReceiver还是收到了。 (1)建立三个广播接收者的Java代码:
(2)在Manifest注册三个广播接收者:
(3)另外开一个工程发送广播,这样除了验证上述结果,还可以做到验证可以跨进程发送:
(4)结果: 发送不带权限的广播: 因为DIYBR1优先级比DIYBR2和DIYBR3高,DIYBR1中止了广播,所以DIYBR2和DIYBR3收不到,但是FinalBR是跟发送广播同进程,所以可以收到,即使它的优先级比DIYBR1低也不会受影响。所以证明abortBroadcast只能中止本进程的广播,发到其他进程的中止不了。 发送带权限的广播: 这个时候就只有符合权限的DIYBR1才能收到。 发送一个规定权限和最终广播接受者的广播: 可以看到只有权限符合的DIYBR1才能收到,而FinalReceiver权限不符合也能收到,这里还有说明一点,FinalReceiver即使广播之前被优先级高的中止了还是能收到。 1.2.3 利用广播开启服务 我们开启服务一般是startService或是bindService,但是有时候我们也可以通过服务内部提供的广播来开启服务并获取服务的方法。 注意:BroadcastReceiver是四大组件唯一一个可以动态注册的! 操作步骤如下: (1)建立一个继承Service的类并在Manifest.xml注册,该类内部定义一个继承BroadcastReceiver的内部类,在其onReceive使用Service的方法; (2)在服务的onCreate方法实例化该BroadcastReceiver子类,并使用registerReceiver来注册该BroadcastReceiver对象,添加Intent-filter; (3)新建一个Activity,发送符合(2)中广播接收者Action的广播,如果(2)中的广播接收到符合的Intent的广播,则会执行onReceive中服务的方法。 具体代码如下: (1)包含BroadcastReceiver内部类的Service类:
(2)发送广播的Activity:
(3)结果: 可以看见发送一个广播就可以调用服务内部openService这个方法,相当于开启了服务。
Class Overview
Helper to register for and send broadcasts of Intents to local objects within your process. This is has a number of advantages over sending global broadcasts with sendBroadcast(Intent)
:
You know that the data you are broadcasting won't leave your app, so don't need to worry about leaking private data.
It is not possible for other applications to send these broadcasts to your app, so you don't need to worry about having security holes they can exploit.
It is more efficient than sending a global broadcast through the system.
1 2 3 4 5 6 7 8 9 10 11 | public class ListenDial extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String num = getResultData(); Log.i( "cth" , "监听到拨打电话信息,拨打号码为:" + num); //监听用户拨打的电话,可获取号码或更改拨号的号码。 //需要的权限是android.permission.PROCESS_OUTGOING_CALL //该receiver的Intent-filter的action必须设为android.action.NEW_OUTGOING_CALL } } |
1 2 3 4 5 6 7 8 9 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | public class DIYBR1 extends BroadcastReceiver { /* * 定义一个广播接收者,监听的行为cth.android.DIYBR,收到后终端广播。 * 它需要在Manifest注册,name和Intent-filter都需要设置, * 权限和优先级可选设置。 * * * */ @Override public void onReceive(Context arg0, Intent arg1) { if (arg1.getAction() == "cth.android.DIYBR" ) { Log.i( "cth" , "DIYBR1接收到" ); abortBroadcast(); //中止广播 } } } public class DIYBR2 extends BroadcastReceiver { @Override public void onReceive(Context arg0, Intent arg1) { if (arg1.getAction() == "cth.android.DIYBR" ) { Log.i( "cth" , "DIYBR2接收到" ); } } } public class DIYBR3 extends BroadcastReceiver { @Override public void onReceive(Context arg0, Intent arg1) { if (arg1.getAction() == "cth.android.DIYBR" ) { Log.i( "cth" , "DIYBR3接收到" ); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | < receiver android:name = ".DIYBR1" android:permission = "cth.authority" > < intent-filter android:priority = "100" > < action android:name = "cth.android.DIYBR" /> intent-filter > receiver > < receiver android:name = ".DIYBR2" android:permission = "null" > < intent-filter android:priority = "1000" > < action android:name = "cth.android.DIYBR" /> intent-filter > receiver > < receiver android:name = ".DIYBR3" android:permission = "null" > < intent-filter android:priority = "10" > < action android:name = "cth.android.DIYBR" /> intent-filter > receiver > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction( "cth.android.DIYBR" ); //设置Action //发送不带权限的广播,在清单文件中Intent-filter的action的name值符合该Action的能收到。 sendBroadcast(intent); //直接发送一个无权限的广播 //发送一个规定权限的广播,只有持有该权限的广播接受者才能收到该广播 sendOrderedBroadcast(intent, "cth.authority" ); //发送一个规定权限和最终广播接受者的广播, //当第三个参数规定了resultRecevier,则表示该广播发出,该resultRecevier一定会接收到, //不管它的优先级是怎么样的,不管广播是否中途被中断,不管它是否符合第二个参数所规定的权限。 sendOrderedBroadcast(intent, "cth.authority" , new FinalBR(), null , 0 , null , null ); //注意:自定义的权限在Manifest要用 } }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | package cth.android.BRopenService; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.util.Log; import android.widget.Toast; public class MyService extends Service { private ServiceCR receiver; @Override public IBinder onBind(Intent arg0) { return null ; } @Override public void onCreate() { Log.i( "cth" , "服务创建" ); IntentFilter filter = new IntentFilter(); filter.addAction( "cth.android.BRopenService" ); //为Intent-filter添加Action receiver = new ServiceCR(); registerReceiver(receiver, filter); //动态注册广播 Log.i( "cth" , "广播接收器已注册" ); super .onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i( "cth" , "服务创建" ); return super .onStartCommand(intent, flags, startId); } private void openService () { Toast.makeText(getApplicationContext(), "服务已开启" ,Toast.LENGTH_SHORT).show(); } @Override public void onDestroy() { super .onDestroy(); unregisterReceiver(receiver); //取消广播的注册 } private class ServiceCR extends BroadcastReceiver { //服务中定义广播接收者的内部类 @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if (intent.getAction() == "cth.android.BRopenService" ) { Log.i( "cth" , "接收到广播" ); openService(); //使用服务中的方法 } } } } |
1 2 3 4 5 6 7 8 9 10 | button = (Button) findViewById(R.id.button); button.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setAction( "cth.android.BRopenService" ); //发送符合Service中BroadcastReceiverAction的广播 sendBroadcast(intent); } }); |
更多相关文章
- android:第二个anroid项目 电话拨号器
- 腾讯云-视频直播(android集成)
- Android自启动应用添加和限制
- Android(安卓)ContentProvider简介
- Android中短信的广播接收问题
- [Android(安卓)Pro] service中显示一个dialog 或者通过windowman
- Android(安卓)10动态申请读写权限
- Android(安卓)SD卡中压缩包解压(ZIP文件)
- android短信开发