简介
当某个特定事件发生时发送广播通知那些对该事件感兴趣的应用。可以是本应用,比如音乐软件常有的前台服务在通知栏里切歌都是用的广播;也可以跨应用,比如:系统中的锁屏,网络变更,耳机按钮点击都会有广播,但是需要注意各个版本之间系统广播的差异,因为Android越来越注重用户隐私,一些系统广播可能无法获取想要的信息。
发送广播
- LocalBroadcastManager.sendBroadcast:用于当前应用内部发送广播,接收器也在本应用,这样更安全也更高效,因为不用跨进程。
//新建意图
Intent intent = new Intent();
intent.setAction("com.dean.broadcast.MUSIC_NEXT");
intent.putExtra("control","next");
//发送广播
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
- Context.sendOrderedBroadcast:通过intent-filter中的priority来控制按顺序一个一个发送广播,如果priority一样则顺序随机。当前接收器处理完广播后可以向下传递结果,也可以阻止广播向下传递。
Intent intent = new Intent();
intent.setAction("com.dean.broadcast.MUSIC_NEXT");
intent.putExtra("control","next");
mContext.sendBroadcast(intent);
- Context.sendBroadcast:随机顺序全体发送广播,效率高,但是无法传递结果也无法中止。
Intent intent = new Intent();
intent.setAction("com.dean.broadcast.MUSIC_NEXT");
intent.putExtra("control","next");
mContext.sendOrderedBroadcast(intent);
接收广播
- 创建广播接收类,类继承自BroadcastReceiver,并且在onReceive方法中处理广播内容
- 注册广播
- 静态注册:在AndroidManifest.xml中注册
<receiver android:name=".services.MusicBroadcastReceiver">
<intent-filter >
<action android:name="android.intent.action.MEDIA_BUTTON"/>
</intent-filter>
</receiver>
- 动态声明
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
registerReceiver(musicBroadcast, intentFilter);
注:
- 如果广播接收器接收到广播,onReceive()方法会被执行,这时该应用的进程就是前台进程,几乎不会被回收。如果是静态注册的,并且广播发射时应用没有在运行,这时应用会启动,因此许多系统广播都改为了动态注册。
- onReceive()执行完成后,进程会被降低优先级,如果是静态注册被启动的应用可能会被立即终止
- 在onReceive内处理广播时,不应有耗时操作,因为onReceive是在主线程中运行的,即使新开线程,也会在onReceive执行完后系统回收进程时一并回收在onReceive派生出的线程
- 如果要提高进程存活度,在接收到广播后多执行一段时间,可以在onReceive内直接使用goAsync()或者使用JobScheduler 调度 JobService
@Override
public void onReceive(Context context, Intent intent) {
InnerTask innerTask = new InnerTask(goAsync(), "a");
innerTask.execute();
}
private static class InnerTask extends AsyncTask<String, Integer, Integer>{
PendingResult pendingResult;
String params;
public InnerTask(PendingResult pendingResult, String params){
this.pendingResult = pendingResult;
this.params = params;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.d(LOG_TAG, "广播任务开始");
}
@Override
protected Integer doInBackground(String... strings) {
Log.d(LOG_TAG, "广播任务进行中");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
}
@Override
protected void onPostExecute(Integer s) {
super.onPostExecute(s);
pendingResult.finish();
Log.d(LOG_TAG, "广播任务完成");
}
}
执行结果
19:36:00.982 31798-31798/com.mh.smart D/MusicBroadcastReceiver: 广播任务开始
19:36:00.988 31798-509/com.mh.smart D/MusicBroadcastReceiver: 广播任务进行中
19:36:05.993 31798-31798/com.mh.smart D/MusicBroadcastReceiver: 广播任务完成
实例:耳机插拔广播接收
新建广播接收类
public class MusicBroadcastReceiver extends BroadcastReceiver {
private static final String LOG_TAG = MusicBroadcastReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
//耳机插拔
if (Intent.ACTION_HEADSET_PLUG.equals(intent.getAction())){
if (intent.hasExtra("state")){
if (intent.getIntExtra("state", 0) == 0){
Log.d(LOG_TAG, "耳机拔出");
}else if (intent.getIntExtra("state", 0) == 1){
Log.d(LOG_TAG, "耳机插入");
}
}
}
}
}
注册广播:需要动态
private void registerMusicBroadcast(){
musicBroadcast = new MusicBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
registerReceiver(musicBroadcast, intentFilter);
}
及时关闭:一般看在哪注册,oncreate注册就是ondestory销毁。onresume注册就在onpause销毁
unregisterReceiver(musicBroadcast);