四大组件:BroadCastReceiver广播

2024-01-28 21:38

本文主要是介绍四大组件:BroadCastReceiver广播,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

BroadCastReceiver:广播接收者,可以接受手机电量变化、短信、电话、app的安装与卸载等都可以接受到这些广播(这些事系统发出的广播),当然我们还可以自定义广播,这就我们自己写发送广播的代码。

分类:

有序广播和无序广播
有序广播:是可以拦截的,可以设置优先级(数值越大,越先接收广播)
无序广播:不可以被拦截,没有优先级。

有关方法:

sendBroadcast(intent);发送广播
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)发送有序广播
abortBroadcast();取消广播,只有有序广播才可以调用该方法,无序广播调用会报错BroadcastReceiver trying to return result during a non-ordered broadcast

这里写图片描述

如果是静态广播,那么不需要在onReceive(...)中判断action,如果是动态注册,需要判断action

静态广播接收者BroadCastReceiver

注册广播接收者有2种方法,代码中注册(动态注册)和AndroidManifest.xml中注册(静态注册),下面的案例没说明动态注册的都是静态注册。

系统发出的广播,我们只做接收。常见的如下:
- 打电话 Receiver
- SD卡状态 Receiver
- 来短信 Receiver
- app的安装与卸载 Receiver
- 开机启动 Receiver

打电话 Receiver

打电话,若是长途,则广播中给手机号添加ip:123456

这里写图片描述

    @Overridepublic void onReceive(Context context, Intent intent) {//获取保存的ipSharedPreferences sp = context.getSharedPreferences("config", context.MODE_PRIVATE);String ip = sp.getString("ip", "17951");//获取拨进来的号码String number = getResultData();//以0开头,则是长途,则在号码前加ipif (number.startsWith("0")) {setResultData(ip + number);}}
<!--在androidManifest中注册的广播是持久广播,app退出仍然有效。  -->
<!-- 声明receiver 添加action -->
<receiver android:name="com.cqc.ipnumber.OutGoingCallBroadCastReceiver" ><intent-filter><action android:name="android.intent.action.NEW_OUTGOING_CALL" /></intent-filter>
</receiver>
<!-- 添加外拨电话权限 -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

SD卡状态 Receiver

 根据action判断sd卡是挂载还是卸载。注意卸载sd卡的action是UNMOUNTED,不是REMOVE
@Override
public void onReceive(Context context, Intent intent) {String action = intent.getAction();if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {// 挂载Log.d(TAG, "sd卡挂载");} else if (Intent.ACTION_MEDIA_UNMOUNTED.equals(action)) {Log.d(TAG, "sd卡卸载");}
}
<!-- 声明receiver --><receiver android:name="com.cqc.sdstatelistener.SdStateReceiver" ><intent-filter><action android:name="android.intent.action.MEDIA_MOUNTED" /><action android:name="android.intent.action.MEDIA_UNMOUNTED" /><!-- sd卡状态比较特殊,除了设置action,还需要data --><data android:scheme="file" /></intent-filter></receiver>

来短信 Receiver

广播接收者:

    @Overridepublic void onReceive(Context context, Intent intent) {//转换成数组Object[] objects = (Object[]) intent.getExtras().get("pdus");//遍历数组,湖区sms对象for (Object object : objects) {SmsMessage sms = SmsMessage.createFromPdu((byte[]) object);//获取短信内容和发布者手机号String content = sms.getMessageBody();String originNumber= sms.getOriginatingAddress();Log.d(TAG, "content="+content+"____originNumber"+originNumber);}}
<receiver android:name="com.cac.smsreceiver.SmsReceiver" ><intent-filter><!-- 处于安全性考虑,android没有提示短信监听的action,但仍然可以使用 --><action android:name="android.provider.Telephony.SMS_RECEIVED" /></intent-filter></receiver>
 <!-- 短信监听的权限 --><uses-permission android:name="android.permission.RECEIVE_SMS" />

把androidManifest.xml的启动的actiivty的intent_filter注释掉,就没有界面了,但是海驿拿到短信, api4.0后,注释掉intent_filter,就拿不到短信了。

app的安装与卸载 Receiver

这里写图片描述

@Override
public void onReceive(Context context, Intent intent) {String action = intent.getAction();if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {// 挂载Log.d(TAG, "安装");} else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {Log.d(TAG, "卸载");}
}
<receiver android:name="com.cqc.installreceiver.InstallReceiver"><intent-filter ><action android:name="android.intent.action.PACKAGE_ADDED"/><action android:name="android.intent.action.PACKAGE_REMOVED"/><!-- 安装卸载还需要添加data --><data android:scheme="package"/></intent-filter>
</receiver>

开机启动 Receiver

    @Overridepublic void onReceive(Context context, Intent intent) {Log.d(TAG, "intent2");Intent intent2 = new Intent(context, MainActivity.class);intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent2);String action = intent.getAction();if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {Log.d(TAG, "Intent.ACTION_BOOT_COMPLETED");}}
 <receiver android:name="com.cqc.bootreceiver.BootReceiver" ><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"/></intent-filter></receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

自定义广播接收者

自定义广播需要设置action,可以获取intent中的数据。

基本使用

自定义广播,在Button的点击监听中发送广播,在receiver中根据action,从intent中取值。

这里写图片描述

发送广播:

Intent intent = new  Intent();
intent.setAction("MyReceiver");
intent.putExtra("name", "奥巴马");
sendBroadcast(intent);

MyReceiver :

public class MyReceiver extends BroadcastReceiver {private static final String TAG = "MyReceiver";@Overridepublic void onReceive(Context context, Intent intent) {Log.d(TAG, "MyReceiver--name="+intent.getStringExtra("name"));//取消广播abortBroadcast();}
}

在AndroidManifest.xml中配置receiver:

<receiver android:name="com.cqc.custombroadcast.MyReceiver"><intent-filter ><action android:name="MyReceiver"/></intent-filter>
</receiver>

自定义有序广播

demo:国家发布政令后,先到省政府,再到市政府,再到县政府…,这里只设置这3级,有先后顺序。点击Button发送广播,一次向下传递。

点击Button发送广播:

 btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//发送自定义广播Intent intent = new Intent();intent.setAction("customOrderReceiver");intent.putExtra("commond", "全国各级部门应该加强安全防范措施");
//              sendBroadcast(intent);//这是无序广播/*** 这是有序广播,参数分别是:* Intent intent:intent对象* String receiverPermission: 接收者权限* BroadcastReceiver resultReceiver:最后一个接收者,不为null,则最后的receiver会接收2次。* Handler scheduler, null* int initialCode  状态码* String initialData,  传递的数据,intent.putExtra(...)* Bundle initialExtras:null*/sendOrderedBroadcast(intent, null, new CountyReceiver(), null, 1, null, null);}});

省级先接到通知

public class ProviceReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Log.d("tag", "省级部门接到中央命令+content="+intent.getStringExtra("commond"));}
}

然后是市级接到通知

public class CityReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Log.d("tag", "市级部门接到中央命令+content="+intent.getStringExtra("commond"));}
}

最后是县级接到通知

public class CountyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Log.d("tag", "县级部门接到中央命令+content="+intent.getStringExtra("commond"));}
}

注意:

1 上面的先后级别是根据广播接收者的priority(优先级)决定的。是在配置receiver时设置的。

 <receiver android:name="com.cqc.customorderreceiver.ProviceReceiver" ><intent-filter android:priority="3" ><action android:name="customOrderReceiver" /></intent-filter></receiver><receiver android:name="com.cqc.customorderreceiver.CityReceiver" ><intent-filter android:priority="2" ><action android:name="customOrderReceiver" /></intent-filter></receiver><receiver android:name="com.cqc.customorderreceiver.CountyReceiver" ><intent-filter android:priority="1" ><action android:name="customOrderReceiver" /></intent-filter></receiver>

2 调用方法sendOrderedBroadcast(…)发送有序广播的时候若指定了最后接收者( resultReceiver),那么 resultReceiver会收到2次广播。
这里写图片描述

动态注册广播接收者

与静态相比区别是:

代码上:

1 不需要再AndroidManifest.xml中注册
2 调用registerReceiver(receiver, filter)注册接收者

理解上:

静态注册的广播接收者:当app关闭的时候也是有效的,也可以接受到服务器发出的广播。
动态注册的广播接收者:当app关闭的时候,不会接受到广播。因为我们是在onCreate()中注册的,而不是在AndroidManifest.xml中注册。

下面的是锁屏和开锁的的广播接收者,当我们打开这个app的时候,按住手机电源键锁屏和接收会打印出log,但是当我们关闭app的时候,再按住手机电源键锁屏和接收则不会打印出log

这里写图片描述

Demo1:

public class MainActivity extends Activity {private MyBroadcastReceiver receiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);receiver = new MyBroadcastReceiver();IntentFilter filter = new IntentFilter();filter.addAction("android.intent.action.SCREEN_ON");//添加actionfilter.addAction("android.intent.action.SCREEN_OFF");registerReceiver(receiver, filter);//注册广播接收者}@Overrideprotected void onDestroy() {unregisterReceiver(receiver);//取消广播接收者super.onDestroy();}//创建广播接收者类public class MyBroadcastReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if ("android.intent.action.SCREEN_OFF".equals(action)) {System.out.println("锁屏");} else if("android.intent.action.SCREEN_ON".equals(action)){System.out.println("解锁");}           }}    
}

代码:https://git.oschina.net/beifang2008/DongTaiBroadCastReceiver

Demo2:

public class MainActivity extends Activity {private MyBroadcastReceiver receiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button btn = (Button) findViewById(R.id.btn);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent("auto_finish");sendBroadcast(intent);              }});receiver = new MyBroadcastReceiver();IntentFilter filter = new IntentFilter();filter.addAction("finish");// 添加actionregisterReceiver(receiver, filter);// 注册广播接收者   }@Overrideprotected void onDestroy() {unregisterReceiver(receiver);// 取消广播接收者super.onDestroy();}// 创建广播接收者类public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if ("finish".equals(action)) {finish();}}}
}

sendBroadcast(intent)与sendStickyBroadcast(intent)的区别?

区别主要是在动态注册广播中才有,在静态注册中是一样的。
sendBroadcast(intent):当发送广播在注册广播前时,接收者是接收不到广播的。
sendStickyBroadcast(intent):当发送广播在注册广播前时,接收者是可以接收到广播的。sendStickyBroadcast发出的最后一个Intent会被保留,下次当Recevier处于活跃的 时候,又会接受到它。

Demo:https://git.oschina.net/beifang2008/DongTaiBroadCastReceiver2

LocalBroadcastManager

Android高效安全的本地广播LocalBroadcast完全解析
LocalBroadcastManager只可以动态注册广播。

获取LocalBroadcastManager对象,单利模式

LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);

设置InentFilter,intentFilter和intent都必须设置action

IntentFilter filter = new IntentFilter();
filter.addAction(localAction);

注册

broadcastManager.registerReceiver(receiver, filter);

发送Broadcast

Intent intent = new Intent(localAction);
broadcastManager.sendBroadcast(intent);

取消注册

broadcastManager.unregisterReceiver(receiver);

android.support.v4.content.LocalBroadcastManager工具类,可以实现在自己的进程内进行局部广播发送与注册,使用它比直接通过sendBroadcast(Intent)发送系统全局广播有以下几个好处

  • 因广播数据在本应用范围内传播,你不用担心隐私数据泄露的问题。
  • 不用担心别的应用伪造广播,造成安全隐患。
  • 相比在系统内发送全局广播,它更高效。

这篇关于四大组件:BroadCastReceiver广播的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/654842

相关文章

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

火语言RPA流程组件介绍--浏览网页

🚩【组件功能】:浏览器打开指定网址或本地html文件 配置预览 配置说明 网址URL 支持T或# 默认FLOW输入项 输入需要打开的网址URL 超时时间 支持T或# 打开网页超时时间 执行后后等待时间(ms) 支持T或# 当前组件执行完成后继续等待的时间 UserAgent 支持T或# User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器

如何掌握面向对象编程的四大特性、Lambda 表达式及 I/O 流:全面指南

这里写目录标题 OOP语言的四大特性lambda输入/输出流(I/O流) OOP语言的四大特性 面向对象编程(OOP)是一种编程范式,它通过使用“对象”来组织代码。OOP 的四大特性是封装、继承、多态和抽象。这些特性帮助程序员更好地管理复杂的代码,使程序更易于理解和维护。 类-》实体的抽象类型 实体(属性,行为) -》 ADT(abstract data type) 属性-》成

vue 父组件调用子组件的方法报错,“TypeError: Cannot read property ‘subDialogRef‘ of undefined“

vue 父组件调用子组件的方法报错,“TypeError: Cannot read property ‘subDialogRef’ of undefined” 最近用vue做的一个界面,引入了一个子组件,在父组件中调用子组件的方法时,报错提示: [Vue warn]: Error in v-on handler: “TypeError: Cannot read property ‘methods

JavaEE应用的组件

1、表现层组件:主要负责收集用户输入数据,或者向客户显示系统状态。最常用的表现层技术是JSP,但JSP并不是唯一的表现层技术。 2、控制器组件:对于JavaEE的MVC框架而言,框架提供一个前端核心控制器,而核心控制器负责拦截用户请求,并将用户请求转发给用户实现的控制器组件。而这些用户实现的控制器则负责处理调用业务逻辑方法,处理用户请求。 3、业务逻辑组件:是系统的核心组件,实现系统的业务逻辑

17 通过ref代替DOM用来获取元素和组件的引用

重点 ref :官网给出的解释是: ref: 用于注册对元素或子组件的引用。引用将在父组件的$refs 对象下注册。如果在普通DOM元素上使用,则引用将是该元素;如果在子组件上使用,则引用将是组件实例: <!-- vm.$refs.p will be the DOM node --><p ref="p">hello</p><!-- vm.$refs.child will be the c