Android——动态注册广播

BroadcastReceiver

发送一条广播,可以被不同的广播接收者所接收,广播接收者收到广播后再进行逻辑判断。

标准广播

通过 new BroadcastReceiver() 创建广播
通过 registerReceiver() 注册广播
通过 sendBroadcast() 发送广播
通过 unregisterReceiver() 注销广播

    @Override
    protected void onStart() {
        super.onStart();
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent != null && intent.getAction().equals(BroadStandardActivity.BROAD_ACTION_COME)) {
                    btn_send.setText("来了");
                }
            }
        };
        // 创建一个意图过滤器,只处理 BROAD_ACTION_COME 的广播
        IntentFilter filter = new IntentFilter(BroadStandardActivity.BROAD_ACTION_COME);
        //注册接收器
        registerReceiver(receiver, filter);
    }
发送标准广播
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(BroadStandardActivity.BROAD_ACTION_COME);
        sendBroadcast(intent);
    }

案例代码

有序广播

  • 一个广播存在多个接收器,这些接收器需要排队收听广播,这意味着该广播是条有序广播。
  • 先收到广播的接收器A,既可让其他接收器继续收听广播,也可中断广播不让其他接收器收听。

通过 sendOrderedBroadcast() 发送广播
通过 setPriority()设置优先级,数字越大,优先级越高

    @Override
    protected void onStart() {
        super.onStart();
        /*
        * 多个接收器处理有序广播的规则:
        * 1、优先级越大的接收器,越早收到有序广播
        * 2、优先级相同的时候,越早注册的接收器越早收到有序广播
        * */

        /*
        * 创建接收器A
        * */
        receiverA = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent != null && intent.getAction().equals(ORDER_ACTION)) {
                    btn_send_order.setText("来了A");
                }
            }
        };
        IntentFilter filterA = new IntentFilter(ORDER_ACTION);
        filterA.setPriority(8);
        registerReceiver(receiverA, filterA);


        /*
         * 创建接收器B
         * */
        receiverB = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent != null && intent.getAction().equals(ORDER_ACTION)) {
                    btn_send_order.setText("来了");
                    abortBroadcast();// 中断广播,此时后面的接收器无法收到该广播
                }
            }
        };

        IntentFilter filterB = new IntentFilter(ORDER_ACTION);
        filterB.setPriority(10);
        registerReceiver(receiverB, filterB);

    }

abortBroadcast():中断广播,让其它广播接收者无法收到该广播
clearAbortBroadcast():这个方法是针对上面的abortBroadcast()方法的,用于取消截获广播。这样它的下一级广播接收者就能够收到该广播了。
getAbortBroadcast():判断是否调用了 abortBroadcast,如果先调用 abortBroadcast,接着再调用 getAbortBroadcast,将返回 true; 如果在调用 abortBroadcastclearAbortBroadcastgetAbortBroadcast,将返回 false;

发送有序广播
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(ORDER_ACTION);
        /*
         * 发送有序广播
         * 第二个参数:广播接收者所需要的权限(有些广播的是需要权限的)
         * */
        sendOrderedBroadcast(intent, null);
    }

案例代码

系统分钟到达广播

安卓系统每到1分钟就会发送一条广播,此时我们可以接受这个广播。

通过 Intent.ACTION_TIME_TICK 进行Action过滤

	IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);

网络变更广播

    private void netWorkReceiver() {
        receiverNet = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent != null) {
                    NetworkInfo networkInfo = intent.getParcelableExtra("networkInfo");
                    String text = String.format(
                            "网络大类为%s,网络小类为%s,网络状态为%s",
                            networkInfo.getTypeName(),
                            networkInfo.getSubtypeName(),
                            networkInfo.getState().toString());

                    tv_tip.setText(text);
                }
            }
        };
        IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(receiverNet, filter);
    }

定时管理器

Android提供了专门的定时管理器 AlarmManager,它利用系统闹钟定时发送广播,常见方法:

  • set:设置一次性定时器
  • setAndAllowWhileIdle:设置一次性定时器,即使设备处于空闲状态,也会保证执行定时器。
  • setRepeating:设置重复定时器,但系统不保证按时发送广播。
  • cancel:取消指定延迟意图的定时器。

注册接收者 AlarmReceiver

        // 上下文传 getApplicationContext() ,而非 this(当前Activity),为了避免内存泄漏
        alarmReceiver = new AlarmReceiver(getApplicationContext());
        IntentFilter filter = new IntentFilter(AlarmReceiver.ALARM_ACTION);
        registerReceiver(alarmReceiver, filter);
发送闹钟广播

定时管理使用了PendingIntent,它与Intent之间的差异主要有下列三点:

  • PendingIntent 代表延迟意图,它指向的组件不会马上激活;而Intent代表实事的意图,它指向的组件会马上激活
  • PendingIntent 是一类消息的组合,不但包含目标的Intent对象, 还包含请求代码、请求方式等信息。
  • PendingIntent 对象在创建之时便已知晓将要用于活动还是广播。
    public void sendAlarm() {
        Intent intent = new Intent(ALARM_ACTION);
        // 创建一个用于广播的延迟意图
        // 针对 S+ (版本1000及更高版本)要求创建 PendingIntent 时指定 FLAG_IMMUTABLE 或 FLAG_MUTABLE
        // 强烈考虑使用 FLAG_IMMUTABLE,仅当某些功能依赖于 PendingIntent,是可变时才使用 FLAG_MUTABLE
        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE);

        // 从系统服务中获取闹钟管理器
        AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 允许在空闲时发送广播,Android6.0之后新增的方法
            alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 3000, pendingIntent);
        } else {
            // 设置一次性闹钟,延迟若干秒后,携带延迟意图发送闹钟广播(但Android6.0之后,set方法在暗屏时不保证发送广播,必须调用setAndAllowWhileIdle方法)
            alarmManager.set(AlarmManager.RTC_WAKEUP, 3000, pendingIntent);
        }
    }
设置重复闹钟
// 设置重复闹钟,每隔一定间隔就发送闹钟广播(但从Android4.4开始,setRepeating方法不保证按时发送广播)
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, pendingIntent);
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null && intent.getAction().equals(ALARM_ACTION)) {
            Log.d("AAAA", "收到广播了");

            // setRepeating 有问题,在接收到广播后又调用一次
            sendAlarm();
        }
    }

案例代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/906044.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ETLCloud怎么样?深度解析其在数据管理中的表现

在BI或数据大屏等数据分析工具中,经常需要从多个业务系统中提取原始数据,然后对数据进行清洗、处理,以获取高质量、有效且干净的数据以供后续的BI进行数据统计和分析使用,从高质量的实现企业数据的价值变现。 然而,在…

0xGame 2024 [Week 4] Jenkins

1.前言 由于好久没做web题了,所以今天来尝试来做一波web题,仅供刷题记录。 2.题目 这个给的提示对于小白来说实在是友好的过劲。 3.分析 上网搜到一个关于Jenkins的历史漏洞,下面链接可供参考 https://blog.csdn.net/2301_80127209/arti…

国标GB28181公网直播EasyGBS国标GB28181软件的应用场景

随着科技的飞速发展,安防视频监控技术已经成为现代社会不可或缺的一部分,它在保障公共安全、企业运营安全以及个人财产安全方面发挥着举足轻重的作用。国标GB28181网页直播平台EasyGBS安防视频监控平台,作为集高效性、稳定性与智能化于一体的…

【Vue项目1】第一篇

Vue项目1学习第一篇 01. 环境配置介绍和项目搭建02. Router路由配置引入03. ElementPlus引入和按需加载04. layout布局和菜单aside组件创建05. aside样式问题和treeMenu组件拆分06. treeMenu组件递归实现 01. 环境配置介绍和项目搭建 (1)安装node.js …

【从零开始的LeetCode-算法】3127. 构造相同颜色的正方形

给你一个二维 3 x 3 的矩阵 grid ,每个格子都是一个字符,要么是 B ,要么是 W 。字符 W 表示白色,字符 B 表示黑色。 你的任务是改变 至多一个 格子的颜色,使得矩阵中存在一个 2 x 2 颜色完全相同的正方形。 如果可以…

Javaweb梳理8——数据库设计

Javaweb梳理8——数据库设计 8 数据库设计8.1 数据库设计简介8.2 表关系(一对多)8.3 表关系(多对多)8.4 表关系(一对一) 8 数据库设计 8.1 数据库设计简介 软件的研发步骤 数据库设计概念 数据库设计就是根据业务系统的具体需…

Edge 浏览器插件开发:图片切割插件

Edge 浏览器插件开发:图片切割插件 在图片处理领域,按比例切割图片是一个常见需求。本文将带你开发一个 Edge 浏览器插件,用于将用户上传的图片分割成 4 个部分并自动下载到本地。同时,本文介绍如何使用 cursor 辅助工具来更高效…

QT QPainter 绘图

QT QPainter 绘图 一、基本绘图类: Qt 中提供了强大的 2D 绘图系统,可以使用相同的 API 在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类。 QPainter 用于执行绘图操作,其提供的 API 在…

【C++】位图详解(一文彻底搞懂位图的使用方法与底层原理)

目录 1.位图的概念 2.位图的使用方法 定义与创建 设置和清除 位访问和检查 转换为其他格式 3.位图的使用场景 1.快速的查找某个数据是否在一个集合中 2.排序去重 3.求两个集合的交集和并集 4.位图的底层实现 私有成员定义与初始化 set和reset的实现 前面的博客我们…

在线教育系统源码开发详解:网校培训平台搭建的核心技术

本篇文章,笔者将详细介绍在线教育系统源码的开发过程,重点聚焦网校培训平台搭建的核心技术,以期为有意从事在线教育行业的开发者提供实用的参考。 一、在线教育系统的构成 前端负责用户的交互体验,后端处理业务逻辑,…

qt QPalette详解

1、概述 QPalette是Qt框架中用于管理颜色组和角色的一种机制。它允许开发者为应用程序中的不同组件(如窗口、按钮、文本框等)定义一套统一的颜色方案。QPalette通过定义颜色角色(如背景色、前景色、选择色等)和颜色组&#xff08…

Java基本语法和基础数据类型——针对实习面试

目录 Java基本语法和基础数据类型标识符和关键字有什么区别?Java关键字有哪些?Java基本数据类型有哪些?什么是自动装箱和拆箱?自动装箱(Autoboxing)自动拆箱(Unboxing) 自动装箱和拆…

逻辑磁盘管理 附实验:逻辑卷的组成与划分

分区类型: 1、系统引导分区 就是存放系统的引导文件和Linux的内核文件 2、swap分区 交换分区,系统的物理内存不足时,从一些长时间未运行的程序当中释放一部分内存释放出来的保存到swap分区,这些未运行的程序一旦运行还要从swap空…

fetch: 取消请求、读取流、获取下载进度...

引言 Fetch API 提供了一个获取资源的接口(包括跨网络通信)。对于任何使用过 XMLHttpRequest 的开发者来说, 对于 Fetch 应该都能轻松上手, 而且新的 API 提供了更强大和灵活的功能集… 本文主要就是记录下, 在使用 Fetch 期间可能会碰到的几个小案例… 一、取消请求 在前端…

【 纷享销客-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

mobaxterm 中文输入问号解决办法

无论是终端,还是session的name,输入中文都是问号,那么使用以下方法可解决问题 语言设置中找到英文键盘删除即可

Hive的数据存储格式

目录 一、前言 二、存储格式 2.1、文本格式(TextFile) 2.1.1、定义与特点 2.1.2、存储与压缩 2. 1.3、使用场景 2.2、行列式文件(ORCFile) 2.2.1、ORC的结构 2.2.2、ORC的数据类型 2.2.3、ORC的压缩格式 2.2.3、ORC存储…

Spring Boot的核心优势及其应用详解

目录 前言1. Spring Boot的核心优势1.1 启动依赖的集成1.2 自动化配置 2. 内嵌服务器支持2.1 内嵌Tomcat服务器2.2 独立运行与便捷部署 3. 外部配置管理3.1 多环境支持3.2 配置优先级与外部化配置 4. Spring Boot的应用场景4.1 微服务架构4.2 云原生应用 结语 前言 在现代的Ja…

scala---10.30

val、var package com_1030class Person {var name:String"rose"def sum(n1:Int,n2:Int):Int{n1n2} } object Person{def main(args: Array[String]): Unit {//创建person对象var personnew Person()println(person.sum(10,20))//30println(person.name)person.nam…

ubuntu22.04 docker-compose搭建apisix高可用

首先你得先确保每台主机安装了docker和docker-compose 3台主机 没有安装docker和docker-compose的可以看我前两篇博客 可以先克隆仓库 git clone https://github.com/apache/apisix-docker.git 进入example目录 拷贝dashboard配置文件 将all-in-one中apisix-dashboard文件夹拷…