Android——BroadcastReceiver (一)

来源:互联网 发布:大数据的理解和认识 编辑:程序博客网 时间:2024/06/05 17:35

Android——BroadcastReceiver (一)

参考:《第一行代码》

Broadcast Receiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。
Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要数练掌握Android系统提供的一个开发利器,那就是BroadcastReceiver。下面我们就对BroadcastReceiver逐一地分析和演练,了解和掌握它的各种功能和用法。

首先

广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收器就能够收到该广播,并在内部处理相应逻辑。

注册广播的方式一般有两种:
(1)在代码中注册(动态注册)
(2)在AndroidManifest.xml中注册(静态注册)。

那么该如何创建一个广播接收器呢?其实只需要新建一个类,让它继承BroadcastReceiver,并重写父类的onReceive()方法就行了。当有广播来到时,onReceive()就会得到执行,具体逻辑就可以在这个方法中处理。

我们先看看如何静态注册,这里我们演示一个小demo 静态注册监听网络变化

1.静态注册监听网络变化

打开Android studio 创建一个BroadcastTest 项目
创建一个NetworkChangeReceiver.java 并继承BroadcastReceiver 和重写它父类的方法onReceive()方法

代码如下:

package com.example.pc.broadcasttest;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.widget.Toast;/** * Created by PC on 2017/11/5. */public class NetworkChangeReceiver extends BroadcastReceiver {    //每当网络状态发生变化时,onReceive()都会得到执行。    @Override    public void onReceive(Context context, Intent intent) {        Toast.makeText(context,"network changes",Toast.LENGTH_SHORT).show();    }}

静态注册是在AndroidManifest.xml文件中配置的,我们就来为NetworkChangeReceiver 注册一个广播地址:

代码如下:

<!--在application里面添加--><receiver android:name=".NetworkChangeReceiver">            <intent-filter>                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>            </intent-filter></receiver>

配置了以上信息之后,只要是android.net.conn.CONNECTIVITY_CHANGE这个地址的广播,NetworkChangeReceiver 都能够接收的到。注意,这种方式的注册是常驻型的,也就是说当应用关闭后,如果有广播信息传来,NetworkChangeReceiver 也会被系统调用而自动运行。

注意:静态注册的广播,必需单独成一个类,不能像动态注册那样写在某个界面里。否则当监听到网络状态变化的时候,会抛出异常。

运行一下程序:

首先你会在注册完成的时候收到一条广播,尝试着开关WIFI或者数据连接来启动和禁用网络,你就会看到有Toast提醒你网络发生了变化。

那么为什么是action的值是android.net.conn.CONNECTIVITY_CHANGE呢?

因为当网络状态发生变化时,系统发出的正是这条值为android.net.conn.CONNECTIVITY_CHANGE的广播,也就是说我们的广播接收器想要监听什么广播,就在这里设置就可以了。

当然其中有一些action是不支持静态注册的:

    android.intent.action.SCREEN_ON

    android.intent.action.SCREEN_OFF

    android.intent.action.BATTERY_CHANGED

    android.intent.action.CONFIGURATION_CHANGED

    android.intent.action.TIME_TICK

2.动态注册监听网络变化

我们先把之前AndroidManifest.xml配置的先注释了,然后再修改MainActivity中的代码:

package com.example.pc.broadcasttest;import android.content.IntentFilter;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;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);    }}

1.什么是IntentFilter ?

IntentFilter翻译成中文就是“意图过滤器”,主要用来过滤隐式意图。当用户进行一项操作的时候,Android系统会根据配置的 “意图过滤器” 来寻找可以响应该操作的组件,服务。

在这里IntentFilter()就是设置 action,等同于配置文件里面Intent-filter设置一样。

2.addAction?

我们的广播接收器想要监听什么广播,就可以在addAction设置相应的action,从而达到动态监听。
3.然后调用registerReceiver()方法进行注册 registerReceiver参数如下:

//receiver:传递一个广播接收器//filter:一个意图过滤器public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {}

应该很好理解。这里就不多说了。

最后

要记得,动态注册广播接收器一定都要取消注册才行。
在这里我们onDestroy()调用unregisterReceiver()方法来实现。

我们运行一下程序:
首先你会在注册完成的时候收到一条广播,然后按下Home键回到主界面(不能按Back键,否则onDestroy()方法会执行),接下来尝试着开关WIFI或者数据连接来启动和禁用网络,你就会看到有Toast提醒你网络发生了变化。

不过,只是提醒网络发生了变化还不够人性化,最好是能准确地告示用户当前是有网络还是没有网络,因此我们还需要对上面的代码进行进一步的优化。
修改NetworkChangeReceiver.java中的代码,如下:

package com.example.pc.broadcasttest;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.widget.Toast;/** * Created by PC on 2017/11/5. */public class NetworkChangeReceiver extends BroadcastReceiver {    //每当网络状态发生变化时,onReceive()都会得到执行。    @Override    public void onReceive(Context context, Intent intent) {        //通过getSystemService()方法得到ConnectivityManager的实例        //这是一个服务类,专门用于管理网络连接的。        ConnectivityManager connectionMannager = (ConnectivityManager)                context.getSystemService(Context.CONNECTIVITY_SERVICE);        //getActiveNetworkInfo() 获取当前连接可用的网络        NetworkInfo networkInfo = connectionMannager.getActiveNetworkInfo();        //isAvailable()  判断当前网络是否可用        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();        }    }}

1.通过getSystemService()方法得到ConnectivityManager的实例。这是一个服务类,专门用于管理网络连接的。
具体的用法可以看这篇ConnectivityManager和NetworkInfo详解
2.然后调用它的getActiveNetworkInfo()方法获取当前连接可用的网络。

3.接着调用NetworkInfo的isAvailable()方法 判断当前网络是否可用。

4.最后我们还是通过Toast的方式对用户进行提示。

5.另外,这里有声明权限才可以。否则程序将会直接崩溃。Android系统是为了保护用户设备的安全和隐私,做了严格的规定。

打开AndroidManifest.xml文件,在里面加入如下权限就可以访问系统网络状态了:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.pc.broadcasttest">    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>    .....</manifest>

现在重新运行一下程序。
然后按下Home键——>设置——>开关WIFI或者数据连接
就可以看见网络是否可以的Toast提示。

注意:

不要再onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的,当onReceive()方法运行了较长时间而没有结束时,程序就会报错。因此广播接收器更多是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动一个服务等。

感谢阅读。下次再见。

原创粉丝点击