短信的收发及在android模拟器之间实践
2011年12月28日
[/b]
本文通过运行两个Android模拟器,介绍在Android中如何实现短信服务(SMS,short message service)的功能。通过这个例子,我想带给大家的是:更加熟悉之前介绍过的Android应用程序的概念及技术细节,且通过实例调度大家的兴趣。我 之所以选择SMS为例子,主要原因是SMS已经非常成熟了,从中可以发掘更多的信息和技术细节,而且我相信大部分人发短信比打电话多。
本文的主要内容如下: 1、温故知新
2、准备工作:SMS涉及的主要类SmsManager
3、简单的SMS发送程序
3.1、运行SMS程序给另一个android模拟器发短
4、SMS增强(一)
5、SMS增强(二)
6、SMS接收程序(下篇)
7、emulator工具(下篇)
8、…
[b]广播接收者:一个广播接收者是这样一个组件,它不做什么事,仅是接受广播公告并作出相应的反应。许多广播源自于系统代码,例如公告 时区的改变、电池电量低、已采取图片、用户改变了语言偏好。应用程序也可以发起广播,例如为了他其他程序知道某些数据已经下载到设备且他们可以使用这些数据
BroadcastReceiver类:是接受sendBroadcast()发送的意图(intents)的基类。可以用Context.registerReceiver()动态地注册这个类的实例,或者通过AndroidManifest.xml中标签静态发布。 广播接收者不显示一个用户界面。然而,它们启动一个活动去响应收到的信息,或者他们可能使用NotificationManager去通知用户。通知可以使用多种方式获得用户的注意――闪烁的背光、振动设备、播放声音等等。典型的是放在一个持久的图标在状态栏,用户可以打开获取信息。 [/b]实现SMS主要用到SmsManager类,该类继承自java.lang.Object类,下面我们介绍一下该类的主要成员。
[b]公有方法: ArrayListdivideMessage(String text)
当短信超过SMS消息的最大长度时,将短信分割为几块。
参数:text――初始的消息,不能为空
返回值:有序的ArrayList,可以重新组合为初始的消息
staticSmsManagergetDefault()
获取SmsManager的默认实例。
返回值:SmsManager的默认实例
voidSendDataMessage(String destinationAddress,String scAddress,short destinationPort,byte[] data,PendingIntent sentIntent, PendingIntent deliveryIntent)
发送一个基于SMS的数据到指定的应用程序端口。
参数:
1)、destinationAddress――消息的目标地址
2)、scAddress――服务中心的地址or为空使用当前默认的SMSC 3)destinationPort――消息的目标端口号
4)、data――消息的主体,即消息要发送的数据
5)、sentIntent―― 如果不为空,当消息成功发送或失败这个PendingIntent就广播。结果代码是Activity.RESULT_OK表示成功,或 RESULT_ERROR_GENERIC_FAILURE、RESULT_ERROR_RADIO_OFF、 RESULT_ERROR_NULL_PDU之一表示错误。对应RESULT_ERROR_GENERIC_FAILURE,sentIntent可能包括额外的“错误代码”包含一个无线电广播技术特定的值,通常只在修复故障时有用。
每一个基于SMS的应用程序控制检测sentIntent。如果sentIntent是空,调用者将检测所有未知的应用程序,这将导致在检测的时候发送较小数量的SMS。
6)、deliveryIntent――如果不为空,当消息成功传送到接收者这个PendingIntent就广播。
异常:如果destinationAddress或data是空时,抛出IllegalArgumentException异常。
voidsendMultipartTextMessage(String destinationAddress,String scAddress, ArrayList parts, ArrayList sentIntents, ArrayList deliverIntents)
发送一个基于SMS的多部分文本,调用者应用已经通过调用divideMessage(String text)将消息分割成正确的大小。
参数:
1)、destinationAddress――消息的目标地址
2)、scAddress――服务中心的地址or为空使用当前默认的SMSC
3)、parts――有序的ArrayList,可以重新组合为初始的消息
4)、sentIntents――跟SendDataMessage方法中一样,只不过这里的是一组PendingIntent
5)、deliverIntents――跟SendDataMessage方法中一样,只不过这里的是一组PendingIntent
异常:如果destinationAddress或data是空时,抛出IllegalArgumentException异常。
voidsendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)
发送一个基于SMS的文本。参数的意义和异常前面的已存在的一样,不再累述。
常量: public static final int RESULT_ERROR_GENERIC_FAILURE
表示普通错误,值为1(0x00000001)
public static final int RESULT_ERROR_NO_SERVICE
表示服务当前不可用,值为4 (0x00000004)
public static final int RESULT_ERROR_NULL_PDU
表示没有提供pdu,值为3 (0x00000003)
public static final int RESULT_ERROR_RADIO_OFF
表示无线广播被明确地关闭,值为2 (0x00000002)
public static final int STATUS_ON_ICC_FREE
表示自由空间,值为0 (0x00000000)
public static final int STATUS_ON_ICC_READ
表示接收且已读,值为1 (0x00000001)
public static final int STATUS_ON_ICC_SENT
表示存储且已发送,值为5 (0x00000005)
public static final int STATUS_ON_ICC_UNREAD
表示接收但未读,值为3 (0x00000003)
public static final int STATUS_ON_ICC_UNSENT
表示存储但为发送,值为7 (0x00000007)
[/b]1)、首先,编辑布局文件res/layout/main.xml,达到我们想要的结果,界面如下:
图1、程序运行界面
对应的xml代码如下:
相应的要在res/values/strings.xm中添加上面定义的视图的text的值,如下: Please input phone NO:Please input SMS\'s content:send!SMS
2)、做完这些准备工作之后,我么要开始编写代码实现简单的短信发送了。
通过第一步我们构建好界面之后,现在要在上面的基础上编写业务逻辑了。大致过程为:在java源文件中,获取用户在edtPhoneNo中输入的电 话号码,edtContent中输入要发送的内容;然后点击btnSend按钮发送短信,要达到这个目的我们要设置btnSend的 OnClickListener以达到当点击它触发发送短信的功能,而且要发送短信就要用到我们前面介绍的SmsManager类提供的方法接口。
设置btnSend的OnClickListener的代码如下: btnSend.setOnClickListener(new View.OnClickListener() { publicvoid onClick(View v) { String phoneNo = edtPhoneNo.getText().toString(); String message = edtContent.getText().toString(); if (phoneNo.length() > 0 && message.length() > 0){ //call sendSMS to send message to phoneNo sendSMS(phoneNo, message); } else Toast.makeText(getBaseContext(), "Please enter both phone number and message.", Toast.LENGTH_SHORT).show(); } });
发送短信的功能的代码如下: privatevoid sendSMS(String phoneNumber, String message) { // ---sends an SMS message to another device--- SmsManager sms = SmsManager.getDefault(); PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(this,TextMessage.class), 0); //if message's length more than 70 ,//then call divideMessage to dive message into several part //and call sendTextMessage()//else direct call sendTextMessage()if (message.length() > 70) { ArrayList msgs = sms.divideMessage(message); for (String msg : msgs) { sms.sendTextMessage(phoneNumber, null, msg, pi, null); } } else { sms.sendTextMessage(phoneNumber, null, message, pi, null); } Toast.makeText(TextMessage.this, "短信发送完成", Toast.LENGTH_LONG).show(); }
如果你已经看了第2节介绍的SmsManager类的介绍,代码应该 很好理解。在这里要说明的是,sendTextMessage方法中的第4个和第5个参数PendingIntent设为null,这样的话不能根据短信 发出之后的状态做相应的事情,如短信发送失败后的提醒、接收者成功接收后的回执……完整的流程源码如下: 3)运行前,还要在清单文件AndroidManifest.xml中加入允许发送短信的权限: [/b]运行上面我们编写的TextMessage程序,另外在Windows的命令行下切换到tools目录下,并输入emulator data smsReceiver,我的如下:
这样就会启动一个android模拟器,如下所示:([b]注意它的编号:5556,就是用这个编号与它通信的)
图2、通过emulator启动一个android模拟器
通过我们TextMessage程序启动的android模拟器,编写短信:
图3、TextMessage程序个5556模拟器发短信
点击发送之后,通过命令行启动的5556号android模拟器会收到我们刚才发送的短信,如下所示:
图4、收到短信的提示 [/b]如果通过命令行的emulator启动android模拟器提示“NO DNS servers found!”,这时我们发的短信模拟器是收不到的。 在Windows下,如果电脑没有介入网络,即找不DNS服务器的话会出现这种情况!
在Mac下,如果提示这个警告的话,可以这样解决:检查你是否有/etc/resolv.conf文件,如果没有的话,通过下面的命令行
ln -s /private/var/run/resolv.conf /etc/resolv.conf可以解决。
[b] 上面我们实现了一个简单的SMS程序,下面我们要对它进行增强!你肯定已经注意到了,我们上面的SMS程序的sendTextMessage方法中的第4个和第5个参数PendingIntent设为null,即sentIntent和deliveryIntent。
第4个参数-sendIntent,当消息成功发送或发送失败都将被触发。广播接收者的结果码,Activity.RESULT_OK表示成功,或 RESULT_ERROR_GENERIC_FAILURE、RESULT_ERROR_RADIO_OFF、 RESULT_ERROR_NULL_PDU之一表示错误。对应RESULT_ERROR_GENERIC_FAILURE,sentIntent可能包括额外的“错误代码”包含一个无线电广播技术特定的值,通常只在修复故障时有用。第5个参数-deliveryIntent,仅当目标接收到你的SMS消息才触发。
为了跟踪发出的短信的状态,实现和注册Broadcast Receiver(广播接收者)监听传递给sendTextMessage方法的参数Pending Intents。下面我们就实现和注册这个广播接收者: String SENT_SMS_ACTION="SENT_SMS_ACTION"; String DELIVERED_SMS_ACTION="DELIVERED_SMS_ACTION"; //create the sentIntent parameter Intent sentIntent=new Intent(SENT_SMS_ACTION); PendingIntent sentPI=PendingIntent.getBroadcast( this, 0, sentIntent, 0); //create the deilverIntent parameter Intent deliverIntent=new Intent(DELIVERED_SMS_ACTION); PendingIntent deliverPI=PendingIntent.getBroadcast( this, 0, deliverIntent, 0); //register the Broadcast Receivers registerReceiver(new BroadcastReceiver(){ @Override publicvoid onReceive(Context _context,Intent _intent) { switch(getResultCode()){ case Activity.RESULT_OK: Toast.makeText(getBaseContext(), "SMS sent success actions", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_GENERIC_FAILURE: Toast.makeText(getBaseContext(), "SMS generic failure actions", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_RADIO_OFF: Toast.makeText(getBaseContext(), "SMS radio off failure actions", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_NULL_PDU: Toast.makeText(getBaseContext(), "SMS null PDU failure actions", Toast.LENGTH_SHORT).show(); break; } } }, new IntentFilter(SENT_SMS_ACTION)); registerReceiver(new BroadcastReceiver(){ @Override publicvoid onReceive(Context _context,Intent _intent) { Toast.makeText(getBaseContext(), "SMS delivered actions", Toast.LENGTH_SHORT).show(); } }, new IntentFilter(DELIVERED_SMS_ACTION));
在基本完成了要做的工作,接下来要做的就是将sendTextMessage的第4个和第5个参数改为sentPI、deliverPI,这样工作基本完成,修改后的sendSMS方法如下: 运行之后的,发送短信成功的话就可以看到如下界面:
图5、增强SMS(一) [b][/b] 下面这个增强是使SMS能够发送二进制数据。要发送数据要使用SmsManager类的sendDataMessage方法,跟sendTextMessage方法类似,只不过该方法多了一个目标端口的参数,构建该SMS的过程跟前面的类似这里就不在累述。
发表评论
-
2012年高考备考(105)武汉市武昌区高三元月调研测试
2012-01-20 11:17 5692012年高考备考(105)武汉市武昌区高三元月调研测试 1 ... -
1月1周低卡饮食 吃出好身材
2012-01-20 11:16 6101月1周低卡饮食 吃出好身材 12小时前 不想节食 ... -
STC ISP
2012-01-20 11:16 970STC ISP 2012年01月12日 ... -
【转】 c51错误2
2012-01-19 16:05 2582【转】 c51错误2 2011年08 ... -
如何更改群集服务帐户密码
2012-01-19 16:04 917如何更改群集服务帐户 ... -
PHP5的异常处理机制(二)
2012-01-19 16:04 645PHP5的异常处理机制(二) 2011年12月15日 根 ... -
PHP 5.0异常处理机制深度探索
2012-01-19 16:04 543PHP 5.0异常处理机制深度探索 2011年11月19日 ... -
铁路企业职工再加薪 一线员工每月至少涨620元
2012-01-17 05:56 586铁路企业职工再加薪 一 ... -
泰国副总理:已获本国军人杀害中国船员充分证据
2012-01-17 05:56 515泰国副总理:已获本国军人杀害中国船员充分证据 2012年01 ... -
大范围雨雪天气10日起侵袭南方 或对春运不利
2012-01-17 05:56 583大范围雨雪天气10日起 ... -
广州8所机关幼儿园获补7524万 比去年增1770万
2012-01-17 05:56 474广州8所机关幼儿园获补7524万 比去年增1770万 201 ... -
Black Duck - Guan Yin Bodhisattva in Mind (2006)
2012-01-17 05:56 675Black Duck - Guan Yin Bodhisatt ... -
皇帝木--识鉴金丝楠木
2012-01-16 04:43 539皇帝木--识鉴金丝楠木 ... -
第四章 中国传统文化的发展历程
2012-01-16 04:43 756第四章 中国传统文化的发展历程 2012年01月04日 ... -
孟氏家族家规
2012-01-16 04:43 1547孟氏家族家规 2012年01月04日 孟氏家族家规(转载 ... -
中国哲学史(先秦部分)-------简答
2012-01-16 04:43 504中国哲学史(先秦部分)-------简答 2012年01月0 ...
相关推荐
Android 开发之旅:短信的收发及在android模拟器之间实践(一) 14 Android 开发之旅:短信的收发及在android模拟器之间实践(二) 15 Android开发之旅 Intents和Intent Filters(理论部分) 16 Android开发之旅 ...
• Android 开发之旅:短信的收发及在android模拟器之间实践(一) • Android 开发之旅:短信的收发及在android模拟器之间实践(二) • Android开发之旅: Intents和Intent Filters(理论部分)
• Android 开发之旅:短信的收发及在android模拟器之间实践(一) • Android 开发之旅:短信的收发及在android模拟器之间实践(二) • Android开发之旅: Intents和Intent Filters(理论部分)
Android系统源码短信模块,短信收发流程分析,从app层到framework层。
本项目是Android的短信收发项目实战,主要功能是短信的发送和接受,主要练习的是Android的四大组件之Broadcast广播i的使用和学习
如何实现短信的接收和发送,了解短信的收发机制
本代码可以实现两个模拟器之间的短信接发,并附有设计文档,希望能帮到各位。
android手机短信的收发 android手机短信的收发
Android多媒体应用——短信收发源码
本工具包包含中国移动、中国联通、中国电信、中国网通及短信中心短信网关模拟器及用于测试用途的手机终端模拟器. 二、功能介绍 中国移动CMPP模拟器 概述:基于CMPP v3.0 v2.0协议开发的,具有方便易用图形化的...
Android SMS短消息服务系统,自己开发的Android短信收发系统,可以用于办公等专项业务。
一个运行在android上的短信收发程序
一个很好的短信收发测试工具,也可以用于企业短信收发。
AT命令操作GSM短信猫收发短信,支持长短信收发,收长短信自动合并成一条短信。
收发短信。 private String getSimpleDateFormat(long long_date) { /*时锟斤拷锟绞阶拷锟轿�yyyy-MM-dd HH:mm:ss"*/ SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); Date d ...
短信收发包 SMSLib
android短信收发流流程
基于Android手机系统的java短信收发程序,本程序提供发送短信功能,并提醒短信接收。
android开发实例,可以接收和发送短信,有一个还可以的界面设计,适用于初级android开发者学习
这是个模拟短信收发系统,内嵌简易电话本功能,是第四届中兴捧月杯中里“信风”的作品