Android 广播

广播机制简介

Android中的广播机制很灵活,Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样改程序就只会接收到自己所关心的广播内容。发送广播可以通过Intent,接收广播需要广播接收器(Broadcast Receiver)

  • 标准广播:所有的广播接收器几乎都会在同一时刻接收到此广播消息,异步执行,没有任何先后顺序,效率比较高但无法被截断
  • 有序广播:同步执行的广播,广播发出后,同一时刻只有一个广播接收器能够收到这条广播消息,当一个广播接收器的逻辑执行完毕后才会传递给下一个广播接收器,优先级高的广播接收器可以先收到消息,还可以截断广播消息
系统广播

开机完成,电量变化,时区改变等活动发生时系统都会发送一条广播

创建广播接收器
  • 1.新建一个类继承自BroadcastReceiver
  • 2.重写onReceive()方法
动态注册一个监听网络变化的程序

修改MainActivity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MainActivity extends AppCompatActivity {
//需要一个InterFilter对象和一个BroadcastReceiver对象
private IntentFilter intentFilter;
private NetWorkChangeReceiver netWorkChangeReceiver;

public MainActivity() {
}

@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(netWorkChangeReceiver); //动态注册的广播必须取消注册
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//当网络发生变化时,系统发出的正是android.net.conn.CONNECTIVITY_CHANGE的广播
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
netWorkChangeReceiver = new NetWorkChangeReceiver();
registerReceiver(netWorkChangeReceiver, intentFilter);
}

//新建一个类,继承自BroadcastReceiver
private class NetWorkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"网络环境发生变化", Toast.LENGTH_SHORT).show();
}
}
}
监听网络状态
  • 声明网络访问权限
1
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • 在API21后原来的NetWorkInfo类被判为过时,不再推荐使用,增加了一个类NetworkCapabilities,其中有很多对于网络性能的描述,可以通过ConnectivityManager获得描述当前网络的NetworkCapabilities

  • 新的指示网络的连接方式包括如下状态

    • TRANSPORT_CELLULAR(蜂窝网络,即数据流量)
    • TRANSPORT_WIFI(wifi)
    • TRANSPORT_BLUETOOTH(蓝牙)
    • TRANSPORT_ETHERNET(以太网)
    • TRANSPORT_VPN(vpn)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); //获取ConnectivityManager实例
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
    if (connectivityManager != null) {
    Network activeNetwork = connectivityManager.getActiveNetwork();
    NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(activeNetwork); //获取NetworkCapabilities对象
    if (capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
    if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
    Log.d("NET", "已连接wifi网络");
    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)) {
    Log.d("NET", "已连接蓝牙网络");
    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
    Log.d("NET", "已连接以太网");
    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
    Log.d("NET", "已连接VPN");
    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
    Log.d("NET", "正在使用数据流量");
    }
    } else {
    Log.d("NET", "网络未连接");
    }
    }
    }
静态注册实现开机启动

Android系统开机后,会发送一个 BOOT_COMPLETED 的广播

接收BOOT_COMPLETED广播,需要权限,该权限:android.Manifest.permission#RECEIVE_BOOT_COMPLETED。

收到开机广播时在onReceive()中执行启动活动

  • Android Studio提供了快捷方式创建广播接收器,右键单击包名,新建->other->Broadcast Receiver

  • Exported表示是否允许该广播接受去接收本程序之外的广播,Enabled表示是否启用这个广播接收器

  • 修改刚创建的BootCompleteReceiver
1
2
3
4
5
6
7
public class BootCompleteReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"已经检测到开机了!",Toast.LENGTH_LONG).show();
}
}
  • 打开AndroidManifest.xml,发现AS自动帮我们完成了广播接收器的代码:
1
2
3
4
5
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
</receiver>
  • 不过这还不够,我们还要声明启动权限以及加入Boot_COMPLETED的权限:
1
2
3
4
5
6
7
8
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/> <!--action标签内容即为要接收的广播-->
</intent-filter>
</receiver>
1
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  • 运行重启模拟器:

0%