在我们上学的时候都知道,学校领导经常通过学习的喇叭广播通知同学们,在Android系统中也是同样道理,由Android系统或者应用发出相应的广播,应用收到广播之后做出相应的动作。Android 中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收到自己所关心的广播内容,这些广播可能是来自于系统的,也可能是来自于其他应用程序的。Android 提供了一套完整的 API,允许应用程序自由地发送和接收广播。下面介绍广播的用法:
一、发送广播:Android 中的广播主要可以分为两种类型,标准广播和有序广播。
1、标准广播:标准广播(Normal broadcasts)是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。标准广播的工作流程如下所示:
发送标准广播方法:sendBroadcast(intent);
2、有序广播:则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广
播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。有序广播的工作流程如下所示:
发送有序广播方法:sendOrderedBroadcast();
二、广播接收器:接收Android系统和应用发出的广播,需要有一个广播接收器(BroadcastReceiver)来接收处理,我们只需继承BroadcastReceiver 然后重写
onReceive() 即可。如下代码所示:
三、在发送广播之前,我们需要注册广播,注册广播又分为两种 ,一种是静态注册,另一种是动态注册:
1、动态注册广播:动态注册广播就是在代码中注册广播。如:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("这里填写你要监听的广播动作");
myReceiver = new MyReceiver();registerReceiver(networkChangeReceiver, intentFilter);
在页面销毁时候记得注销广播:
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver );
}
2、静态注册广播:动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大的优势,但是它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的。静态注册广播这种方法可以让程序在未启动的情况下就能接收到广播。如:
这时候你要写一个广播接受类去处理,并且在AndoridManifest.xml 配置文件里面经常注册,<intent - filter> 里面的 action 就是监听发出这个广播的动作,action 可以添加多个。
3、实践是最好的老师,下面我们写个demo 来验证一下以上两种方式(demo 的实现方式是 一个Button按键发出一条动态注册过的自定义的广播,接收器接收到之后Toast 显示表示接收成功来验证动态注册广播,另一个就是静态注册监听设备的系统中网络设备变化情况的广播,通过开关 设备的网络开关,然后接收器收到Toast 显示表示接收成功来验证静态注册广播):
MainActivity.class 代码如下:
public class MainActivity extends AppCompatActivity {
private String TAG = MainActivity.class.getName();
private MyReceiver myReceiver;
private IntentFilter intentFilter;
private final String ACTION_MY_BORADCAST = "android.intent.action.MY_BROADCAST";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
registerBroadCast();
}
/**
* 注册自定义的广播
*/
private void registerBroadCast(){
intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_MY_BORADCAST);
myReceiver = new MyReceiver();
registerReceiver(myReceiver,intentFilter);
}
@OnClick(R.id.btn_send_static_broadcast)
public void onClick() {
Intent intent = new Intent(ACTION_MY_BORADCAST);
sendBroadcast(intent);
}
/**
* 广播接收器
*/
class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(ACTION_MY_BORADCAST)){
Log.d(TAG,"收到自定义广播...");
Toast.makeText(context, "收到自定义广播...", Toast.LENGTH_SHORT).show();
}
}
}
}
AdnroidManifest.xml 配置如下:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"></action>
</intent-filter>
</receiver>
MyBroadcastReceiver.class 接收器是静态注册中监听系统中网络变化的接收器。代码如下:
public class MyBroadcastReceiver extends BroadcastReceiver {
private String TAG = MyBroadcastReceiver.class.getName();
@Override
public void onReceive(Context context, Intent intent) {
// TODO your thing
if(intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE")){
ConnectivityManager connectionManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable()) {
Toast.makeText(context, "网络发生变化,网络可用...",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "网络发生变化,网络不可用",
Toast.LENGTH_SHORT).show();
}
}
}
}
4 、 看下gif 效果:
四、前面我们发送和接收的广播全部都是属于系统全局广播,即发出的广播可以被其他任何的任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播。这样就很容易会引起安全性的问题,比如说我们发送的一些携带关键性数据的广播有可能被其他的应用
程序截获,或者其他的程序不停地向我们的广播接收器里发送各种垃圾广播。为了能够简单地解决广播的安全性问题,Android 引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。本地广播的用法并不复杂,主要就是使用了一个 LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法。代码如下所示:
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
// 获取实例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
// 注册本地广播监听器
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
// 发送本地广播
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast",
Toast.LENGTH_SHORT).show();
}
}