Android内置了很多系统级别的广播,可以在应用程序中通过监听这些广播来得到各种系统的状态信息。比如手机开机完成后会发出一条广播,电池的电量发生变化会发出一条广播,时间或时区发生改变也会发出一条广播等等。如果想要接收到这些广播,就需要使用广播接收器(BroadcastReceiver)。
创建广播接收器
public class NewBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//接收到广播后的具体逻辑
}
}
}
创建一个广播接收器需要新建一个类继承BroadcastReceiver,并重写onReceive()
方法。这样当有广播到来时,onReceive()
方法就会得到执行,具体的逻辑就可以在这个方法中处理。
注册广播接收器
广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够收到该广播,并在内部处理相应的逻辑。注册广播的方式一般有两种,在代码中注册和在AndroidManifest.xml中注册,其中前者也被称为动态注册,后者也被称为静态注册。
1. 动态注册
示例:监听网络变化
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//动态注册
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册
unregisterReceiver(networkChangeReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectionManager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable()) {
Toast.makeText(context, "Network is available",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Network is unavailable",
Toast.LENGTH_SHORT).show();
}
}
}
}
创建NetworkChangeReceiver
在MainActivity中定义了一个内部类NetworkChangeReceiver继承BroadcastReceiver,并重写onReceive()
方法。在onReceive()
方法中,首先通过Context的getSystemService()
方法得到了ConnectivityManager的实例,这是一个系统服务类,专门用于管理网络连接的。然后调用它的getActiveNetworkInfo()
方法可以得到NetworkInfo的实例,接着调用NetworkInfo的isAvailable()
方法,就可以判断出当前是否有网络,最后通过Toast的方式对用户进行提示。
注册广播接收器
在 onCreate()
方法中,首先创建了一个IntentFilter的实例,并给它添加了一个值为
android.net.conn.CONNECTIVITY_CHANGE
的action,因为该值正是当网络状态发生变化时系统发出的广播的值。也就是说广播接收器想要监听什么广播,就在这里添加相应的action就行了。接下来创建了一个NetworkChangeReceiver的实例,然后调用registerReceiver()
方法进行注册,将NetworkChangeReceiver的实例和IntentFilter的实例都传了进去,这样NetworkChangeReceiver就会收到所有值为android.net.conn.CONNECTIVITY_CHANGE
的广播,也就实现了监听网络变化的功能。
注销广播接收器
最后要记得,动态注册的广播接收器一定都要取消注册才行,这里我们是在onDestroy()
方法中通过调用
unregisterReceiver()
方法来实现的。
添加查询系统网络状态的权限
Android系统为了保证应用程序的安全性做了规定,如果程序需要访问一些系统的关键性信息,必须在配置文件中声明权限才可以,否则程序将会直接崩溃。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
2. 静态注册
动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大的优势,但是它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()
方法中的。而静态注册的广播接收器可以让程序在未启动的情况下就能接收到广播。
示例:让程序接收一条开机广播
创建BootCompleteReceiver
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
}
}
这里不再使用内部类的方式来定义广播接收器,因为稍后需要在AndroidManifest.xml中将这个广播接收器的类名注册进去
注册广播接收器
<receiver android:name=".BootCompleteReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
首先通过android:name
来指定具体注册哪一个广播接收器,然后在<intent-filter>
标签里加入想要接收的广播就行了,由于Android系统启动完成后会发出一条值android.intent.action.BOOT_COMPLETED
的广播,因此在这里添加了相应的action。
添加监听系统开机广播的权限
<uses-permission android:name=" android.permission.RECEIVE_BOOT_COMPLETED"/>
注意:不要在onReceive()
方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的,当onReceive()
方法运行了较长时间而没有结束时,程序就会报错。因此广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动一个服务等。