使用SMS
SMS表示短消息服务,但它通常称为文本消息。Android SDK支持发送和接收文本消息。首先介绍使用 SDK 发送SMS消息的各种方法。
1.发送SMS消息
要从应用程序发送文本消息,需要向描述文件中添加
<uses-permission android:name="android.permission.SEND_SMS"/>
权限,然后使用 android.telephony.SmsManager类,下面看一下我们的布局文件。
<?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"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Destination Address:"/>
<EditText
android:id="@+id/addrEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:phoneNumber="true"
android:text="9045551212"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Message"/>
<EditText
android:id="@+id/msgEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="hello sms"/>
</LinearLayout>
<Button
android:id="@+id/sendSmsBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Text Message"/>
</LinearLayout>
我们的Activity类 TelephonyDemo类
package xiaohang.zhimeng;
import android.app.Activity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class TelephoneDemo extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button sendBtn = (Button) findViewById(R.id.sendSmsBtn);
sendBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
EditText addrTxt = (EditText) TelephoneDemo.this
.findViewById(R.id.addrEditText);
EditText msgTxt = (EditText) TelephoneDemo.this
.findViewById(R.id.msgEditText);
try {
sendSmsMessage(addrTxt.getText().toString(), msgTxt
.getText().toString());
Toast.makeText(TelephoneDemo.this, "SMS Sent",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(TelephoneDemo.this, "Failed to send SMS",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private void sendSmsMessage(String address, String message) {
// 可以通过静态方法getDefault()方法来获得 一个SmsManager对象
SmsManager smsMgr = SmsManager.getDefault();
// 发送消息
smsMgr.sendTextMessage(address, null, message, null, null);
}
}
下面看一下运行效果 见下图
上面的示例演示了使用Android SDK 发送 SMS文本消息。首先看一下布局代码片段,可以看到,用户界面包含两个EditText字段:一个用于捕获SMS 接收者的目标地址 (电话号码),另一个用于保存文本消息。用户界面还有一个按钮用来发送消息。
该示例有一个 sendSmsMessage()方法。该方法使用SmsManager类的 sendTextMessage()方法来发送SMS消息。下面给出了 SmsManager.sendTextMessage()的签名:
sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent)
在这个示例中,仅填充了目标地址和文本消息参数。但是,可以自定义该方法,以便不使用默认的SMS中心(蜂窝塔网络上发送SMS消息的服务器地址)。也可以实现一个自定义方法,在发送消息或收到通知时调用挂起的 Intent。
总之,使用Android很容易实现SMS消息的发送。请注意,使用模拟器,SMS消息不会实际发送到目的地。但是,如果 sendTextMessage()方法未返回异常,就可以认为发送成功。我们使用了Toast类在UI中消息 发送成功的提示,以表明消息是否发送成功。
2.监视传入的SMS消息。
基本的思路是这样的 当设备 也就是我们的手机 收到一条短消息的时候 系统就会广播就会广播一个包含了
android.provider.Telephony.SMS_RECEIVED
动作的
Intent。我们只需要自己定义一个 广播接收器BroadcastReceiver 来过滤这个 Intent 然后 在 onReceive()方法里边实现自己的逻辑。
首先第一步是,请求接受它们的权限。将
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
权限添加到 描述文件中。接下来,需要实现一个监视程序来监听 SMS消息。就是我们自己定义的BroadcastReceiver 我们来看看我们自己的 定义的BroadcastReceiver 的代码
package xiaohang.zhimeng;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log;
public class MySMSMonitor extends BroadcastReceiver {
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction() != null
&& ACTION.compareToIgnoreCase(intent.getAction()) == 0) {
Object[] pduArray = (Object[]) intent.getExtras().get("pdus");
SmsMessage[] messages = new SmsMessage[pduArray.length];
for (int i = 0; i < pduArray.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]);
// 打印消息
System.out.println(messages[i].getDisplayMessageBody());
}
Log.d("MySMSonitor", "SMS Message Received.");
}
}
}
然后我们还需要在AndroidManifest.xml 文件中注册这个 接收器。
<receiver android:name="MySMSMonitor">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
onReceive()方法将拥有广播 Intent,它将在 bundle属性中包含了 SmsMessage。可以调用
intent.getExtras().get("pdus")
提取出 SmsMessage。此调用返回一个在PDU(Protocol Description Unit, 协议描述单元)模式中定义的对象数组,PDU是一种表示SMS消息的行业标准方式。 然后可以将PDU转换为 Android SmsMessage对象。从上面的代码我们可以看到 以对象数组的形式从 Intent 获得PDU。然后构造一个 SmsMessage 对象数组,其大小与PDU 数组的大小相等。最后,对PDU数组进行迭代,调用 SmsMessage.createFromPdu()来从PDU创建 SmsMessage对象。读取传入消息之后的操作必须迅速完成。尽管广播接收程序在系统中拥有较高的优先级,但它仍然必须快速完成相关操作,并且不能让用户看见。因此,你的选择是有限的。绝不要直接执行任何UI工作。可以发出通知,也可以启动服务来继续工作。onReceive()方法完成以后,onReceive()方法的承载进程随时可能被结束。可以启动服务,但不能绑定到服务,因为这样就意味进程需要存在一段时间,而这种情况是不可能发生的。
大家自己用 Emulator Control给模拟器发一条消息 试试就OK 了。
源码已上传