美文网首页
第一行代码-广播(2)

第一行代码-广播(2)

作者: bluewind1230 | 来源:发表于2018-01-19 22:17 被阅读0次

    1.接收系统广播

    1.1动态注册监听网络变化

    注册的目的与意义

    广播接收器可以自由地对自己感兴趣的广播进行注册,这样有相应的广播发出的时候,广播接收器就能够接受到该广播(注册的目的与意义)

    谁来注册:广播接收器

    注册的方式

    动态注册:在代码中注册;
    静态注册:在清理文件(AndroidManifest.xml)中注册;

    注意点:动态注册的广播接收器一定都要取消注册才可,这里是在onDestroy()方法里面

    调用unregisterReceiver()实现

    如何创建一个广播接收器

    新建一个类,让它继承自BroadcastReceiver,同时重写父类的OnReceiver()方法即可
    这样当有广播到来的时候,OnReceiver()方法就会得到执行,下面通过动态注册的方式编写一个能够监听网络变化的程序,源代码如下:

    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) {
                    Toast.makeText(context, "network is unavailable",
                           Toast.LENGTH_SHORT).show();
          }
       }
    }
    

    内部类NetworkChangeReceiver 继承自BroadcastReceiver,并重写了onReceive方法,网络一旦发生变化,onReceive方法就会得到执行;
    onCreate方法中:
    1)先创建了一个IntentFilter实例,并给其添加一个
    android.net.conn.CONNECTIVITY_CHANGEaction,网络状态发生变化,系统发出的正是一条值为android.net.conn.CONNECTIVITY_CHANGE的广播,也就是说广播接收器想要监听什么广播,就在这里添加相应的action(利用addAction);
    2)接下来创建一个NetworkChangeReceiver的实例,然后调用registerReceiver()方法进行注册,将networkChangeReceiverintentFilter两个实例都传进去了,这样NetworkChangeReceiver就会收到所有值为android.net.conn.CONNECTIVITY_CHANGE的广播(联系上文),进而实现监听网络变化的功能;

    注意点:动态注册的广播接收器一定都要取消注册才可,这里是在onDestroy()方法里面

    调用unregisterReceiver()实现

     class NetworkChangeReceiver extends BroadcastReceiver {
    
            @Override
            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();
               }
          }
        }
    
    

    OnReceive()方法中:
    1.首先通过getSystemService得到connectionManager的实例,这是一个系统服务类,专门用于管理网络连接的;
    2.然后调用它的getActiveNetworkInfo()方法得到NetworkInfo的实例;
    3.接着调用NetworkInfo的isAvailable()方法,就可以判断出是否有网络连接

    注意:

    如果程序需要进行一些对用户来说比较敏感的操作,就必须在配置文件中声明权限才可以,否则程序将直接崩溃;比如这里访问系统的网络状态就需要声明权限,打开AndroidManifest.xml文件:

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

    1.2静态注册实现开机启动

    动态注册有一个缺点:必须要在开机之后才能接收广播,因为注册的逻辑是写在onCreate()方法中的;

    静态注册的目的

    为了让程序在为启动的情况下接收到广播,需要使用静态注册的方法

    image.png

    我们准备让程序收到一条开机广播,当收到这条广播的时候可以在OnReceive()方法里面执行相应的逻辑,从而实现开机的功能;(过程见上面和下面的图)


    image.png
    image.png

    广播接收器名默认为:MyReceiver,改为:BootCompleteReceiver (这里没有改)
    Exported表示是否允许这个广播接收器接受本程序以外的广播;
    Enabled属性表示是否启用这个广播接收器

    package com.example.broadcasttest;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.widget.Toast;
    
    public class BootCompleteReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
        }
    
    }
    

    静态的广播接收器一定要在清单文件中注册才可以使用,不过由于我们是使用安卓的快捷方式创建的广播接收器,注册这一步被自动完成了,

    image.png

    <application>标签内出现了一个新的标签<receiver>,其用法和<activity>类似,通过android:name来指定具体注册哪一个广播接收器,Exported和Enabled属性根据我们刚才勾选的自动生成,不过目前此接收器还是不能接收到开机广播,需要对清单文件(AndroidManifest.xml)进行修改,

    image.png
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.broadcasttest">
    
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <receiver
                android:name=".BootCompleteReceiver"
                android:enabled="true"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                </intent-filter>
            </receiver>
            <receiver
                android:name=".MyBroadcastReceiver"
                android:enabled="true"
                android:exported="true">
                <intent-filter android:priority="100">
                    <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
                </intent-filter>
            </receiver>
        </application>
    
    </manifest>
    

    1.安卓系统启动完成之后会发出一条值为android.intent.action.BOOT_COMPLETED的广播,因此在</intent-filter>标签里面添加了相应的action(靠近最后的地方);
    2.除此之外,监听系统开机广播也是需要声明权限的,故<uses-permission >标签加了
    android:name="android.permission.RECEIVE_BOOT_COMPLETED权限
    将模拟器关闭重新启动即可.

    静态注册小结:

    1.右击创建接收器,(清单文件中自动完成注册)
    2.在</intent-filter>标签(清单文件中)里面添加相应的action
    3.监听系统开机广播需要声明权限

    注意点:

    接收器的OnReceive()方法中不要添加过多的逻辑,广播接收器是不允许开启线程,当此方法运行了较长时间而没有结束的时候,程序会报错!

    相关文章

      网友评论

          本文标题:第一行代码-广播(2)

          本文链接:https://www.haomeiwen.com/subject/dbiaoxtx.html