创建广播接收器并注册广播

发送广播:使用Intent
接收广播:广播接收器
创建广播接收器:
方法:新建一个类继承自BroadcastReceiver,并重写父类的onReceive( )方法。当有广播接收到的时候,onReceive( )中的逻辑就会得到执行
注册广播:
  1. 动态注册广播:在代码中注册
  2. 静态注册广播:在AndroidManifest.xml文件中注册
1. 动态注册广播
例子:实现监听网络变化的功能

修改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.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 change" , Toast.LENGTH_SHORT).show() ;
        }
    }
}
效果:当我们开关数据的时候,就会出现提醒 “network change”
解析:
Step 1:首先,我们先创建了一个广播接收器,叫做NetworkChangeReceiver
class NetworkChangeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive (Context context , Intent intent) {
        Toast.makeText (context , "network change" , Toast.LENGTH_SHORT).show() ;
    }
}
可见,NetworkChangeReceiver继承自BroadcastReceiver,并且我们重写了其中的onReceive ( )方法,添加了自己的逻辑—–加了一段Toast提醒
Step 2:创建一个IntentFilter对象
private IntentFilter intentFilter ;
Step 3:为IntenFilter添加action,监听某种广播
(系统网络状态发生变化时候,会发出一条action为”android.net.conn.CONNECTIVITY_CHANGE”)
intentFilter.addAction ("android.net.conn.CONNECTIVITY_CHANGE") ;

Intent和IntentFilter的区别:

初看我也很会混淆Intent和IntentFilter,不知道为什么动态注册广播使用IntentFilter.addAction( )而不使用Intent.addAction( )
Intent
一般用于启动活动,服务,组件,发送广播等等,是一种意图
所以,一个Intent只能有唯一的action,作为它启动的活动,或是组件等的唯一标识符
IntentFilter
顾名思义,是一种过滤器,Intent的过滤器。
它只有被用在动态注册广播中
看着很熟悉吧,在AndroidManifest.xml中,每一个activity中都有一个<intent-filter>的标签,它里面描述了activity的各种属性,action,category,data,可以供Intent来匹配。
发送给应用程序的广播多种多样,十分多,怎么样才可以过滤掉我们不想要的广播呢?靠的就是IntentFilter。使用它的addAction( )方法,可以为它添加过滤的字符(有点类似Logcat中的filter),从而在许多广播中找到我们需要的广播
所以,一个IntentFilter可以有多个action作为过滤标识符
Step 4:创建一个广播接收器的实例(我们Step 1创建好的广播接收器NetworkChangeReceiver)
networkChangeReceiver = new NetworkChangeReceiver () ;
Step 5:注册广播
调用registerReceiver( )方法来注册
registerReceiver (networkChangeReceiver , intentFilter) ;
该方法带有两个参数:
  1. 第一个参数是广播接收器,描述是广播是谁收到的
  2. 第二个参数是IntentFilter,描述收到哪些广播
Step 6:在活动销毁时注销广播
我们重写onDestroy( )方法,添加注销广播的代码
调用unregisterReceiver( )方法
@Override
protected void onDestroy () {
    super.onDestroy () ;
    unregisterReceiver (networkChangeReceiver) ;
}
该方法带有一个参数
  1. 参数是广播接收器,描述销毁的是哪个广播接收器

优化广播接收器:

显然,只有提醒网络变化很不人性化,应该还要提醒网络是否可用
我们这样修改NetworkChangeReceiver中的onReceive( )方法
@Override
public void onReceive (Context context , Intent intent) {
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE) ;
    NetworkInfo networkInfo = connectivityManager.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 () ;
    }
}
首先,ConnectivityManager是一个系统服务类,专门管理网络连接。调用getSystemService ( )方法,得到它的实例
通过值为Context.CONNECTIVITY_SERVICE来找到它的实例
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE) ;
然后,NetworkInfo,从名字上看就知道,这是一个带有网络连接方面信息的对象。我们通过getActiveNetworkInfo( )方法来得到当前的NetworkInfo实例
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo () ;
最后可以通过isAvailable( )方法来得知网络是否可用
networkInfo.isAvailable()
然后,一切看起来万事大吉,今晚吃鸡了,我们开开心心run代码。会很难过地发现,程序崩溃了。这是为什么?
原来是因为Android系统为了保证应用程序的安全性做了规定:如果程序需要访问一些系统的关键信息,必须在配置文件中声明权限才可以,否则程序会直接崩溃。
那么,我们便需要在配置文件,也就是AndroidManifest.xml中作出加入查询网络状态的权限
<manifest
    ……
    >
    ……
    <uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE">
    ……
</manifest>
优点:灵活,可以自由地控制注册和注销
缺点:必须要在程序启动之后才能接收广播
2. 静态注册广播
例子:我们让程序接收一条开机广播,然后出现提醒
Step 1:创建一个广播接收器
这里创建广播接收器和动态注册的时候有什么不同呢?动态注册广播,我们采用的是在MainActivity.java中定义了内部类的方式,然后在onCreate( )中使用registerReceiver( )方法来动态注册,随时随地注册。而我们这次是要接收开机广播,程序都还没启动,onCreate( )方法都还没有被调用,显然,内部类已经无法满足我们这次的需求
所以,这次我们新建了一个文件叫BootCompleteReceiver.java,里面是一个新建类继承自Broadcast,然后可以在配置文件中进行注册,从而实现开机启动,接收开机广播的功能

BootCompleteReceiver.java

public BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive (Context context , Intent intent) {
        Toast.makeText (context , "Boot Complete" , Toast.LENGTH_SHORT).show();
    }
}
Step 2:在配置文件中将广播接收器的类名注册进去

AndroidManifest.xml

<manifest
    ……
    >
    ……
    <uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED">
    ……
    <application
        ……
        >
        ……
        <receiver android:name = ".BootCompleteReceiver">
            <intent-filter>
                <action android:name = "android.intent.action.RECEIVE_BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>
开机信息自然也是系统关键信息,所以也需要和网络连接那样声明权限
<uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED">
然后是注册广播接收器的代码,使用了<receiver>的标签;这个标签里面的android:name属性,指明了类名,说明了是哪个广播接收器;然后是这个标签之间的<intent-filter>标签(动态注册用IntentFilter对象,静态注册用<intent-filter>标签),里面的<action/>标签里的android:name属性指明了可以接收的广播的action属性,开机时系统发出的广播的值是”android.intent.action.BOOT_COMPLETED”,所以这里可以接受的广播的action就是上面这个值
<receiver android:name = ".BootCompleteReceiver">
    <intent-filter>
        <action android:name = "android.intent.action.RECEIVE_BOOT_COMPLETED"/>
    </intent-filter>
</receiver>
然后我们开开心心run代码,关机然后开机,就可以发现一开机这个程序就会自启动然后出现”Boot Complete”的提醒
优点:可以让程序在未启动的情况下接收广播
(动态注册应该和静态注册结合使用,来接收不同的广播)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值