android开发之短信监听拦截_BroadcastReceiver的使用

1.广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。     普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高, 但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播。          有序广播是按照接收者声明的优先级别,被

大家好,又见面了,我是全栈君。

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 的多个广播接收者所接收。

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

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

public class IncomingSMSReceiver extends BroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent) { 
//操作..
   }            
}

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

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

IntentFilter filter = new IntentFilte("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>

 

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

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

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

所以在BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR(Application No Response)的对话框。 
 如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成。 
这里不能使用子线程来解决,因为 BroadcastReceiver 的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了。 
BroadcastReceiver一旦结束,此时BroadcastReceiver所在的进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程)。 
如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死。所以采用子线程来解决是不可靠的。 

 

 

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

接收电池电量变化广播Intent ,在AndroidManifest.xml文件中的<application>节点里订阅此Intent: 

<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED"/>
</intent-filter>
</receiver>

 

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

<receiver android:name=".IncomingSMSReceiver"> 
<intent-filter> 
 <action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

 

并且要进行权限声明:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

 

 5.接受系统的短信广播,操作短信内容。

AndroidManifest.xml

<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>

<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>

 

<!-- Receiver -->

<receiver android:name=".sms.SMSReceiver">

<intent-filter>

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

</intent-filter>

</receiver>

java:

package org.anymobile.demo.sms;

 

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.telephony.gsm.SmsMessage;

import android.util.Log;

 

public class SMSReceiver extends BroadcastReceiver

{

    public static final String TAG = "ImiChatSMSReceiver";

    //android.provider.Telephony.Sms.Intents

    public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";

   

    @Override

    public void onReceive(Context context, Intent intent)

    {

       if (intent.getAction().equals(SMS_RECEIVED_ACTION))

       {

           SmsMessage[] messages = getMessagesFromIntent(intent);

           for (SmsMessage message : messages)

           {

              Log.i(TAG, message.getOriginatingAddress() + " : " +

                  message.getDisplayOriginatingAddress() + " : " +

                  message.getDisplayMessageBody() + " : " +

                  message.getTimestampMillis());

           }

       }

    }

   

    public final SmsMessage[] getMessagesFromIntent(Intent intent)

    {

        Object[] messages = (Object[]) intent.getSerializableExtra("pdus");

        byte[][] pduObjs = new byte[messages.length][];

 

        for (int i = 0; i < messages.length; i++)

        {

            pduObjs[i] = (byte[]) messages[i];

        }

        byte[][] pdus = new byte[pduObjs.length][];

        int pduCount = pdus.length;

        SmsMessage[] msgs = new SmsMessage[pduCount];

        for (int i = 0; i < pduCount; i++)

        {

            pdus[i] = pduObjs[i];

            msgs[i] = SmsMessage.createFromPdu(pdus[i]);

        }

        return msgs;

    }

 

}

作者:jason0539

微博:http://weibo.com/2553717707

博客:http://blog.csdn.net/jason0539(转载请说明出处)

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/121396.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab如何做正交多项式曲线拟合,matlab正交多项式拟合

    matlab如何做正交多项式曲线拟合,matlab正交多项式拟合在实验模态分析中用Matlab实现离散化正交多项式算法[C],马永列;陈章位;胡海清4.在实验模态分析中用Matlab实现离散化正交多项式算法[C],马永列……变换后的条件数上限表如下:拟合次数1=1cond2(A)2<9.93<50.34<435④在实际应用中还可以利用正交多项式求拟合多项式。一种方法是构造离散……..

    2025年5月24日
    2
  • UVA1455 – Kingdom(并查集 + 线段树)

    UVA1455 – Kingdom(并查集 + 线段树)

    2021年12月14日
    50
  • linux下安装ffmpeg_linux 当前时间

    linux下安装ffmpeg_linux 当前时间linuxffmpeg安装ffmpeg安装不会吧这都22年了还有人问ffmpeg安装第一步我们先去下载资源包这里是4.4版本wgethttp://www.ffmpeg.org/releases/ffmpeg-4.4.tar.gz第二步解压资源包tar-zxvfffmpeg-4.4.tar.gz第3步创建安装目录我是安装在##我是安装在/www/server/ffmpeg下面mkdirffmpeg第4步返回解压目录cdffmpeg-4.

    2022年9月12日
    2
  • MQTT(一)C#使用 MQTTnet 快速实现 MQTT 通信(文末有完整Demo下载)[通俗易懂]

    MQTT(一)C#使用 MQTTnet 快速实现 MQTT 通信(文末有完整Demo下载)[通俗易懂]目录MQTT(一)C#使用MQTTnet快速实现MQTT通信(文末有完整Demo下载)MQTT(二)在windows64位上安装Python环境MQTT(三)Python客户端+net客户端+net服务端简单通信MQTT(四)树莓派开机自动运行Python客户端MQTT(五)EMQ开源MQTT消息服务器1什么是MQTT?MQTT(MessageQue…

    2022年6月25日
    290
  • vue的双向绑定原理及实现_vue双向绑定指令

    vue的双向绑定原理及实现_vue双向绑定指令vue双向绑定原理及实现一、MVC模式二、MVVM模式三、双向绑定原理1、实现一个Observer2、实现一个Watcher3、实现一个Compile4、实现一个MVVM四、最后写一个html测试一下我们的功能一、MVC模式MVC模式以往的MVC模式是单向绑定,即Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新二、MVVM模式MVVM模式就是Model–View–ViewModel模式。它实现了View的变动,自动反映在ViewModel,反之亦然

    2022年10月10日
    2
  • 自动化渗透测试系统_自动化测试用例管理工具

    自动化渗透测试系统_自动化测试用例管理工具一.渗透测试“三板斧”1.信息搜集——全面了解系统网络信息:DNSIP端口服务器信息:操作系统版本服务中间件;版本WEB系统信息:使用技术部署系统数据库第三方软件:版本社工记录:个人邮件地址泄露账号密码历史网站信息2.漏洞利用——占领根据地web漏洞发现系统漏洞发现漏洞利用编写自动漏洞利用脚本放置隐蔽后门3.横向扩展——扩大成果,深度挖掘内网架构分析、攻陷信息中心和数据中心、突破认证服务器(AD域)、内网中间人攻击(获取单点信息)、多级多点后

    2022年8月12日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号