什么是BroadcastReceiver

BroadcastReceiver是Android体系的四大组件之一,本质上是一种全局的监听器,用于监听系统全局的广播消息,正式因为其本质为全局监听,因此可以非常方便的实现系统中不同组件之间的通信。也方便我们自己的app针对系统开机、电量低等广播做出相应反映。同时我们也可以自己发送广播,来实现不同组件之间的通信

系统接收短信广播,然后弹出Toast:

package cn.lixyz.broadcastreceiver;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast; public class MainActivity extends Activity { private IntentFilter filter;
private SMSReceiver sms; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
sms = new SMSReceiver();
registerReceiver(sms, filter); } @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(sms);
} class SMSReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "有短信", Toast.LENGTH_SHORT).show();
Log.d("TTTT", "~~~~~~~");
}
}
}

MainActivity.java

还需要添加权限:

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

运行结果:

Android的大量系统事件都会对外发送广播,下面是常见的广播常量:

ACTION_TIME_CHANGED   系统时间被改变

ACTION_DATE_CHANGED   系统日期被改变

ACTION_TIMEZONE_CHANGED   系统时区被改变

ACTION_BOOT_COMPLETED       系统启动完成

ACTION_PACKAGE_ADDED        系统添加包

ACTION_PACKAGE_CHANGED    系统的包改变

ACTION_PACKAGE_REMOVED     系统的包被删除

ACTION_PACKAGE_RESTARTED  系统的包被重启

ACTION_PACKAGE_DATA_CLEARED    系统的包数据被清空

ACTION_BATTERY_CHANGED     电池电量改变

ACTION_BATTERY_LOW     电池电量低

ACTION_POWER_CONNECTED    系统连接电源

ACTION_POWER_DISCONNECTED      系统与电源断开

ACTION_SHUTDOWN        系统被关闭

Broadcast的类型

广播分为标准广播有序广播

              标准广播是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎在同一时间都会接收到这条广播,没有顺序可言,这种广播效率高,但无法截断。

有序广播则是一种同步执行的广播,在广播发出后,同一时刻只会有一个广播接收器能够接收到这条广播消息,当这个广播接收器中的逻辑执行完毕之后,广播才会继续传递。优先级高的广播接收器可以先接收到,并且可以截断广播,广播被截断后,后面的广播接收器就无法再接收到了。

运行原理

当其他程序发出广播消息之后,所有注册了广播接收器的应用程序都将会检测注册时的过滤器是否与发出的广播消息向匹配,匹配则会调用BroadcastReciver的onReceive()方法进行处理。所以开发BroadcastReciver应用,主要是对onReceive()方法的实现

广播的注册

创建完BroadcastReceiver之后,还不能够使它进入工作状态,我们需要为它注册一个指定的广播地址,否则无法接收广播

静态注册:写在AndroidManifest.xml文件中,注册的广播接收器必须继承BroadReceiver

动态注册:写在代码中使用Context.registerReceiver注册,由Intent来传递注册时用到的Action

广播的收发

刚才说过了,广播分为有序广播和标准广播,那么发送广播的形式也不同

标准广播发送:使用sendBroadcast()发送

有序广播发送:使用sendOrderBroadcast()发送

广播的收取:定义一个继承BroadcastReceiver的类,继承该类后覆盖其onReceiver()方法,并在该方法中响应事件。

有序广播的优先级

有序广播接收器通过intent-filter的priority参数来确定哪个接收器先接收到广播,数值越大,优先级越高,趋势范围在-1000~1000之间,也可以通过abortBroadcast()来阻断广播,阻断之后,之后的接收器则不会再接收到。

本地广播

之前我们看到的都是全局广播,也就是说我们发出的广播,其他应用也可以收到,这就存在安全问题,为了简单的解决安全性问题,Android引入了一套本地广播机制,使用这个机制发出的广播只能够在应用内部进行传递,并且广播接收器也只能接收来自应用程序本身发出的广播。

本地广播使用LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法。

package cn.lixyz.broadcastreceiver;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity { private IntentFilter intentFilter; private LocalBroadcastManager localBroadcastManager; private LocalReceiver localReceiver; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // 获取LocalBroadcastReceiver实例
localBroadcastManager = LocalBroadcastManager.getInstance(this); Button button = (Button) findViewById(R.id.sendlocalBroadcast);
button.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
Intent intent = new Intent("cn.lixyz.broadcastreceiver.localreceiver");
// 发送本地广播
localBroadcastManager.sendBroadcast(intent);
}
}); intentFilter = new IntentFilter();
intentFilter.addAction("cn.lixyz.broadcastreceiver.localreceiver"); localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter); } @Override
protected void onDestroy() {
super.onDestroy();
// unregisterReceiver(myBroadcastReciver);
} class LocalReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
Log.d("TTTT", "接收到了本地广播");
}
}
}

Android笔记(六十)Android总结:四大组件——BroadcastReceiver篇的更多相关文章

  1. Android笔记(六十九) 仿微信界面(一)

          综合之前的Fragment和自定义组件的知识,实现微信界面 MainActivity.java package cn.lixyz.test; import android.app.Acti ...

  2. Android笔记(六十六) android中的动画——XML文件定义属性动画

    除了直接在java代码中定义动画之外,还可以使用xml文件定义动画,以便重用. 如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在 ...

  3. Android笔记(六十八) Fragment总结

    Fragment的产生: 为了适应各种尺寸的屏幕,谷歌推出Fragment,可以把Fragment成Activity的一个组成部分,它拥有自己的生命周期.可以接收并处理用户的各种事件,还可以动态的增删 ...

  4. Android笔记(六十五) android中的动画——属性动画(propertyanimation)

    补间动画只能定义起始和结束两个帧在“透明度”.“旋转”.“倾斜”.“位移”4个方面的变化,逐帧动画也只能是播放多个图片,无法满足我们日常复杂的动画需求,所以谷歌在3.0开始,推出了属性动画(prope ...

  5. Android笔记(六十四) android中的动画——补间动画(tweened animation)

    补间动画就是只需要定义动画开始和结束的位置,动画中间的变化由系统去补齐. 补间动画由一下四种方式: 1.AplhaAnimation——透明度动画效果 2.ScaleAnimation ——缩放动画效 ...

  6. Android笔记(六十二)网络框架volley

    什么是Volley 很多时候,我们的APP都需要用到网络技术,使用HTTP协议来发送接收数据,谷歌推出了一个网络框架——volley,该框架适合进行数据量不大,但通信频繁的网络操作. 它的优点: (1 ...

  7. Android笔记(六十三) android中的动画——逐帧动画( frame-by-frame animation)

    就好像演电影一样,播放实现准备好的图片,来实现动画效果. 逐帧动画需要用到AnimationDrawable类,该类主要用于创建一个逐帧动画,然后我们把这个动画设置为view的背景即可. androi ...

  8. Android Studio(六):Android Studio添加注释模板

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

  9. Android笔记(五十九)Android总结:四大组件——Service篇

    什么是服务? 服务(service)是Android中实现程序后台运行的解决方案,适用于去执行那些不需要和用户交互并且还需要长期运行的任务.服务的运行不依赖于任何用户界面. 服务运行在主线程中,所以在 ...

随机推荐

  1. Linux目录结构和作用

    转载自:https://blog.csdn.net/wangrongrongwq/article/details/79624797 [常见目录说明] 目录 /bin 存放二进制可执行文件(ls,cat ...

  2. postman跳过登陆直接使用的办法

    新版的postman不再是Chrome的插件,而是一个独立的app.下载安装后会提示你注册账户或者登陆.在私有环境,例如实验室,或者单机调试,或者其他VPN隔离的内部环境,无法完成登陆操作. 解决办法 ...

  3. 基因型数据正负链怎么翻转(snp flip)

    在合并数据过程当中,经常会发现不同来源的数据正负链不是统一的,这是一件很头疼的事. 正负链没有统一的情况下直接合并在一起会产生什么后果呢. 举个最简单的例子,假如我们从小明和小红分别拿到了一批基因型数 ...

  4. PAT 甲级 1079 Total Sales of Supply Chain (25 分)(简单,不建树,bfs即可)

    1079 Total Sales of Supply Chain (25 分)   A supply chain is a network of retailers(零售商), distributor ...

  5. xshell的ssh连接频繁提示Socket error Event: 32 Error: 10053(待验证)

    修改/etc/ssh/sshd_config下的配置文件 将ClientAliveInterval的值修改为60 然后重启ssh服务器 目前没有在频繁出现ssh断开问题了,应该是有效的

  6. 安装hbase分布式集群出现的报错- ERROR:org.apache.hadoop.hbase.PleaseHoldException: Master is initializing

    可能的原因如下: 1. 时间没有同步 HBase需要结点间的时间必须是同步的,可以使用date命令在Linux查看时间(同步时间命令:ntpdate 1.cn.pool.ntp.org) 2. 底层采 ...

  7. Activiti6.0流程编辑器汉化教程(en.json文件汉化)

    { "GENERAL": { "MAIN-TITLE": "Activiti", "ERROR": { "GE ...

  8. Django文档阅读之模型

    模型 模型是您的数据唯一而且准确的信息来源.它包含您正在储存的数据的重要字段和行为.一般来说,每一个模型都映射一个数据库表. 基础: 每个模型都是一个 Python 的类,这些类继承 django.d ...

  9. sorted内置函数

    对List.Dict进行排序,Python提供了两个方法 --------------------------------sorted--------------------------------- ...

  10. java有包名的调用没有包名的类,用反射

    没有包名,就是说在根目录,普通项目就是在src下,maven项目就是在src/java目录下 // 通过全类名,没有包名就直接是类名,有包名就要加上包名,比如:com.xiaostudy.TLStri ...