目录

一、广播机制简介

二、接收系统广播

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

2.静态注册实现开机启动

三、发送自定义广播

1.发送标准广播

2.发送有序广播

五、广播的最佳实践---实现强制下线功能


一、广播机制简介

发送广播:Intent

接收广播:广播接收器(Broadcast Receiver)

Android广播分为两种类型:标准广播和有序广播

标准广播:异步执行的广播,所有的广播接收器会在同一时刻接收到的广播

有序广播:同步执行的广播,优先级高的广播接收器先收到广播,并且可以截断广播

二、接收系统广播

注册广播的方式有两种:在代码中注册(动态注册)和在AndroidManifest.xml中注册(静态注册)

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

缺点:必须要在程序启动之后才能接收到广播

  1. 创建IntentFilter实例,并且使用addAction()方法添加想要监听的广播
  2. 创建一个xx类继承BroadcastReceiver,重写onReceiver()方法,然后在MainActivity创建该类的实例
  3. 调用registerReceiver(),传入这两个实例
  4. 取消注册是在onDestroy()方法中通过调用unregisterReceiver()方法来实现
public class MainActivity extends AppCompatActivity {private IntentFilter intentFilter;private NetworkChangeReceiver networkChangeReceiver;@Overrideprotected 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是注册广播接收器,是ContextWrapper类的方法registerReceiver(networkChangeReceiver,intentFilter);}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(networkChangeReceiver);}class NetworkChangeReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "网络发生变化", Toast.LENGTH_SHORT).show();}}
}

2.静态注册实现开机启动

  1. 创建一个xx类继承BroadCastReceiver

  2. 在AndroidManifest.xml注册静态的广播接收器

  3. 在AndroidManifest.xml添加响应广播的action,并且声明该广播的权限

三、发送自定义广播

1.发送标准广播

  1. 通过静态注册定义一个广播接收器用于接收自定义的广播

  2. 首先构建一个Intent对象,并把要发送的广播的值传入。再调用ContextWrapper的sendBroadcast()方法将广播发送出去

  3. 在 Android 8.0 之后,对于广播的发送与接收变严格了,需要加入Component参数

  4. 或者按照《第一行代码-第三版》的方法解决:在Android 8.0系统之后,静态注册的BroadcastReceiver是无法接收隐式广播的,而默认情况下我们发出 的自定义广播恰恰都是隐式广播。因此这里一定要调用setPackage()方法,指定这条广播是 发送给哪个应用程序的,从而让它变成一条显式广播,否则静态注册的BroadcastReceiver将 无法接收到这条广播。 注意只有静态注册才写,动态注册不需要写

Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent("com.jack.broadcasttest.MY_BROADCAST");intent.setPackage(getPackageName());//intent.setComponent(new ComponentName("com.jack.broadcasttest","com.jack.broadcasttest.MyBroadcastReceiver"));sendBroadcast(intent);}
});

2.发送有序广播

        <receiverandroid:name=".AnotherBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.jack.broadcasttest.MY_BROADCAST" /></intent-filter></receiver><receiverandroid:name=".MyBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.jack.broadcasttest.MY_BROADCAST" /></intent-filter></receiver>

再注册一个静态接收广播,发现两个receiver都接收到自定义广播,并且和静态注册的顺序相关


        Button button = findViewById(R.id.send_broadcast);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent("com.jack.broadcasttest.MY_BROADCAST");intent.setPackage(getPackageName());//sendOrderedBroadcast()方法接收两个参数:第一个 参数仍然是Intent;第二个参数是一个与权限相关的字符串,这里传入null就行了。 sendOrderedBroadcast(intent,null);}});
        <receiverandroid:name=".AnotherBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.jack.broadcasttest.MY_BROADCAST" /></intent-filter></receiver><receiverandroid:name=".MyBroadcastReceiver"android:enabled="true"android:exported="true">//通过android:priority属性设置优先级<intent-filter android:priority="100"><action android:name="com.jack.broadcasttest.MY_BROADCAST" /></intent-filter></receiver>
public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();//abortBroadcast()方法表示将广播截断abortBroadcast();}
}

实测 MyBroadcastReceiver可以把广播截断


五、广播的最佳实践---实现强制下线功能

发送自定义广播:

public class MainActivity extends BaseAcitvity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button send = findViewById(R.id.send_forceOffline);send.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent("com.jack.broadcastreceiverbest.FORCE_OFFLINE");sendBroadcast(intent);}});}
}

注册一个动态广播接收器:

public class BaseAcitvity extends AppCompatActivity {private ForceOfflineReceiver forceOfflineReceiver;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityCollector.addActivity(this);}@Overrideprotected void onResume() {super.onResume();IntentFilter filter = new IntentFilter();filter.addAction("com.jack.broadcastreceiverbest.FORCE_OFFLINE");forceOfflineReceiver = new ForceOfflineReceiver();registerReceiver(forceOfflineReceiver,filter);}@Overrideprotected void onPause() {super.onPause();unregisterReceiver(forceOfflineReceiver);}@Overrideprotected void onDestroy() {super.onDestroy();ActivityCollector.removeActivity(this);}class ForceOfflineReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {AlertDialog.Builder builder = new AlertDialog.Builder(BaseAcitvity.this);builder.setTitle("Warning");builder.setMessage("You are forced to be offline.Please try to login again");builder.setCancelable(false);builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {ActivityCollector.finishAll();Intent intent = new Intent(context, LoginActivity.class);//注意这里的写法,context去掉也行,或者改成BaseActivity.super也行//为什么context也行呢,查看源码startActivity()是一个抽象方法呀?因为Context类也是一个抽象类,既然有实例context,必然是通过多态间接实现父类的实例化,那么调用的方法肯定是子类已经实现的方法context.startActivity(intent);}});builder.show();}}
}

完!

第一行代码-第二版(郭霖著)笔记五(Broadcast Receiver)相关推荐

  1. 图灵直播|《第一行代码》作者郭霖在线Coding,今晚八点,给你留位!

    图源来自Pexels "我们为什么需要 Kotlin?答:消失的 Getter 和 Setter.又见空指针.Smart Cast.打日志.再见Utils.晚安ButterKnife--&q ...

  2. Android第一行代码第二版简要总结

    进入安卓的第一本书(简要概括) 第一章 了解大体Android 1.Android系统架构 Linux内核层:为Android设备的各种硬件提供了底层的驱动. 系统运行库层:通过c/c++库来提供主要 ...

  3. 第一行代码-第二版(郭霖著)笔记六(持久化技术)

    目录 一.持久化技术简介 二.文件存储 1.将数据存储到文件中 2.从文件中读取数据 三.SharedPreference存储 1.将数据存储到SharedPreferences中 2.从Shared ...

  4. 第一行代码-第二版(郭霖著)笔记十一(高级技巧)

    目录 一.全局获取Context的技巧 二.使用Intent传递对象 1.Serializable方式 2.Parcelable方式 三.定制自己的日志工具 四.调试Android程序 五.深色主题 ...

  5. 第一行代码-第二版(郭霖著)笔记四(Fragment)

    目录 一.碎片是什么 二.碎片的使用方式 1.碎片的简单用法 2.动态添加碎片 3.在碎片中模拟返回栈 4.碎片和活动之间的通信 三.碎片的生命周期 1.碎片的状态和回调方法 四.动态加载布局的技巧 ...

  6. 《第一行代码》作者郭霖大神安卓问题解答

    列举了几个郭大神解答的有关Android的问题,虽然只有几个问题,但是基本涵盖了各个安卓开发阶段的困惑,郭大神的回答简洁深刻,收获颇丰. 1.工作有点吃力怎么办? 首先你要自信,公司都信任你了,你又何 ...

  7. 第一行代码第二版6.4.1小节创建数据库中遇到adb shell出错的问题

    该小节中我们照着作者说的一步步写完相应的代码,并运行程序,最后需要使用adb shell来对数据库和表的创建情况进行检查. 可是当配置好环境变量之后,在命令行终端输入adb shell结果如下所示: ...

  8. 第一行代码(第二版)全书代码下载

    Github地址: https://github.com/newcaoguo/booksource

  9. 第一行代码-ListViewDemo(2)-读书笔记

    对应第一行代码的114页 activity_main.xml <?xml version="1.0" encoding="utf-8"?> < ...

最新文章

  1. PHP 获取数组最后一个值
  2. Do a test write by windows live writer
  3. netbeans连接数据库_NetBeans Java EE技巧#1 –数据库中的实体类
  4. leetcode176. 第二高的薪水(SQL)
  5. JAVA面试——计算机网络
  6. 前端实现图片悬浮_悬浮图片之上效果实现
  7. 数据结构排序3-堆排序
  8. Android应用程序管理系列(一)——管理对象封装概述
  9. 求助下 Ubuntu 15.10(64 位)下安装 pyspider 下的问题 - V2EX
  10. ubuntu-键盘映射
  11. graphpad做折线图_Graphpad Prism搞定折线和曲线图,so easy!
  12. 人事管理系统 C语言,人事管理系统----C语言设计
  13. QQ勋章墙工具-支持所有版本完成QQ等级加速
  14. 移动通信核心网技术总结(一)语音与上网业务的实现
  15. 嵌入式技术栈之spi协议的时序
  16. Avoid mutating a prop directly since the value will be overwritten whenever
  17. Github十大深度学习项目
  18. extern 用法小结
  19. 植物大战僵尸2android最新版,植物大战僵尸2
  20. Github API:爬取Github用户数据

热门文章

  1. H264、H265 Nalu头部解析
  2. Zookeeper VS Chubby
  3. PMO如何建立项目管理文化?
  4. Hotspot垃圾收集器一览
  5. mysql hzpy_在线浏览美图源码+py源码附带爬虫功能
  6. 物联网通信技术|课堂笔记week2-1|Linux网络管理基本命令
  7. ESP32S用Micropython编程开发,TCP连接Tlink控制开关灯,可微信控制开关
  8. 一步步教你实现微信小程序自定义组件
  9. 微信小程序 自定义组件生命周期
  10. docker安装nginx1.20.2并配置nginx.conf