广播:系统级别的消息通知
目录
5.1简介
标准广播:异步执行,接收广播信息没有顺序之分。效率高,无法被截断。
有序广播:同步执行,同一时刻只有一个广播接收器能收到广播消息,有接收顺序之分。前面的广播接收器能截断后面的广播接收器。
5.2接收系统广播
5.2.1动态注册
在代码中注册,新建一个类继承BroadcastReceiver,重写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);//取消注册
}
class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);//得到系统服务类ConnectivityManager
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isAvailable()){//判断是否有网络
Toast.makeText(context,"network is avaliable",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"network is unavaliable",Toast.LENGTH_SHORT).show();
}
}
}
}
IntentFilter:过滤器,筛选含特定字符串的内容。
ConnectivityManager:回答有关网络连接状态的查询的类。它还会在网络连接发生变化时通知应用程序。通过调用获取此类的实例 Context.getSystemService(Context.CONNECTIVITY_SERVICE)
。
这个类的主要职责是:
- 监控网络连接(Wi-Fi,GPRS,UMTS等)
- 在网络连接发生变化时发送广播意图
- 当与网络的连接丢失时,尝试“故障转移”到另一个网络
- 提供允许应用程序查询可用网络的粗粒度或细粒度状态的API
networkinfo:描述网络连接状态。
动态注册的广播接受器一定要取消注册。unregisterReceiver()
如果程序需要进行对用户比较敏感的操作,就必须在配置文件中声明权限。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
5.2.2静态注册
必须要在AndroidManifest.xml中注册
com.example.broadcasttest->New->Other->Broadcast Receiver(Exported:是否允许这个广播接收器接受本程序以外的广播,Enable:是否启用这个广播接收器)
public class BootCompleteReceiver extends BroadcastReceiver {
public BootCompleteReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context,"Boot Complete", Toast.LENGTH_LONG).show();
}
}
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<intent-filter></intent-filter>添加过滤器
不要在onReceive()中添加过多的逻辑和进行比较耗时的操作,广播接收器中不允许开启线程,当onReceive()运行长时间没有结束时,程序会报错。
5.3发送自定义广播
5.3.1发送标准广播
新建一个类用于接受反馈广播接收器MyBroadcastReceiver
静态广播在AndroidManifest中注册广播接收器
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
接受的广播为MY_BROADCAST
在MainActivity中发送广播:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
}
});
此处广播用Intent传播的,还可以携带一些信息。
5.3.2发送有序广播
发送广播改为sendOrderedBroadcast(intent,null);
第一个参数表示发送的广播字段,第二个参数与权限相关。
将AndroidManifest中注册的广播接受器设置权限:<intent-filter android:priority="100"></intent-filter>
优先级高的广播接收器可以选择截断广播:在onReceiv()中添加abortBroadcast();
5.4使用本地广播
使用LocalBroadcastManager管理广播
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;//过滤器
private LocalReceiver localReceiver;//本地广播接收器
private LocalBroadcastManager localBroadcastManager;//本地广播管理器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager = LocalBroadcastManager.getInstance(this);//获取实例
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,intentFilter);//注册本地广播
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(localReceiver);//取消注册
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in local broadcast",Toast.LENGTH_LONG).show();
}
}
}
LocalBroadcastManager.getInstance(this);//获取本地广播管理器实例
LocalBroadcastManager.registerReceiver(localReceiver,intentFilter);//注册本地广播接收器
本地广播无法通过静态注册方式接收。