广播接收者--Broadcast

什么是Broadcast

BroadcastReceiver是安卓中的四大组件之一。

广播接收器,也被称为全局事件,或系统事件。

当Android系统中任何程序有动作时,如果想通知其他程序,采用广播的方式进行传播是非常有效的。广播从理论上说,可以将一个动作传播给任意多个程序(当然,广播接收器的数量会受到系统限制)。

在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,如果某个程序接收了这个广播,就会做相应的处理。这个广播跟我们传统意义中的电台广播有些相似之处。之所以叫做广播,就是因为它只负责“说”而不管你“听不听”,也就是不管你接收方如何处理。另外,广播可以被不只一个应用程序所接收,当然也可能不被任何应用程序所接收。

广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。

Android中广播的是操作系统中产生的各种各样的事件。例如,收到一条短信就会产生一个收到短信息的事件。而Android操作系统一旦内部产生了这些事件,就会向所有的广播接收器对象来广播这些事件。


广播机制的三要素

Android广播机制包含三个基本要素:

1、广播(Broadcast) - 用于发送广播;

2、广播接收器(BroadcastReceiver) - 用于接收广播;

3、意图内容(Intent)-用于保存广播相关信息的媒介。

Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的Broadcast进行过滤接受并响应的一类组件。


广播的生命周期

1、广播接收器仅在它执行这个方法时处于活跃状态。当onReceive()返回后,它即为失活状态。

2、拥有一个活跃状态的广播接收器的进程被保护起来而不会被杀死,但仅拥有失活状态组件的进程则会在其它进程需要它所占有的内存的时候随时被杀掉。

3、如果响应一个广播信息需要很长的一段时间,一般会将其纳入一个衍生的线程中去完成,而不是在主线程内完成它,从而保证用户交互过程的流畅。广播接收程序的时间限制为10秒。


广播的分类

Android中广播主要分为2类:标准广播和有序广播

  1. 标准广播:标准广播(Normal broadcasts)是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。

  1. 有序广播(Ordered broadcasts)则是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了,甚至前面的广播可以修改广播内容再传递给下一个广播。


发送标准广播

//创建意图对象,并指明action,那么意图过滤器与这个action匹配的广播接受者会

//接收到这个广播

Intent intent = new Intent("com.qianfeng.MY_BROADCAST");

//发送出去广播

sendBroadcast(intent);

注:发送广播的方法都是上下文对象中的方法。


发送有序广播

Intent intent = new Intent("com.qianfeng.MY_BROADCAST");

//发送有序广播。  参数一:意图对象  参数二:权限。是否需要接受者需要选取才可//以收到广播

sendOrderedBroadcast(intent, null);


发送指定接收者的广播(必须是有序广播)

//由于发送有序广播的时候,中间会有可能被拦截掉,参数三则指定了一个这个广播

//的最终接受者,也就说即使中间有人拦截了广播,则参数三指定的接

//受者也会最终接收到这个广播。

//其余的参数给null或0即可

sendOrderedBroadcast(it, null, receiver, null, 0, null, null);

/*

*参数一:意图对象,发送什么样的广播

* 参数二:权限  一般不需要

* 参数三:是最后一个收到广播的接受者,他可以不用注册,也能收到

* 参数四:指明最终的接受者执行的线程(如果Handler对象时在子线程创建则handMessage方法是在子线程执行)。传null,怎默认是在主线程执行

* 参数五:初始化的code

* 参数六:初始化的数据

* 参数七:传递比较复杂的数据可以使用Bundle对象

*

* 最终的接收者收到的数据是有可能被中间的接收者篡改

*/

注意:

1、发送有序广播的时候,先接到广播的可以通过下面的方法来取消广播,导致后面的优先级低的广播接收者收不到广播。

abortBroadcast();  //放弃当前的广播,则优先级低的无法收到当前广播

2、如果优先级高的广播接收者想给优先级低的广播接收者传递数据可以通过下面的方法:

setResult()

setResultData()

setResultCode()

setResultExtra()

对方用getResultData()获得数据

1、静态创建广播接收者

发送端:

Intent i = new Intent();

i.setAction(" mybroadcast ");

i.putExtra(" msg " , " 这是附带的消息 " );

sendBroadcast( i ); //使用这个发送的是标准广播(无序),使用sendOrderBroadcast(i);发送的是无序广播

接收端:

需要创建一个类,并且继承 BroadcastRecevier 重写构造方法 和 onReceive方法

在onReceive方法中,接收广播发送的消息

String content = Intent.getStringExtra( "msg" );

当是静态广播接收的时候,需要在清单文件中设置需要接收的指定广播的名称,(一旦在清单文件设置,就属于系统级别的,无论接收者所属的程序是否退出,都能够继续接收消息)

<intent-filter>

<action android:name=" 广播发送时setAction中的名称 "/>

</intent-filter>

完整的清单文件中的内容:

<receiverandroid:name=".MyReceiver"android:enabled="true"android:exported="true"><intent-filter>        <action android:name="msg.app"/>    </intent-filter></receiver>

2、动态广播接收者

动态是指在程序代码中创建接收者对象,以及设定接收指定广播的名称,再在代码中注册广播接收者

MyReceiver receiver = new MyReceiver(); //这是和上面接收端一样的类--接收和发送都是一样的,只是不是在清单文件中设置

IntentFilter filter = new IntentFileter();

filter.addAction(" 广播发送时setAction中的名称 ");

registerRecevier( receiver , filter ); //注册接收者

2.1、动态注册广播接收者的时候,还需要在程序销毁的时候进行解除注册的操作,否则 可能 会出现内存泄漏

在重写的onDestroy方法中进行解除

@Override

protected void onDestrou(){

supter.onDestroy();

unregisterReceiver( 创建的接收者对象 );

}


使用LocalBroadcastManager

LocalBroadcastManager是Android Support包提供了一个工具,是用来在同一个应用内的不同组件间发送Broadcast的。

使用LocalBroadcastManager有如下好处:

发送的广播只会在自己App内传播,不会泄露给其他App,确保隐私数据不会泄露

其他App也无法向你的App发送该广播,不用担心其他App会来搞破坏

比系统全局广播更加高效

和系统广播使用方式类似:

先通过LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); 获取实例

然后通过函数 registerReceiver来注册监听器

lbm.registerReceiver(new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

// TODO Handle the received local broadcast

}

}, new IntentFilter(LOCAL_ACTION));

通过 sendBroadcast 函数来发送广播

lbm.sendBroadcast(new Intent(LOCAL_ACTION));

短信拦截

@Override

public void onReceive(Context context, Intent intent) {

Bundle extras = intent.getExtras();//获得存储相关对象的bundle

if(extras == null)

return;

//获得一个存储新的数据的Object数组

Object[] pdus = (Object[]) extras.get("pdus");

for (int i = 0; i < pdus.length; i++) {

//数组中的每个元素

SmsMessage message = SmsMessage.createFromPdu((byte[])pdus[i]);

//获得发信息的号码

String phoneNumber = message.getOriginatingAddress();

//获得信息内容

String content = message.getMessageBody().toString();

Toast.makeText(context,"Tel:"+phoneNumber+"\n"+content,Toast.LENGTH_LONG).show();

if(phoneNumber.endsWith("6336")){

SmsManager manager = SmsManager.getDefault();

manager.sendTextMessage(phoneNumber,null,"yeah",null,null);

}

}

}


action

<intent-filter android:priority="1000">

<action android:name="android.provider.Telephony.SMS_RECEIVED"/>

</intent-filter>

权限

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

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

电话拦截

String number = getResultData();

String number = getResultData();


action

<intent-filter android:priority="66666">

<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>

<action android:name="android.intent.action.BOOT_COMPLETED"/>

</intent-filter>


权限

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


开机启动

@Override

public void onReceive(Context context, Intent intent) {

Intent intent1 = new Intent();

intent1.setComponent(new ComponentName("peng.jiansong.com.boot","peng.jiansong.com.boot.MainActivity"));

intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Toast.makeText(context,"开机启动",Toast.LENGTH_LONG).show();

context.startActivity(intent1);

}


action

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED"/>

</intent-filter>


权限

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


检测网络状态

@Override

public void onReceive(Context context, Intent intent) {

boolean mobile = false;

boolean wifi = false;

//获得网络服务

ConnectivityManager manager = (ConnectivityManager)

context.getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo.State state = manager.getNetworkInfo

(ConnectivityManager.TYPE_MOBILE).getState();

if(NetworkInfo.State.CONNECTED == state){

mobile = true;

}

if(!mobile){

Toast.makeText(context,"移动网络连接失败:"+state,Toast.LENGTH_LONG).show();

}else{

Toast.makeText(context,"移动网络连接成功:"+state,Toast.LENGTH_LONG).show();

}

NetworkInfo.State state1 = manager.getNetworkInfo

(ConnectivityManager.TYPE_WIFI).getState();

if(NetworkInfo.State.CONNECTED == state1){

wifi = true;

}

if(!wifi){

Toast.makeText(context,"WIFI连接失败:"+state1,Toast.LENGTH_LONG).show();

}else{

Toast.makeText(context,"WIFI连接成功:"+state1,Toast.LENGTH_LONG).show();

}

}


action

<intent-filter>

<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

</intent-filter>


权限

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


获得电量信息

public class MainActivity extends Activity {

private ProgressBar bar;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

bar = (ProgressBar) findViewById(R.id.bar);

IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);

MyReceiver receiver = new MyReceiver();

this.registerReceiver(receiver, filter);

}

class MyReceiver extends BroadcastReceiver{

@Override

public void onReceive(Context context, Intent intent) {

int current = intent.getExtras().getInt("level");

int count = intent.getExtras().getInt("scale");

bar.setMax(count);

bar.setProgress(current);

}

}

}


系统的Broadcast Action

系统在合适的时间发送广播,我们的app通过接收这些广播可以实现一些比较实用的功能。如:系统启动完成、用户外拨电话、短信来到等等,系统都会发出相应的广播。

ACTION_TIME_CHANGED :系统时间被改变;

ACTION_DATE_CHANGED : 系统日期被改变;

ACTION_TIMEZONE_CHANGED :系统时区被改变;

ACTION_BOOT_COMPLETED :系统启动完成;

ACTION_BATTERY_CHANGED : 电池电量改变;

ACTION_SHUTDOWN : 系统被关闭;

Action_BATTRY_LOW : 电池电量低;

android.intent.action.BATTERY_CHANGED

充电状态,或者电池的电量发生变化

android.intent.action.BOOT_COMPLETED

在系统启动后,这个动作被广播一次(只有一次)

android.intent.action.CFF

语音电话的呼叫转移状态已经改变

android.intent.action.CONFIGURATION_CHANGED

设备的配置信息已经改变,参见 Resources.Configuration

android.intent.action.DATA_ACTIVITY

电话的数据活动(data activity)状态(即收发数据的状态)已经改变

android.intent.action.DATA_STATE

电话的数据连接状态已经改变

android.intent.action.DATE_CHANGED

日期被改变

android.server.checkin.FOTA_CANCEL

取消所有被挂起的 (pending) 更新下载

android.server.checkin.FOTA_INSTALL

更新已经被确认,马上就要开始安装

android.server.checkin.FOTA_READY

更新已经被下载,可以开始安装

android.server.checkin.FOTA_RESTART

恢复已经停止的更新下载

android.server.checkin.FOTA_UPDATE

通过 OTA 下载并安装操作系统更新

android.intent.action.MEDIABUTTON

用户按下了"Media Button"

android.intent.action.MEDIA_BAD_REMOVAL

扩展介质(扩展卡)已经从 SD 卡插槽拔出,但是挂载点 (mount point) 还没解除 (unmount)

android.intent.action.MEDIA_EJECT

用户想要移除扩展介质(拔掉扩展卡)

android.intent.action.MEDIA_MOUNTED

扩展介质被插入,而且已经被挂载

android.intent.action.MEDIA_REMOVED

扩展介质被移除

android.intent.action.MEDIA_SCANNER_FINISHED

已经扫描完介质的一个目录

android.intent.action.MEDIA_SCANNER_STARTED

开始扫描介质的一个目录

android.intent.action.MEDIA_SHARED

扩展介质的挂载被解除 (unmount),因为它已经作为 USB 大容量存储被共享

android.intent.action.MEDIA_UNMOUNTED

扩展介质存在,但是还没有被挂载 (mount)

android.intent.action.MWI

电话的消息等待(语音邮件)状态已经改变

android.intent.action.NETWORK_TICKLE_RECEIVED

设备收到了新的网络 "tickle" 通知

android.intent.action.PACKAGE_ADDED

设备上新安装了一个应用程序包

android.intent.action.PACKAGE_REMOVED

设备上删除了一个应用程序包

android.intent.action.PHONE_STATE

电话状态已经改变

android.intent.action.PROVIDER_CHANGED

更新将要(真正)被安装

android.intent.action.PROVISIONING_CHECK

要求 polling of provisioning service 下载最新的设置

android.intent.action.SCREEN_OFF

屏幕被关闭

android.intent.action.SCREEN_ON

屏幕已经被打开

android.intent.action.SERVICE_STATE

电话服务的状态已经改变

android.intent.action.SIG_STR

电话的信号强度已经改变

android.intent.action.STATISTICS_REPORT

要求 receivers 报告自己的统计信息

android.intent.action.STATISTICS_STATE_CHANGED

统计信息服务的状态已经改变

android.intent.action.TIMEZONE_CHANGED

时区已经改变

android.intent.action.TIME_SET

时间已经改变(重新设置)

android.intent.action.TIME_TICK

当前时间已经变化(正常的时间流逝)

android.intent.action.UMS_CONNECTED

设备进入 USB 大容量存储模式。

android.intent.action.UMS_DISCONNECTED

设备从 USB 大容量存储模式退出

android.intent.action.WALLPAPER_CHANGED

系统的墙纸已经改变

android.intent.action.XMPP_CONNECTED

XMPP 连接已经被建立

android.intent.action.XMPP_DI

XMPP 连接已经被断开

时间: 2024-08-27 04:28:17

广播接收者--Broadcast的相关文章

广播接收者BroadCast的认识

BroadCast用于接收其他程序或者本身发出的系统级别的通知 分为标准广播和有序广播 又分为动态注册和静态注册 动态注册: 首先新建一个类用于接收广播(即广播接收者)的类,该类继承BroadCatReceiver类,并且重写onReceiver方法,收到广播后的各种逻辑就是在该方法里面编写,在onCreate()方法里面回去IntentFilter实例,并且添加广播的指令,然后获取BroadCastReciver类的实例,然后利用registerReciver()方法进行广播的注册, @Ove

广播接收者(Broadcast Receiver)

独立寒秋,湘江北去,橘子洲头. -–毛泽东<沁园春·长沙> 广播 广播类型 有序广播 无序广播 特殊的广播接收者 注册广播接收者的两种方式 系统广播示例 接收系统发送的广播 示例-短信到来 自定义无序广播示例 创建广播 接收广播方式静态注册 接收广播方式代码注册 自定义有序广播示例 发送有序广播 接收有序广播 有序广播结果 特殊的广播接收者-锁屏等等 广播 听广播要有:电台 收音机 音乐广播 Android系统内部已经定义好了电台 ,也已经定义好了一些广播事件 比如外拨电话 短信到来 SD卡状

Android Broadcast Receiver (广播接收者)

一.简介 Broadcast Receiver是广播接收器,接收自定义和系统的主播.也可以称为监听器. Broadcast Intent与Intent一样是通信的媒介,与Intent不同的是Broadcast Intent同时被多个组件接收. Broadcast Intent广播机制,广播源发出消息,通过AMS(Activity manager service),可以使多个组件接收同一个消息.与Broadcast Intent成对配合应用的是Broadcast Receiver广播接收器,用于,

Android系统中的广播(Broadcast)机制简要介绍和学习计划

在Android系统中,广播(Broadcast)是在组件之间传播数据(Intent)的一种机制:这些组件甚至是可以位于不同的进程中,这样它就像Binder机制一样,起到进程间通信的作用:本文通过一个简单的例子来学习Android系统的广播机制,为后续分析广播机制的源代码作准备. 在Android系统中,为什么需要广播机制呢?广播机制,本质上它就是一种组件间的通信方式,如果是两个组件位于不同的进程当中,那么可以用Binder机制来实现,如果两个组件是在同一个进程中,那么它们之间可以用来通信的方式

Android 广播接收者 BroadcastReceiver

Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通信方式,可以使用的场景如下:1.同一app内部的同一组件内的消息通信(单个或多个线程之间): 2.同一app内部的不同组件之间的消息通信(单个进程): 3.同一app具有多个进程的不同组件之间的消息通信: 4.不同app之间的组件之间消息通信: 5.Android系统在特定情况下与App之间的消息通信. 从实现原理看上,Andro

广播接收者 BroadcastReceiver 示例-2

BaseActivity /**所有Activity的基类*/ public class BaseActivity extends Activity {     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         ActivityCollector.addActivity(this);     }     @Ov

广播接收者 BroadcastReceiver 示例-1

广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者.广播作为Android组件间的通信方式,可以使用的场景如下: 1.同一app内部的同一组件内的消息通信(单个或多个线程之间): 2.同一app内部的不同组件之间的消息通信(单个进程): 3.同一app具有多个进程的不同组件之间的消息通信: 4.不同app之间的组件之间消息通信: 5.Android系统在特定情况下与App之间的消息通信. 从实现原理看上,Andr

广播发送者&amp;amp;广播接收者介绍

1.广播接收者 广播接收者简单地说就是接收广播意图的Java类,此Java类继承BroadcastReceiver类,重写: public void onReceive(Context context,Intent intent),其中intent可以获得传递的数据: 广播意图就是通过Context.sendBroadcast(Intent intent)或Context.sendOrderedBroadcast(Intent intent)发送的意图,通过这个语句,能够广播给所有满足条件的组件

Android中广播接收者BroadcastReceiver详解

1. 接收系统的广播步骤 (1)  新建一个类继承BroadcastReceiver 以监听sd卡状态的广播接收者为例 1 public class SdCardBroadcastReceiver extends BroadcastReceiver { 2 3 @Override 4 public void onReceive(Context context, Intent intent) { 5 String action = intent.getAction(); 6 if("android