Android BroadcastReceiver 接收广播
Boardcast 广播,就是那种村口的大喇叭或者学校的大喇叭,记得读初中的时候是寄宿,学校的大喇叭总是广播 "xxx,你爸妈来找你啦,快来值班室...",所有人都会听到,当然只有 xxx 会去值班室,因为他是它们的孩子啊
今天我们要学习的 BroadcastReceiver
也和这个类似,是 Android APP 之间的大喇叭,是通信的一个手段
Android 系统自己在很多时候都会发送广播,比如电量低或者充足,刚启动完,插入耳机,输入法改变等, 发生这些时间,系统都会发送广播,这个叫系统广播
每个 APP 都会收到,如果想让一个应用在接收到广播的时候做一些操作,比如:系统开机后,偷偷后台跑服务~哈哈,这个时候只需要为应用注册一个用于监视开机的 BroadcastReceiver
,当接收到开机广播就做写偷偷摸摸的勾当
两种广播类型
-
标准广播
完全异步执行的广播,发出广播后,所有的广播接收器几乎会在同一时刻收到这条广播通知
-
有序广播
同步执行的一种广播,发出广播后,同一时间只有一个广播接收者能收到,当这个广播接收者的逻辑执行完后,才会传递到下一个广播接收者
前一个广播接收者还可以截断广播,让广播不会继续传递
接收系统广播
接收广播之前,先要为我们的 APP 注册广播接收器
Android 提供了两种注册广播的方式 动态 与 静态
-
动态注册
就是在
Java
代码中指定Intent-filter
,然后添加不同的Action
想监听什么广播就写什么 Action
动态注册需要应用程序启动后才能接收广播信息
注意: 动态注册的广播一定要调用
unregisterReceive()
取消广播注册 -
静态注册
在
AndroidManifest.xml
设置<receiver>
就可以让 APP 在未启动的情况下接收到广播
动态注册
我们先来看看最后效果图,这是一个 网络状态广播 的例子,演示的接收 网络状态变更 的广播
一开始是没有联网的,即打开飞行模式,然后取消飞行模式,过了一会儿就出现 Toast提示
-
创建一个 空的 Android 项目
cn.twle.android.DynamicBroadcast
-
自定义一个 BroadcastReceiver,在
onReceive()
方法中完成广播要处理的事务,在MainActivity.java
同一目录下创建文件MsBroadcastReceiver.java
package cn.twle.android.dynamicbroadcast; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class MsBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"网络状态发生改变~",Toast.LENGTH_SHORT).show(); } }
-
修改 MainActivity.java 动态注册广播
package cn.twle.android.dynamicbroadcast; import android.content.IntentFilter; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { MsBroadcastReceiver mReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mReceiver = new MsBroadcastReceiver(); IntentFilter itFilter = new IntentFilter(); itFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); registerReceiver(mReceiver, itFilter); } //别忘了将广播取消掉 @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(mReceiver); } }
动态注册有个缺点就是需要程序启动才可以接收广播,假如我们需要程序没有启动也能接收广播的话,那么就需要注册静态广播
静态注册
我们以接收开机广播为例讲解如何 静态注册 广播
-
创建一个 空的 Android 项目
cn.twle.android.StaticBroadcast
-
在
MainActivity.java
目录下创建MsBootCompleteReceiver
,重写onReceive
完成事务处理package cn.twle.android.staticbroadcast; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class MsBootCompleteReceiver extends BroadcastReceiver { private final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED"; @Override public void onReceive(Context context, Intent intent) { if (ACTION_BOOT.equals(intent.getAction())) Toast.makeText(context, "开机完毕~", Toast.LENGTH_LONG).show(); } }
-
在
AndroidManifest.xml
中对该MsBootCompleteReceiver
进行注册,添加开机广播的intent-filter
<receiver android:name=".MsBootCompleteReceiver"> <intent-filter> <action android:name = "android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
同时加上
android.permission.RECEIVE_BOOT_COMPLETED
的权限<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
然后重启下手机会发现过了一会儿,就会弹出开机完毕这个 Toast 的了
Android 4.3 以上的版本,是允许将程序安装到 SD 卡上的,假如你的程序是安装在 SD 上的,就会收不到开机广播
注意事项
广播更多的时候扮演的是一个打开其它组件的角色,比如启动 Service, Notification 提示 , Activity 等
不要在广播里添加过多逻辑或者进行任何耗时操作
因为在广播中是不允许开辟线程的,当 onReceiver()
方法运行较长时间 ( 超过 10 秒 ) 还没有结束的话,那么程序会报错