Android 中内置了很多系统级别的广播,我们可以在应用程序中通过监听这些广播来得到各种系统的状态信息。比如手机开机完成后发出一条广播,电池的电量发生变化后发出一条广播,时间或时区发生改变发出一条广播等等。如果想要接收到这些广播,就需要使用到广播接收器。
注册广播的方式有两种,在代码中注册(动态注册)和在 AndroidManifest.xml 中注册(静态注册)。
1 动态注册
创建一个广播接收器:即新建一个类,让它继承自 BroadcastReceiver, 并重写父类的 onReceive() 方法。当有广播到来时 ,onReceive() 方法就会得到执行, 具体的逻辑编写在这个方法中。
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);
}
/**
* “网络变化”的广播接收器
*/
private class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager manager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo=manager.getActiveNetworkInfo();
if(networkInfo!=null&&networkInfo.isAvailable()){
Toast.makeText(context,"网络可用",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"网络不可用",Toast.LENGTH_SHORT).show();
}
}
}
}
我们在 MainActivity 中定义了一个内部类 NetworkChangeReceiver,它继承自 BroadcastReceiver ,并重写了 onReceive 方法。这样只要网络状态发生变化,onReceive 方法就会得到执行。
我们在 onReceive 方法中,通过 getSystemService() 方法得到 ConnectivityManager 的实例(管理网络连接),这样就可以判断出当前是否有网络咯。
我们在 onCreate 方法中,创建了 IntentFilter 实例,用于监听网络状态的变化。广播接收器想要监听什么广播,就在此添加相应的 Action。最后调用 registerReceiver 方法进行注册。
要记住,动态注册的广播一定要在 onDestroy() 方法中取消哦O(∩_∩)O~
如果程序需要进行一些对用户来说比较敏感的操作,就必须在配置文件中声明权限,否则程序会直接崩溃。所以我们要访问系统的网络状态,就必须先声明权限,打开 AndroidManifest.xml :
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
运行程序,然后按下 Home 键 → 按下 Menu 键 → System settings → Data usage 进入数据使用详情界面 , 关闭 Cellular Data 会弹出网络不可用的提示 :
重新打开 Cellular Data 又会弹出网络可用的提示:
2 静态注册
动态注册的广播接收器可以自由地控制注册与注销,这在灵活性方面有很大的优势,但它也存在缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在 onCreate() 方法中的。
而使用静态注册的方式可以让程序在未启动的情况下接收到广播。
我们让程序接收一条关机广播,收到这条广播时会执行 onReceive() 方法。在 Android Studio 中可以这样创建广播接收器:右击包名
→ New → Other → Broadcast Receiver,弹出窗口:
这里为广播接收器命名,Exported 表示是否允许此广播接收本程序以外的广播,Enabled 表示是否启用这个广播接收器。
点击 Finish 完成创建后,修改 ShutdownReceiver 中的代码:
public class ShutdownReceiver extends BroadcastReceiver {
public ShutdownReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "系统正在关机", Toast.LENGTH_LONG).show();
}
}
静态的广播接收器一定要在 AndroidManifest.xml 文件中注册才可以使用,不过如果使用 Android Studio 来创建的广播接收器,会自动帮我们完成注册:
<receiver
android:name=".ShutdownReceiver"
android:enabled="true"
android:exported="true"></receiver>
所有的静态广播接收器都是在这里注册的。
我们还要对 AndroidManifest.xml 文件进行修改,为 <intent-filter>
标签添加相应的 Action:
<receiver
android:name=".ShutdownReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_SHUTDOWN" />
</intent-filter>
</receiver>
注意:不要在 onReceive() 方法中添加过多的逻辑或者进行耗时操作,因为广播接收器中是不允许开启线程的,当 onReceive() 方法运行了较长时间而没有结束时,程序就会报错。因此,广播接收器主要用于打开程序其他组件的作用,比如创建一条状态栏的通知。