引言
本文通过运行两个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、…
1、温故知新
广播接收者
:一个广播接收者是这样一个组件,它不做什么事,仅是接受广播公告并作出相应的反应。许多广播源自于系统代码,例如公告
时区的改变、电池电量低、已采取图片、用户改变了语言偏好。应用程序也可以发起广播,例如为了他其他程序知道某些数据已经下载到设备且他们可以使用这些数
据
BroadcastReceiver
类:是接受sendBroadcast()
发送的意图(intents)的基类。可以用Context.registerReceiver()
动态地注册这个类的实例,或者通过AndroidManifest.xml
中<receiver>标签静态发布。
广播接收者不显示一个用户界面。然而,它们启动一个活动去响应收到的信息,或者他们可能使用NotificationManager
去通知用户。通知可以使用多种方式获得用户的注意——闪烁的背光、振动设备、播放声音等等。典型的是放在一个持久的图标在状态栏,用户可以打开获取信息。
2、准备工作:SMS涉及的主要类SmsManager
实现SMS主要用到SmsManager
类,该类继承自java.lang.Object
类,下面我们介绍一下该类的主要成员。
公有方法:
-
ArrayList<
String
>
divideMessage
(String text)
当短信超过SMS消息的最大长度时,将短信分割为几块。
参数
:text
——初始的消息,不能为空
返回值
:有序的ArrayList<
String
>
,可以重新组合为初始的消息
-
static
SmsManager
getDefault
()
获取SmsManager的默认实例。
返回值
:SmsManager
的默认实例
-
void
SendDataMessage
(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异常。
-
void
sendMultipartTextMessage
(String
destinationAddress,
String
scAddress,
ArrayList<
String
>
parts,
ArrayList<
PendingIntent
>
sentIntents, ArrayList<
PendingIntent
>
deliverIntents)
发送一个基于SMS的多部分文本,调用者应用已经通过调用divideMessage
(String text)将消息分割成正确的大小。
参数
:
1)、destinationAddress
——消息的目标地址
2)、scAddress
——服务中心的地址or为空使用当前默认的SMSC
3)、parts
——有序的ArrayList<
String
>
,可以重新组合为初始的消息
4)、sentIntents
——跟SendDataMessage
方法中一样,只不过这里的是一组PendingIntent
5)、deliverIntents
——跟SendDataMessage
方法中一样,只不过这里的是一组PendingIntent
异常
:如果destinationAddress
或data
是空时,抛出IllegalArgumentException异常。
-
void
sendTextMessage
(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)
3、简单的SMS发送程序
1)、首先,编辑布局文件res/layout/main.xml
,达到我们想要的结果,界面如下:
图1、程序运行界面
对应的xml代码如下:
<?
xml version="1.0" encoding="utf-8"?>
<
LinearLayout
xmlns
:android
="http://schemas.android.com/apk/res/android"
android
:orientation
="vertical"
android
:layout_width
="fill_parent"
android
:layout_height
="fill_parent"
>
<
TextView
android
:layout_width
="fill_parent"
android
:layout_height
="wrap_content"
android
:text
="@string/txtPhoneNo"
/>
<!-- text's value define in res/values/strings.xml -->
<
EditText
android
:layout_width
="fill_parent"
android
:layout_height
="wrap_content"
android
:id
="@+id/edtPhoneNo"
/>
<
TextView
android
:layout_width
="fill_parent"
android
:layout_height
="wrap_content"
android
:text
="@string/txtContent"
/>
<
EditText
android
:layout_width
="fill_parent"
android
:layout_height
="wrap_content"
android
:minLines
="3"
android
:id
="@+id/edtContent"
/>
<
Button
android
:layout_width
="wrap_content"
android
:layout_height
="wrap_content"
android
:text
="@string/btnText"
android
:id
="@+id/btnSend"
/>
</
LinearLayout
>
相应的要在res/values/strings.xm
中添加上面定义的视图的text的值,如下:
<?
xml version="1.0" encoding="utf-8"?>
<
resources
>
<
string
name
="txtPhoneNo"
>
Please input phone NO:</
string
>
<
string
name
="txtContent"
>
Please input SMS/'s content:</
string
>
<
string
name
="btnText"
>
send!</
string
>
<
string
name
="app_name"
>
SMS</
string
>
</
resources
>
2)、做完这些准备工作之后,我么要开始编写代码实现简单的短信发送了。
通过第一步我们构建好界面之后,现在要在上面的基础上编写业务逻辑了。大致过程为:在java源文件中,获取用户在edtPhoneNo中输入的电
话号码,edtContent中输入要发送的内容;然后点击btnSend按钮发送短信,要达到这个目的我们要设置btnSend的
OnClickListener以达到当点击它触发发送短信的功能,而且要发送短信就要用到我们前面介绍的SmsManager
类提供的方法接口。
设置btnSend的OnClickListener的代码如下:
btnSend.setOnClickListener(new
View.OnClickListener() {
public
void
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();
}
});
发送短信的功能的代码如下:
private
void
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<String> 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,这样的话不能根据短信
发出之后的状态做相应的事情,如短信发送失败后的提醒、接收者成功接收后的回执……完整的流程源码如下:
TextMessage.java源文件全部代码
3)运行前,还要在清单文件AndroidManifest.xml中加入允许发送短信的权限:
<?xml version="1.0
" encoding="utf-8
"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android
"
package
="skynet.com.cnblogs.www
"
android:versionCode="1
"
android:versionName="1.0
">
<application android:icon="@drawable/icon
" android:label="@string/app_name
">
<activity android:name=".TextMessage
"
android:label="@string/app_name
">
<intent-filter>
<action android:name="android.intent.action.MAIN
" />
<category android:name="android.intent.category.LAUNCHER
" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.SEND_SMS
"/>
</manifest>
3.1、运行SMS程序给另一个android模拟器发短信
运行上面我们编写的TextMessage程序,另外在Windows的命令行下切换到tools目录下,并输入emulator –data smsReceiver,我的如下:
这样就会启动一个android模拟器,如下所示:(注意它的编号:5556,就是用这个编号与它通信的
)
图2、通过emulator启动一个android模拟器
通过我们TextMessage程序启动的android模拟器,编写短信:
图3、TextMessage程序个5556模拟器发短信
点击发送之后,通过命令行启动的5556号android模拟器会收到我们刚才发送的短信,如下所示:
图4、收到短信的提示
tips:
如果通过命令行的emulator启动android模拟器提示“NO DNS servers found!”,这时我们发的短信模拟器是收不到的。
-
在Windows下,如果电脑没有介入网络,即找不DNS服务器的话会出现这种情况!
-
在Mac下,如果提示这个警告的话,可以这样解决:检查你是否有/etc/resolv.conf
文件,如果没有的话,通过下面的命令行
ln -s /private/var/run/resolv.conf /etc/resolv.conf可以解决。
4、SMS增强(一)
上面我们实现了一个简单的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
public
void
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
public
void
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方法如下:
修改后的sendSMS方法完整代码
运行之后的,发送短信成功的话就可以看到如下界面:
图5、增强SMS(一)
5、SMS增强(二)
下面这个增强是使SMS能够发送二进制数据。要发送数据要使用SmsManager类的sendDataMessage方法,跟sendTextMessage方法类似,只不过该方法多了一个目标端口的参数,构建该SMS的过程跟前面的类似这里就不在累述。
转帖地址:http://www.cnblogs.com/skynet/archive/2010/06/14/1758284.html
分享到:
相关推荐
Android 开发之旅:短信的收发及在android模拟器之间实践(一) 14 Android 开发之旅:短信的收发及在android模拟器之间实践(二) 15 Android开发之旅 Intents和Intent Filters(理论部分) 16 Android开发之旅 ...
Android 短信收发流程是 Android 系统源码中一个非常重要的模块,它负责处理短信的发送和接收过程。在这个流程中,涉及到多个组件和类别,包括 ComposeMessageActivity、WorkingMessage、TelephonyManager 等。下面...
在Android平台上,短信收发是一项基础且重要的功能。本文将深入探讨如何在Android应用中实现这一功能,特别关注Broadcast(广播)的使用,这是Android四大组件之一,它在处理系统事件和应用程序间通信中起到关键作用...
1. **Android SMS API**:Android SDK提供了一系列API,允许开发者直接操作短信功能。主要涉及到`SmsManager`类,它是发送短信的主要接口。例如,我们可以使用`SmsManager.getDefault().sendTextMessage()`方法发送...
在Android系统中,短信的收发是通过系统的SMS服务来实现的,这涉及到Android的底层通信框架和消息处理机制。本文将深入解析Android源码,探讨短信收发工具的实现,以及如何通过编程接口(API)来控制这个过程。 ...
在Android系统中,Java语言是开发应用程序的主要工具之一,其中包括短信收发功能。这个基于Android的Java短信收发程序允许用户不仅发送短信,还能接收到短信通知,这在很多应用场景中都非常实用,如验证码发送、紧急...
在Android平台上,短信收发是常见的功能之一,尤其对于初学者来说,理解并实现这个功能是掌握Android开发的重要步骤。本教程将详细讲解如何利用Android SDK来创建一个短信收发工具,包括界面设计和功能实现。 一、...
总之,"手机短信开发之联通短信网关模拟器"提供了一套全面的工具,帮助开发者在短信服务开发过程中节省时间和精力,提高效率。通过深入理解和熟练运用SGIP协议、SGIP网关以及相关的API,开发者可以构建出稳定可靠的...
在Android平台上,开发一个收发短信的程序是一个基础但实用的功能。这涉及到Android系统的权限管理、意图(Intent)的使用、BroadcastReceiver以及SmsManager类的应用。以下是对这个开发例程的详细解析: 首先,要...
本文将深入探讨一款名为"Android SMSPopup"的应用,它是一款专为Android设计的短信收发程序,旨在提供更便捷、个性化的短信管理体验。 首先,"SMSPopup"这一名称本身就揭示了其核心功能。"Popup"意为弹出窗口,意味...
在Android平台上,短信服务是移动应用开发中的一个重要组成部分,它允许用户发送和接收文本消息。在本主题中,我们将深入探讨如何在Android应用中实现多媒体短信(MMS)的发送和接收功能,以及相关的源码解析。 ...
每一部手机都具有短信接收和发送功能,下面我们通过代码来实现接收和发送短信功能。 一、接收短信 1、创建内部广播接收器类,接收系统发出的短信广播 2、从获得的内容中解析出短信发送者和短信内容 3、在...
在深入探讨Android手机短信的收发之前,我们先来了解一下与之相关的几个核心概念:广播接收者(BroadcastReceiver)及其工作原理。 ##### 1. 广播接收者(BroadcastReceiver) 广播接收者是一种特殊的Android组件...
在Android Studio实现MQTT对主题的订阅和数据的收发,以及将数据封装成对象传回MainActivity,方便进行数据处理,其操作信息在TextView中展示相关的数据。对相关的数据一目了然,同时,在页面中为物联网的开发提供了...
在Android开发中,Socket通信是实现设备间数据传输的重要手段,尤其在构建网络服务和进行设备间的实时交互时。本文将深入探讨如何在Android平台上创建一个Socket客户端,以及如何通过TCP协议进行数据的发送和接收。 ...
这个“SMS.rar”压缩包文件似乎包含了一个自定义开发的Android短信收发系统,适用于特定的办公或业务需求。下面,我们将深入探讨Android SMS相关的技术知识,以及如何构建这样的系统。 一、Android SMS API ...
在这个项目中,我们将深入Android开发的核心,学习如何构建一个具有吸引力且用户友好的短信应用。 首先,我们要关注的是UI/UX设计。在Android开发中,Material Design是谷歌推荐的设计语言,它提供了丰富的组件和...
根据给定文件中的内容,本文将详细介绍如何在Android环境中创建并实现一个简单的发送短信的应用程序。本例中,我们将创建一个名为`SendMessage`的工程项目,并指定其构建目标为Android 2.1,即API Level 7。 1. **...