无所不知的BroadcastReceiver

/**

广播接收器 是一种用于响应系统范围广播通知的组件。 许多广播都是由系统发起的—例如,通知屏幕已关闭、电池电量不足或已拍摄照片的广播应用也可以发起广播—例如,通知其他应用某些数据已下载至设备,并且可供其使用。 尽管广播接收器不会显示用户界面,但它们可以创建状态栏通知,在发生广播事件时提醒用户。 但广播接收器更常见的用途只是作为通向其他组件的“通道”,设计用于执行极少量的工作。 例如,它可能会基于事件发起一项服务来执行某项工作。
 */

基础识记

        /**
         * 广播
         * 1、如果你不需要在应用之间进行发送的话则可以使用LocalBroadcastManager,这个类只是在本进程内进行是安全的
         * 2、如果你使用Manifest里面注册的广播接受者,不希望其它的应用程序去发送到你这个接受者里面你需要加入android:exported="false"
         * 广播分为有序广播和无序广播
         * 有序广播:广播按照一定的顺序去执行,执行规则:
         *          1、如果在Manifest里面设置了优先级从高到低的顺序执行
         *          2、如果优先级相同或者没有设置优先级则按程序执行顺序从上到下开始接受广播
         *          3、如果是不同的应用则按应用的安装顺序进行执行
         * 无序广播:具有相同行为的广播都能接受到
         *          1、当多个应用程序都有你的广播接受者,而你想让其中的一个应用去接受你需要为Intent设置setPackage()
         */

发送顺序广播

        Intent intent = new Intent();
        intent.setAction("com.andly.basic");
        //intent  意图
        //receiverPermission  接受需要的权限
        //resultReceiver  指定最后执行的Receiver(此receiver一定会执行)
        //initialCode  结果码通常是RESULT_OK
        //initialData  初始化的字符串
        //initialExtras 初始化的数据 类型为Bundle
        sendOrderedBroadcast(intent, null, null, null, 0, "A", null);

在Android官方文档里面解释说不许在BroadcastReceiver里面直接开启Activity和绑定服务,可以startService,原因是因为BroadcastReceiver和Activity操作是不同的,一个运行在后台一个运行在前台。但是查看源码可以看到BroadcastReceiver里面的Context实际是ReceiverRestrictedContext类,当你需要从BroadcastReceiver里面跳转到Activity加上NEW_TASK

Intent intent1 = new Intent(context, MainActivity.class);
        intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent1);

从代码角度来解释一下原因:1、在BroadcastReceiver里面不能绑定服务和注册广播  2、在BroadcastReceiver里面不能直接开启Activity

1、在BroadcastReceiver里面不能绑定服务和注册广播

先了解一下这个类的继承关系:

《无所不知的BroadcastReceiver》

查看ReceiverRestrictedContext类:

《无所不知的BroadcastReceiver》

可以看到它的registerReceiver和BindService实现都抛出了一个不被允许的异常。

2、在BroadcastReceiver里面不能直接开启Activity

查看ContextImpl的源码startActivity方法

《无所不知的BroadcastReceiver》

这样看到这条件便知道为啥不能在BroadcastReceiver里面直接startActivity了,然后查看Android7.0的源码

《无所不知的BroadcastReceiver》

可以惊奇的发现这方法做了优化经过测试在Android7.0可以不用加NEW_TASK就能进行跳转.估计是做了优化。

接下来介绍一下接受系统广播的例子。

1、接收开机启动的广播

permission:

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

receiver:

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

                <category android:name="android.intent.category.HOME" />
            </intent-filter>
        </receiver>

2、接受拨打电话的广播

permission:

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

receiver:

        <receiver android:name=".phone_listener.PhoneBroadcastReceiver">
            <intent-filter>
                <!--接受拨打电话的广播接受者-->
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
        </receiver>

3、接受接收短信的广播

permission:

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

receiver:

        <receiver android:name=".sms_listener.SmsBroadcastReceiver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

4、接受SD卡是否挂载广播

receiver:

        <receiver android:name=".sdcard_state.ScardStateReceiver">
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_MOUNTED" />
                <action android:name="android.intent.action.MEDIA_UNMOUNTED" />
                <action android:name="android.intent.action.MEDIA_REMOVED" />
                <data android:scheme="file" />
            </intent-filter>
        </receiver>

5、接受应用程序是否卸载广播

receiver:

        <receiver android:name=".package_listener.PackageBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>

    原文作者:coding渣渣
    原文地址: https://blog.csdn.net/weiwozhiyi/article/details/50650732
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞