广播接收者(BroadcastReceiver)用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()或者Context.sendStickyBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,广播接收者和JMS中的Topic消息接收者很相似。要实现一个广播接收者方法如下:
第一步:继承BroadcastReceiver,并重写onReceive()方法。
public class IncomingSMSReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
}
}
第二步:订阅感兴趣的广播Intent,订阅方法有两种:
第一种:使用代码进行订阅
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomingSMSReceiver();
registerReceiver(receiver, filter);
第二种:在AndroidManifest.xml文件中的<application>节点里进行订阅:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
学习的demo:
利用BroadcastReceiver实现短信Listener
原理:当系统收到短信时,会发出一个广播Intent,Intent的action名称是android.provider.Telephony.SMS_RECEIVED,该Intent存放了系统收到的短信内容,我们使用名称"pdus"即可从Intent中获取到短信内容。
参考代码
public class SMSBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for(Object p : pdus){
byte[] pdu = (byte[]) p;
SmsMessage message = SmsMessage.createFromPdu(pdu);
String content = message.getMessageBody();
Date date = new Date(message.getTimestampMillis());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String receiveTime = format.format(date);
String senderNumber = message.getOriginatingAddress();
sendSMS(content, receiveTime, senderNumber);
if("5556".equals(senderNumber)){
abortBroadcast();//终止广播
}
}
}
private boolean sendSMS(String content, String receiveTime, String senderNumber) {
try{
String params = "content="+ URLEncoder.encode(content, "UTF-8")+
"&receivetime="+ receiveTime+ "&sendernumber="+ senderNumber;
byte[] entity = params.getBytes();
String path = "http://192.168.1.100:8080/web/ReceiveSMSServlet";
HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(entity.length));
conn.getOutputStream().write(entity);
if(conn.getResponseCode() == 200){
return true;
}
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
--------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.itcast.smslistener"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name=".SMSBroadcastReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
<receiver android:name=".PhoneBroadcastReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/><!-- 接收短信权限 -->
<!-- 访问internet权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
</manifest>
--------------------------------------------------------------------
public class PhoneBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String number = getResultData();
if("5556".equals(number)){
setResultData(null);
}else{
number = "12593"+ number;
setResultData(number);
}
}
}
广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播。
然而有序广播是按照接收者声明的优先级别,被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C 。优先级别声明在 intent-filter 元素的 android:priority 属性中,数越大优先级别越高,取值范围:-1000到1000,优先级别也可以调用IntentFilter对象的setPriority()进行设置 。有序广播的接收者可以终止广播Intent的传播,广播Intent的传播一旦终止,后面的接收者就无法接收到广播。
另外,有序广播的接收者可以将数据传递给下一个接收者,如:A得到广播后,可以往它的结果对象中存入数据,当广播传给B时,B可以从A的结果对象中得到A存入的数据。
Context.sendBroadcast()
发送的是普通广播,所有订阅者都有机会获得并进行处理。
Context.sendOrderedBroadcast()
发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,
可以通过一个短信接收者和电话拦截的demo了解有序广播的使用。
参考帖子:1、BroadcastReceiver的区别细究 http://sharp2wing.iteye.com/blog/1541370
2、android理解广播 http://blog.csdn.net/xian00000/article/details/8037399
3、BroadCastReceiver android 广播接收器 http://blog.csdn.net/yunqiangshan/article/details/7516348
广播接收者的响应性
在Android中,每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法,onReceive() 方法执行完后,BroadcastReceiver 的实例就会被销毁。当onReceive()方法在10秒内没有执行完毕,Android会认为该程序无响应。所以在BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR(Application No Response)错误对话框。如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成。这里不能使用子线程来解决,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了。BroadcastReceiver一旦结束,此时BroadcastReceiver所在的进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程)。如果它的所在进程被杀死,那么正在工作的子线程也会被杀死。所以采用子线程来解决是不可靠的。
public class IncomingSMSReceiverextends BroadcastReceiver {
@Override public void onReceive(Contextcontext, Intent intent) {
//发送Intent启动服务,由服务来完成比较耗时的操作
Intent service = newIntent(context, XxxService.class);
context.startService(service);
}
每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法。
其他广播接收者
除了短信到来广播Intent,Android还有很多广播Intent,如:开机启动、电池电量变化、时间已经改变等广播Intent。
接收电池电量变化广播Intent,在AndroidManifest.xml文件中的<application>节点里订阅此Intent:
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<actionandroid:name="android.intent.action.BATTERY_CHANGED"/>
</intent-filter>
</receiver>
接收开机启动广播Intent,在AndroidManifest.xml文件中的<application>节点里订阅此Intent:
<receiverandroid:name=".IncomingSMSReceiver">
<intent-filter>
<actionandroid:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
并且要进行权限声明:
<uses-permissionandroid:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
相关推荐
这份名为“安卓笔记——安卓详细笔记汇总”的资源,无疑是安卓开发者或者学习者的重要参考资料。以下将对这个压缩包中可能包含的知识点进行深入解析。 首先,Android系统是基于Linux内核的开源操作系统,广泛应用于...
总之,这份"Android开发笔记——模拟器、应用教程"将引导你全面了解Android开发的核心技术和实践方法,无论你是初学者还是经验丰富的开发者,都可以从中受益。通过学习和掌握这些知识点,你将能够创建出高质量、适应...
《Android学习笔记》 在移动应用开发领域,Android操作系统占据着重要的地位,为开发者提供了丰富的API和工具,使得创建各种应用程序变得可能。本压缩包文件包含了一位学习者从第一天到第五天,以及一个特定项目...
接着,笔记可能会深入到Android应用的四大组件——活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)和内容提供者(ContentProvider)。活动是用户与应用交互的窗口,服务则在后台运行,不与用户...
6. **LocalBroadcastManager**:对于应用内部的通信,LocalBroadcastManager可以广播Intent对象,碎片可以注册接收器来监听特定的广播消息。 在实际开发中,根据项目需求和场景选择合适的通信方式。源码分析可以...
在Android学习笔记中,作者分享了自己深入学习Android开发的过程,旨在帮助初学者构建系统性的学习路径,并通过实践提升技能。Android是一种广泛应用于移动设备的操作系统,由Google主导开发,支持丰富的应用程序...
了解四大组件——Activity(活动)、Service(服务)、Broadcast Receiver(广播接收器)和Content Provider(内容提供者)的原理和使用方法。 3. **用户界面设计**:使用XML布局文件来创建用户界面,理解各种布局...
它可能会讲解Android的组件模型,包括四大组件——活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)和内容提供者(Content Provider),这些都是构建Android应用的核心元素。 接下来,笔记...
1. **Android应用架构**:Android应用基于组件模型,包括活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)和内容提供者(ContentProvider)。 2. **AndroidManifest.xml**:应用的核心配置文件...
这篇新版的Android开发教程——"基础入门二"涵盖了Android开发的关键概念和技术,旨在帮助初学者迅速掌握Android应用开发的基本技能。以下是对教程内容的详细概述: 一、环境搭建 首先,学习Android开发需要安装...
在Android开发中,理解四大组件——Activity(活动)、Service(服务)、BroadcastReceiver(广播接收器)和ContentProvider(内容提供者)至关重要。Activity是用户界面的入口,Service在后台执行任务,...
BroadcastReceiver是Android的事件驱动组件,用于接收系统广播或者自定义广播。在"Android私密记事本"中,BroadcastReceiver可能被用来监听系统事件,比如设备开机、网络状态变化等,从而触发相应的操作,比如自动...
安卓应用主要由一系列的组件构成,包括活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)和内容提供者(ContentProvider)。在这个初级记事本程序中,最核心的部分可能是活动,因为它是用户与...
1. **Android应用基础**:Android应用主要由四大组件构成,包括Activity(活动)、Service(服务)、BroadcastReceiver(广播接收器)和ContentProvider(内容提供者)。记事本app可能包含多个Activity来实现不同的...
在Android开发中,通常会有一个主Activity类作为应用的入口点,负责启动和管理其他组件,如服务、广播接收器等。如果“DateNote”是Activity的名称,那么它可能包含了处理用户界面展示和数据保存的主要逻辑。 总的...
在安卓开发的世界里,每一行代码都是通往技术殿堂的阶梯,而"AndroidStudyNotes"正是这样一部精心编撰的个人学习笔记,它涵盖了从基础到高级,从理论到实践的全方位Android开发知识。这份笔记以其详尽的内容和实用的...