Android第一行代码-广播

作者 汪小祯 日期 2016-08-10
Android第一行代码-广播

今天上午不要练车,所以继续来码学习笔记

动态注册监听网络变化

创建两个实例

IntentFilter用于监听广播,NetworkChangeReceiver用于监听广播变化(应该是这样)

private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;

新建一个NetworkChangeReceiver类继承BroadcastReceiver

当网络变化时onReceive()方法就会执行

class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();
}

在onDestroy()中进行取消注册

@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}

在onCreate()中添加代码

实例化IntentFilter(),并给它添加一个android.net.conn.CONNECTIVITY_CHANGE值,因为当网络变化时系统广播的正是android.net.conn.CONNECTIVITY_CHANGE。
接着调用registerReceiver方法进行注册,将networkChangeReceiver和intentFilter传值进去
这样当intentFilter监听的广播出现时,就会执行networkChangeReceiver中的onReceive(我猜是这样)

intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver,intentFilter);

准备的告诉用户当前是否有网络

通过getSystemService()方法得到ConnectivityManager的实例,然后调用getActivityNetworkInfo()方法得到NetworkInfo的实例,接着调用NetworkInfo的isAvailable()方法,就可以判断是否有网络了。
在onReceive()中加入以下代码

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();
}

静态注册实现开机启动

动态注册的广播接收器可以自由的控制注册和注销,但是也有致命的缺点就是,必须在程序启动后才可以接受广播,如果想要在程序未启动的情况下就可以接受广播,就需要使用静态注册的方法了。
新建一个BootCompleteReceiver类继承BroadcastReceiver

public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
}
}

修改AndroidManifest.xml文件

加入权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

一个新的标签,所有的静态注册的广播接收器都是在这里进行注册,它的用法和类似,先是通过android:name来指定具体注册哪一个广播接收器,接着在标签里加入想要接收的广播,比如系统启动时会发生一条”android.intent.action.BOOT_COMPLETED”,这里在这里添加。

<receiver android:name=".BootCompleteReceiver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

小米4真机调试这一步失败,也许因为安全措施的原因?虚拟机测试通过。

发送自定义广播

新建一个MyBroadcastReceiver继承BroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceive",
Toast.LENGTH_SHORT).show();
}
}

在AndroidManifest.xml中进行注册

<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>

在MainActivity中添加代码

可以放在按钮事件里面执行

Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);

发生有序广播

一个应用程序发出的广播,另一个应用程序应该也可以接收到

新建另一个APP项目,然后新建一个AnotherBroadcastReceiver类

public class AnotherBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in AnotherBroadcastReceiver",
Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}

在AndroidManifest.xml中注册

<receiver
android:name=".AnotherBroadcastReceiver"
android:priority="100" >
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>

开始测试

先运行新建的APP,然后再打开上一个APP,发生广播,会发现弹出两个Toast。

小米4真机调试这一步失败,也许因为安全措施的原因?虚拟机测试通过。

发生有序广播

改动一行代码,第一个参数仍是Intent,第二个参数是null

Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendOrderedBroadcast(intent,null);

设定先后顺序

<receiver android:name=".MyBroadcastReceiver">
<intent-filter android:priority="100">
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>

android:priority中的数值越大优先级越高

设置是否允许扩散

在MyBroadcastReceiver中

public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceive",
Toast.LENGTH_SHORT).show();
abortBroadcast(); //截断广播
}
```
## 使用本地广播
广播只在本地应用程序中进行。
### 创建两个实例
IntentFilter用于监听广播,NetworkChangeReceiver用于监听广播变化(应该是这样)
``` java
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;

新建一个NetworkChangeReceiver类继承BroadcastReceiver

当网络变化时onReceive()方法就会执行

class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast",
Toast.LENGTH_SHORT).show();
}}

在onDestroy()中进行取消注册

@Override
protected void onDestroy(){
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}

在onCreate()中添加代码

通过LocalBroadcastManager的getInstance()方法得到它的一个实例,然后在注册广播接收器的时候调用LocalBroadcastManager的registerReceiver()方法。

localBroadcastManager = LocalBroadcastManager.getInstance(this);
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
```
### 发送广播
发送广播的时候,调用LocalBroadcastManager的sendBroadcast()方法
``` java
Intent intent = new Intent(
"com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);