您的位置:首页 > 移动开发 > Android开发

Android四大组件之一 广播接收者 BroadcastReceiver

2016-11-12 11:24 806 查看


Android四大组件之一 广播接收者 BroadcastReceiver

(Broadcast 广播 Rceiver 接收者)


【1】为什么需要广播接收者 ?

android 相当于一个电台,定义了许多的广播事件,当产生外拨电话或者短信到来等事件的时候,那么广播接收者就会接收这些广播。

广播接收者简单地说就是接收广播意图的Java类,此Java类继承BroadcastReceiver类,重写:

public void onReceive(Context context,Intent intent),其中intent可以获得传递的数据;

广播意图就是通过Context.sendBroadcast(Intent intent)或Context.sendOrderedBroadcast(Intent intent)发送的意图,通过这个语句,能够广播给所有满足条件的组件,比如intent设置了action="com.xiazdong",则所有在AndroidManifest.xml中设置过<actionAndroid:name="com.xiazdong"/>的广播接收者都能够接收到广播;

来源: <http://blog.csdn.net/xiazdong/article/details/7768807/>


【2】初识BroadcastReceiver --- Ip 拨号器

<!-- 外拨电话需要一个权限 -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

(1)创建一个类去继承 BroadcastReceiver这个类 自动重写 onReceive() 方法

public class OutGoingCallReceiver extends BroadcastReceiver {

public void onReceive(Context context, Intent intent) {

}
}

[/code]

(2) 在配置文件中配置 广播接收者


<!-- 注册广播接收者 -->

<receiver android:name="cn.edu.aynu.shuse.Receiver.OutGoingCallReceiver" >


<!-- 添加意图过滤器 -->

<intent-filter>


<!-- 外拨电话的动作 --> 

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

</intent-filter>

[/code]

(3) 当action 的事件发生了,在广播接收者这个类中的onReceive()这个方法就会被执行。

package cn.edu.aynu.shuse.Receiver;


import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;


/**

* @author 子 广播接收者 四大组件都需要在 AndroidManifast.xml 中进行注册

*/

public class OutGoingCallReceiver extends BroadcastReceiver {


// 当接收到外拨电话的时候,回调此方法

@Override

public void onReceive(Context context, Intent intent) {

// [0] 回调此方法

System.out.println("回调此方法onReceive");

// [1] 返回当前的广播的数据

String phone_number = getResultData();

System.out.println("当前的号码" + phone_number);


// [2]在此电话前面添加一个 区号

if (phone_number.startsWith("0")) {

setResultData("17951" + phone_number);

System.out.println("添加区号的电话" + getResultData());

}


}



[/code]


【3】SD卡的状态监听

注意:在针对SD卡卸载还是装载的时必须候需要添加上一个约束。

<!-- 注册广播接收者 -->

<receiver android:name="cn.edu.aynu.shuse.Receiver.OutGoingCallReceiver" >


<!-- 添加意图过滤器 -->

<intent-filter>



<!-- SD 卡 挂载事件-->

<actionandroid:name="android.intent.action.MEDIA_MOUNTED"/>

<!-- SD卡 卸载事件 -->

<actionandroid:name="android.intent.action.MEDIA_UNMOUNTABLE"/>

<!-- 支持SD 卡的事件 必须写一个约束 -->

<dataandroid:scheme="file"/>


</intent-filter>



</receiver>

[/code]

判断SD 是否装载 或 卸载

// 当接收到外拨电话的时候,回调此方法

@Override

public void onReceive(Context context, Intent intent) {


// 用于返回动作事件

String action = intent.getAction();

if ("android.intent.action.MEDIA_MOUNTED".equals(action)) {

// 说明SD卡被挂载了

System.out.println("SD卡被挂载了");


} else if ("android.intent.action.MEDIA_UNMOUNTED".equals(action)) {

// 说明SD卡被卸载了

System.out.println("SD卡被卸载了");



}


}

[/code]

【4】短息的监听

<!-- 接收短息的权限 -->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

注意:监听短息的动作事件已经在安装在 Eclipse 上20以后的ADT 上面去掉。需要这个事件需要自己手动写
在配置文件中配置

<!-- 注册广播接收者 -->

<receiver android:name="cn.edu.aynu.shuse.Receiver.OutGoingCallReceiver" >


<!-- 添加意图过滤器 -->

<intent-filter>


<!-- 短息监听的事件 -->

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

</intent-filter>

</receiver>

[/code]

(2)使用到一个新的api获取短信息的一个类SmsMessage

// 当接收到接收到短息的时候,回调此方法

@Override

public void onReceive(Context context, Intent intent) {


System.out.println("短信被检测到了");


Object[] object = (Object[]) intent.getExtras().get("pdus");

for (Object smss : object) {

// 创建一个SmsMessage 类对象

SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) smss);


// 获取发送短息的内容

String messageBody = smsMessage.getMessageBody();

// 获取发送者的电话号

String originatingAddress = smsMessage.getOriginatingAddress();

//

Toast.makeText(context, messageBody + "" + originatingAddress,Toast.LENGTH_LONG).show();



}

}

[/code]


【5】 广播接收者在不同版本上的差异

在2.3 版本的手机上,广播事件都是可以执行的。比如监听短信的到来。

可以直接创建无图标 和 无界面的应用

在4.0 版本以后的手机上,广播事件都一些比较恶意的,都已经被禁用掉了。

4.0以后的手机创建无图标 和无界面的应用,第一次安装应用必须有界面,否则创建的广播事件是不会生效的。


【5.1】 创建无图标和无界面的应用只需要将 配置文件中 声明的主界面中的 intent-filter 删除即可。http://www.cnblogs.com/allenzheng/p/4510725.html

在低版本的手机上 2.3

<intent-filter>

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


<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

[/code]

在高版本上 4.0 以上

 <intent-filter>

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


<category android:name="android.intent.category.DEFAULT" />

</intent-filter>

[/code]

<!-- 要想在桌面不显示图标,只需注释掉APP入口Activity中的下面这句即可,或者把下面的LAUNCHER改成DEFAULT也行 -->



【6】手机应用的卸载 和 安装的广播事件

(1) 创建一个类继承 BroadcastReceiver 类 自动重写 onReceive() 方法

String action = intent.getAction();

if ("android.intent.action.PACKAGE_INSTALL".equals(action)) {

System.out.println("应用被安装");

}else if ("android.intent.action.PACKAGE_ADDED".equals(action)) {

System.out.println("应用被安装add");


}else if ("android.intent.action.PACKAGE_REMOVED".equals(action)) {

System.out.println("应用被卸载"+getResultData());

}

[/code]

(2)在配置文件中配置 receive 信息,主要配置 action 信息

注意: 在配置 手机应用是否 卸载 和 安装 的广播事件上,需要配置一个data 约束(scheme)
名为 package

<!-- 注册广播接收者 -->

<receiver android:name="cn.edu.aynu.shuse.Receiver.OutGoingCallReceiver" >


<!-- 添加意图过滤器 -->

<intent-filter>

<!-- 应用的安装 -->

<action android:name="android.intent.action.PACKAGE_INSTALL"/> <!--这个是谷歌程序员预留的动作事件 -->

<action android:name="android.intent.action.PACKAGE_ADDED"/> <!-- 这个是真正的手机应用安装事件 -->

<!-- 应用的卸载 -->

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

 

<!-- 支持手机应用的卸载和安装 必须有一个约束 -->

<data android:scheme="package"/>

</intent-filter>

</receiver>

[/code]



【7】手机重启广播事件

(1)创建一个类继承于BroadcastReceiver

// 当手机重新启动 就跳转界面

Intent intent2= new Intent(context, MainActivity.class);

// 如果在广播接收者里面开启 activity 界面,需要设置一个任务栈环境

intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

context.startActivity(intent2);

[/code]

(2) 配置receive 的action

<!-- 手机重启的权限 -->
<uses-permissionandroid:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<!-- 注册广播接收者 -->

<receiver android:name="cn.edu.aynu.shuse.Receiver.OutGoingCallReceiver" >


<!-- 添加意图过滤器 -->

<intent-filter>

 <!-- 手机的重启 -->

 <actionandroid:name="android.intent.action.BOOT_COMPLETED"/> <!-- 需要加一个权限 -->

</intent-filter>

</receiver>

[/code]


小知识点: 怎么禁用手机物理按钮的返回按钮。


@Override

public void onBackPressed() {


//删除调用父类方法


}

[/code]


【8】广播的两种方式 :有序广播和 无序广播

无序广播: 类似于新闻联播,你看不看它都准时播放

发送方发出后,几乎同时到达多个广播接收者处,某个接收者不能接收到广播后进行一番处理后传给下一个接收者,并且无法终止广播继续传播;Context.sendBroadcast(intent);

有序广播:类似于习大大发大米 一级一级向下进行

广播接收者需要提前设置优先级,优先级高的先接收到广播,优先级数值为-1000~1000,在AndroidManifest.xml的<intent-filter android:priority="xxx">设置;比如存在3个广播接收者A、B、C,优先级A>B>C,因此A最先收到广播,当A收到广播后,可以向广播中添加一些数据给下一个接收者(intent.putExtra()),或者终止广播(abortBroadcast());Context.sendOrderedBroadcast(intent);
来源: http://www.cnblogs.com/wanghaoyuhappy/p/5292733.html

api有说明

There are two major classes of broadcasts that can be received:

Normal broadcasts (sent with
Context.sendBroadcast
)
are completely asynchronous. All receivers of the broadcast are run in an undefined order, often at the same time. This is more efficient, but means that receivers cannot use the result or abort APIs included here.
Ordered broadcasts (sent with
Context.sendOrderedBroadcast
)
are delivered to one receiver at a time. As each receiver executes in turn, it can propagate a result to the next receiver, or it can completely abort the broadcast so that it won't be passed to other receivers. The order receivers run in can be controlled
with the
android:priority
attribute of the matching intent-filter;
receivers with the same priority will be run in an arbitrary order.

翻译:
有两个主要类型的广播,可以接受:

正常广播(发送Context.sendBroadcast)是完全异步的。所有的广播接收器都是运行在一个未定义的顺序,常常在同一时间。这是更有效,但意味着接收器不能使用结果或中止api包含在这里。

有序广播(发送Context.sendOrderedBroadcast)交付给一个接收器。反过来,因为每个接收器执行结果传播到下一个接收器,也可以完全终止广播,以便它不会传递给其他接收器。订单接收器可以控制运行在android:优先级属性匹配的意图过滤器;具有相同优先级的接收器将运行在一个任意的顺序。

【8.1】演示无序广播----新闻联播(自定义的广播事件)


无序广播

【1】无序广播的发送

// 发送无序广播


Intent intent = new Intent();

// 【2】设置action

intent.setAction("cn.edu.aynu.sushe");

// 【2.1】设置额外的数据

intent.putExtra("name", "新闻联播7点准时开始");

// 【3】 发送广播

this.sendBroadcast(intent);

[/code]

【2】无序广播的接收
(1)创建一个类 继承于BroadcastReceiver 这个类,重写其中的 onReceive() 方法

package cn.edu.aynu.shuse1;


import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.widget.Toast;


public class ReceiverCustomBroadcast extends BroadcastReceiver {


@Override

public void onReceive(Context context, Intent intent) {

// 接收定制的广播

//【1】取出我们发送广播的数据

String stringExtra = intent.getStringExtra("name");


Toast.makeText(context, stringExtra, Toast.LENGTH_LONG).show();


}

}
[/code]

(2)配置清单文件

 <!-- 注册广播接收者-->

<receiver android:name="cn.edu.aynu.shuse1.ReceiverCustomBroadcast">

<!--添加意图过滤器-->

<intent-filter >

<!-- 自定义的动作,可以添加多个 -->

<action android:name="cn.edu.aynu.sushe"/>


</intent-filter>


[/code]

有序广播

【1】有序广播的发送

public void sendOrderBroadcast(View v) {


Intent intent = new Intent();

intent.setAction("com.aynu.shijie");

/**参数解释 

 *intent意图

 *receiverPermission 接收这条广播具备什么权限

 *resultReceiver最终的广播接受者,广播一定会传给它

 *scheduler handler对象处理广播的分发

 *initialCode 初始代码

 *initialData 初始数据

 *initialExtras 额外的数据,如果觉得初始数据不够,可以通过bundle来指定其他数据

*/

sendOrderedBroadcast(intent, null, null, null, 1, "有序广播开始发送", null);


}

[/code]

【2】有序广播接收

(1)创建一个类继承 BoradcastReceiver 重新 onReceive()方法

package cn.edu.aynu.shuse1;


import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.widget.Toast;


public class ReceiverCustomBroadcast3 extends BroadcastReceiver {


@Override

public void onReceive(Context context, Intent intent) {

// 接收定制的广播

// 【1】取出我们发送广播的数据

String resultData = getResultData();

//重写数据
setResultData("发送广播32131231231");
Toast.makeText(context, resultData + "2", Toast.LENGTH_LONG).show();

}


}

[/code]

(2) 在清单文件中配置 receive 信息

</receiver>


<receiver android:name="cn.edu.aynu.shuse1.ReceiverCustomBroadcast3">


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

<action android:name="com.aynu.shijie"/>


</intent-filter>


</receiver>

[/code]


终止广播

无序广播不能被终止掉,有序广播可以被终止掉。

终止广播方法

abortBroadcast(); // 终止广播
是BoradcastReceiver 的方法

【9】特殊的广播接收者

比如操作特别频繁的广播事件 屏幕的锁屏和解锁 电池电量的变化 这样的广播接收者在清单文件里面注册无效


/* <receiver android:name="com.itheima.screen.ScreenReceiver">

 <intent-filter >

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

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

 </intent-filter>

 </receiver>*/

 

//[1]动态的去注册屏幕解锁和锁屏的广播

screenReceiver = new ScreenReceiver();

//[2]创建intent-filter对象

IntentFilter filter = new IntentFilter();

//[3]添加要注册的action

filter.addAction("android.intent.action.SCREEN_OFF");

filter.addAction("android.intent.action.SCREEN_ON");

//[4]注册广播接收者

this.registerReceiver(screenReceiver, filter);

[/code]

package com.itheima.screen;


import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;


public class ScreenReceiver extends BroadcastReceiver {


@Override

public void onReceive(Context context, Intent intent) {


//[1]获取到当前广播的事件类型

String action = intent.getAction();

//[2]对当前广播事件类型做一个判断


if ("android.intent.action.SCREEN_OFF".equals(action)) {


System.out.println("屏幕锁屏了");

}else if ("android.intent.action.SCREEN_ON".equals(action)) {


System.out.println("说明屏幕解锁了~~~");

}


}


}

[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: