`
zhengjj_2009
  • 浏览: 153129 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

曾经的笔记——android的学习笔记(广播接收者)

 
阅读更多

广播接收者(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里不能做一些比较耗时的操作,否侧会弹出ANRApplication No Response)错误对话框。如果需要完成一项比较耗时的工作,应该通过发送IntentService,由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() 方法。

 

其他广播接收者

除了短信到来广播IntentAndroid还有很多广播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开发笔记——模拟器、应用教程 pdf

    总之,这份"Android开发笔记——模拟器、应用教程"将引导你全面了解Android开发的核心技术和实践方法,无论你是初学者还是经验丰富的开发者,都可以从中受益。通过学习和掌握这些知识点,你将能够创建出高质量、适应...

    android学习笔记.zip

    《Android学习笔记》 在移动应用开发领域,Android操作系统占据着重要的地位,为开发者提供了丰富的API和工具,使得创建各种应用程序变得可能。本压缩包文件包含了一位学习者从第一天到第五天,以及一个特定项目...

    Android群英传笔记

    接着,笔记可能会深入到Android应用的四大组件——活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)和内容提供者(ContentProvider)。活动是用户与应用交互的窗口,服务则在后台运行,不与用户...

    Android学习笔记(十六)——碎片之间进行交互(附源码)

    6. **LocalBroadcastManager**:对于应用内部的通信,LocalBroadcastManager可以广播Intent对象,碎片可以注册接收器来监听特定的广播消息。 在实际开发中,根据项目需求和场景选择合适的通信方式。源码分析可以...

    Android学习笔记

    在Android学习笔记中,作者分享了自己深入学习Android开发的过程,旨在帮助初学者构建系统性的学习路径,并通过实践提升技能。Android是一种广泛应用于移动设备的操作系统,由Google主导开发,支持丰富的应用程序...

    android 学习笔记

    了解四大组件——Activity(活动)、Service(服务)、Broadcast Receiver(广播接收器)和Content Provider(内容提供者)的原理和使用方法。 3. **用户界面设计**:使用XML布局文件来创建用户界面,理解各种布局...

    Android开发教程笔记完全版

    它可能会讲解Android的组件模型,包括四大组件——活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)和内容提供者(Content Provider),这些都是构建Android应用的核心元素。 接下来,笔记...

    安卓Android源码——安卓桌面EyeRoom.zip

    1. **Android应用架构**:Android应用基于组件模型,包括活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)和内容提供者(ContentProvider)。 2. **AndroidManifest.xml**:应用的核心配置文件...

    新版Android开发教程;笔记--基础入门二

    这篇新版的Android开发教程——"基础入门二"涵盖了Android开发的关键概念和技术,旨在帮助初学者迅速掌握Android应用开发的基本技能。以下是对教程内容的详细概述: 一、环境搭建 首先,学习Android开发需要安装...

    Android-LearningNotes.zip

    在Android开发中,理解四大组件——Activity(活动)、Service(服务)、BroadcastReceiver(广播接收器)和ContentProvider(内容提供者)至关重要。Activity是用户界面的入口,Service在后台执行任务,...

    Android私密记事本

    BroadcastReceiver是Android的事件驱动组件,用于接收系统广播或者自定义广播。在"Android私密记事本"中,BroadcastReceiver可能被用来监听系统事件,比如设备开机、网络状态变化等,从而触发相应的操作,比如自动...

    安卓Android源码——初初级记事本程序,直接写文件.zip

    安卓应用主要由一系列的组件构成,包括活动(Activity)、服务(Service)、广播接收器(BroadcastReceiver)和内容提供者(ContentProvider)。在这个初级记事本程序中,最核心的部分可能是活动,因为它是用户与...

    一个完整的记事本app

    1. **Android应用基础**:Android应用主要由四大组件构成,包括Activity(活动)、Service(服务)、BroadcastReceiver(广播接收器)和ContentProvider(内容提供者)。记事本app可能包含多个Activity来实现不同的...

    自己从零编写的Android记事本APP软件

    在Android开发中,通常会有一个主Activity类作为应用的入口点,负责启动和管理其他组件,如服务、广播接收器等。如果“DateNote”是Activity的名称,那么它可能包含了处理用户界面展示和数据保存的主要逻辑。 总的...

    AndroidStudyNotes:AndroidStudyNotes个人学习笔记

    在安卓开发的世界里,每一行代码都是通往技术殿堂的阶梯,而"AndroidStudyNotes"正是这样一部精心编撰的个人学习笔记,它涵盖了从基础到高级,从理论到实践的全方位Android开发知识。这份笔记以其详尽的内容和实用的...

Global site tag (gtag.js) - Google Analytics