android开发之 广播机制

   广播接收器(BroadcastReceiver)

 Android中的广播主要可以分为两种类型,标准广播和有序广播。 

 

   标准广播(Normal broadcasts):

 是一种完全异步执行的广播,在广播发出之后,所有的 广播接收器几乎都会在同一时刻接收到这条广播消息,

因此它们之间没有任何先后顺序可 言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。

 

 有序广播(Orderedbroadcasts):

 则是一种同步执行的广播,在广播发出之后,同一时刻 只会有一个广播接收器能够收到这条广播消息,当这个

广播接收器中的逻辑执行完毕后,广 播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广

播接收器就可以先 收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器

就无法收到广播消息了。  

 想要接收到广播,就需要使用广播接收器了。

注册广播的方式一般有两种,在代码中注册和在 AndroidManifest.xml中注册,其中前者也被称为动态注册,

后者也被称为静态注册。 

这是就收广播的方法:

下面是 动态注册监听网络变化

 

  那么该如何创建一个广播接收器呢?其实只需要新建一个类,让它继承自BroadcastReceiver, 并重写父类的

onReceive()方法就行了。这样当有广播到来时,onReceive()方法就会得到执行, 具体的逻辑就可以在这个方

法中处理。 那我们就先通过动态注册的方式编写一个能够监听网络变化的程序,借此学习一下广播 接收器的基本

用法吧。新建一个 BroadcastTest项目,然后修改 MainActivity中的代码:

public class MainActivity extends Activity {
    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) {
            Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();
        }
    }
}

        可以看到,我们在 MainActivity 中定义了一个内部类 NetworkChangeReceiver,这个类 是继承自

BroadcastReceiver的,并重写了父类的 onReceive()方法。这样每当网络状态发生变 化时,onReceive()

方法就会得到执行,这里只是简单地使用 Toast提示了一段文本信息。 然后观察 onCreate()方法,首先我们

创建了一个 IntentFilter的实例,并给它添加了一个 值为 android.net.conn.CONNECTIVITY_CHANGE

的 action,为什么要添加这个值呢?因为 当网络状态发生变化时,系统发出的正是一条值为

android.net.conn.CONNECTIVITY_ CHANGE 的广播,也就是说我们的广播接收器想要监听什么广播,

就在这里添加相应的 action就行了。接下来创建了一个 NetworkChangeReceiver的实例,然后调用

registerReceiver() 方法进行注册,将 NetworkChangeReceiver 的实例和 IntentFilter 的实例都传了进去

,这样 NetworkChangeReceiver就会收到所有值为android.net.conn.CONNECTIVITY_CHANGE的广 播,

也就实现了监听网络变化的功能。 最后要记得,动态注册的广播接收器一定都要取消注册才行,这里我们是在

onDestroy() 方法中通过调用 unregisterReceiver()方法来实现的。 整体来说,代码还是非常简单的,现在

运行一下程序。首先你会在注册完成的时候收到 一条广播,然后按下 Home键回到主界面(注意不能按 Back键

,否则 onDestroy()方法会执 行) ,接着按下 Menu键→Systemsettings→Datausage进入到数据使用详情

界面,然后尝试着 开关 MobileData来启动和禁用网络,你就会看到有 Toast提醒你网络发生了变化。 不过只

是提醒网络发生了变化还不够人性化,最好是能准确地告诉用户当前是有网络还 是没有网络,因此我们还需要

对上面的代码进行进一步的优化。修改 MainActivity中的代码:

public class MainActivity extends Activity {
  

    class NetworkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connectionManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfonetworkInfo = 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();
            }
        }
    }
} 

 在onReceive()方法中,首先通过get getSystemService()方法得到了 ConnectivityManager的

实例,这是一个系统服务类,专门用于管理网络连接的。然后调用它的 getActiveNetworkInfo() 

方法可以得到 NetworkInfo的实例,接着调用 NetworkInfo的 isAvailable()方法,就可以判断

出当前是否有网络了,最后我们还是通过 Toast的方式对用户进行提示。 

另外要注意:

   Android系统为了保证应用程序的安全性做了 规定,如果程序需要访问一些系统的关

键性信息,必须在配置文件中声明权限才可以,否则 程序将会直接崩溃,比如这里查询系统的网络

状态就是需要声明权限的。打开 AndroidManifest.xml文件,在里面加入如下权限就可以查询系统

网络状态了: 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0">

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="19" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
……
</manifest> 

 

然后就可以再android的应用中查看这些已经声明的权限了。

现在再次运行就看里看到来自系统的提示了。

 

 

还有一个就是

 静态注册实现开机启动 这个我还不是太明白所以没打算写  等等明白了就决定写下来。

 

 

 2, 静态注册实现开机启动:(链接)

 

 

 

 

posted @ 2016-05-12 22:22  Jhin  阅读(207)  评论(0编辑  收藏  举报