Android 采用广播接收者实现短信应用

广播接收者--BroadcastReceiver(实现短信应用)

原理:当系统收到短信时,会发出一个广播Intent,Intent的action名称为Android.provider.Telephony.SMS_RECEIVED,该Intent存放了系统收到的短信内容,我们使用名称“pdus”即可从Intent中获取到短信内容。



广播接收者--BroadcastReceiver

广播接收者(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,订阅方法有两种:

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

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>



web端(只需一个servlet):

public class ReceiveSMSServlet extends HttpServlet {


public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {


}



public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String content = request.getParameter("content");
String receivetime = request.getParameter("receivetime");
String senderNumber = request.getParameter("senderNumber");
System.out.println("短信内容: "+content);
System.out.println("接收时间: "+receivetime);
System.out.println("发送者号码: "+senderNumber);
}




}


Android端:(不需要Activity,只需一个类):



public class SMSBroadcastReceiver extends BroadcastReceiver {


@Override
public void onReceive(Context arg0, Intent intent) {
// TODO Auto-generated method stub
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());
/*将Date类型的时间转换为字符格式,并指定时间格式为2010-9-10 12:33*/
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/*将日期格式化*/
String receivetime = format.format(date);
/*取得短信*/
String senderNumber = message.getOriginatingAddress();
sendSMS(content,receivetime,senderNumber);//调用此方法将短信数据发送给WEB应用

//jia将此号码加入不想要的名单
/*if("15555215556".equals(senderNumber)) {
abortBroadcast();//终止广播*/
}
}
}


private boolean sendSMS(String content, String receivetime, String senderNumber) {
// TODO Auto-generated method stub
String path = "http://192.168.0.13:8080/ReceiveSMSData/ReceiveSMSServlet";
try {
String params = "content="+URLEncoder.encode(content, "UTF-8")+"&receivetime="+
receivetime+"&senderNumber="+senderNumber;
byte[] enity = params.getBytes();
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.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(enity.length));
conn.getOutputStream().write(enity);

if(conn.getResponseCode()==200) {
return true;
}
} catch (Exception ex) {
// TODO Auto-generated catch block
ex.printStackTrace();

return false;

}


}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.smslistener"
    android:versionCode="1"
    android:versionName="1.0" >


    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/><!-- 接收短信权限 -->
<uses-permission android:name="android.permission.INTERNET"/><!-- 访问网络权限 -->

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver android:name=".SMSBroadcastReceiver">
            <intent-filter android:priority="1000">
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>
        </receiver>

    </application>


</manifest>



广播被分为两种不同的类型:“普通广播”和”有序广播“。普通广播完全是异步的,可以在同一时刻(逻辑上)被所有接收者接收到,相对有序广播消息传递的效率比较高,但缺点是:接受者不能将处理结果传递给下一个接收者,并且无法终止广播(Intent)的广播;然而有序广播是按照接收者声明的优先级别,被接受者依次接受广播。优先级别在<intent-filter>的android:priority属性中声明,数值越大优先级别越高,取值范围:-1000到1000,优先级别也可以用IntentFilter对象的setPriority()进行设置。有序广播的接收者可以终止广播Intent的传播,广播Intent的传播一旦终止,后面的接收者就无法接收到广播。另外,有序广播的接收者可以将数据传递给下一个接收者。

Context.sentBroadcast()

发送的是普通广播,所有订阅者都有机会获得并进行处理。

Context.sentOrderedBroadcast()

发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,前面的接受者有权终止广播(BroadcastReceiver.abortBroadcast),如果广播被前面的接收者终止,后面的接收着就再也无法获取到广播。对于有序广播,前面的接收者可以将数据通过setResultExtras(Bundle)方法存放进结果对象,然后传递给下一个接收者,下一个接收者通过代码:

Bundle bundle = getResultExtras(true)可以获取上一个接收者存入在结果对象中的数据。

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值