在 Android 中发送 SMS 并接收反馈






4.74/5 (21投票s)
本文介绍了如何在 Android 中发送 SMS 短信,并接收已发送和已送达的反馈。
引言
使用 Android 编程,您可以将 SMS 功能集成到您自己的 Android 应用程序中。 这允许您创建可以从您的 Android 设备发送和接收 SMS 消息的 Android 应用程序。 在本文中,我将解释如何以编程方式发送 SMS 消息。 此外,我还将展示如何监控 SMS 消息的状态,例如,消息何时发送以及何时传递给接收者。
在这里,我假设读者具有使用 Eclipse IDE 创建 Android 应用程序的基本知识。
背景
Android 要求在 *AndroidManifest.xml* 文件中指定应用程序所需的权限。 这确保在安装应用程序时,用户知道它需要哪些权限。 此外,它还为用户提供了一个选项,可以决定是否安装 SMS 应用程序,因为这样的应用程序需要用户承担发送 SMS 消息的费用。
Using the Code
需要在 *AndroidManifest.xml* 文件中添加以下行,以允许应用程序发送 SMS 消息
<uses-permission android:name="android.permission.SEND_SMS"/>
以下是 *AndroidManifest.xml* 文件的完整代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.azim"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.SEND_SMS"/>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".SMSSenderActivity"
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>
</manifest>
SMS 应用程序的用户界面包含两个 EditText
字段,分别用于接受消息文本和电话号码,以及一个 Button
控件用于发送消息。 以下是 *main.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/hello"
/>
<TextView android:text="Enter SMS Text: " android:id="@+id/textView1"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<EditText android:layout_width="match_parent" android:layout_height="wrap_content"
android:id="@+id/editText1"></EditText>
<TextView android:text="Enter Phone Number: " android:id="@+id/textView2"
android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
<EditText android:layout_width="match_parent" android:layout_height="wrap_content"
android:id="@+id/editText2"></EditText>
<Button android:text="Send SMS" android:id="@+id/button1" android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
</LinearLayout>
SmsManager
类用于以编程方式发送 SMS 消息。 该类通过使用 static getDefault()
方法实例化,如下所示
SmsManager sms=SmsManager.getDefault();
SmsManager
类的 sendTextMessage()
方法用于发送文本消息,如下所示
sms.sendTextMessage(phone, null, message, piSent, piDelivered);
sendTextMessage()
方法接受五个参数,如下所示
phone
- 收件人的电话号码address
- 服务中心地址(默认为 null)message
- 要发送的 SMS 消息piSent
- 消息发送时要调用的 PendingIntentpiDelivered
- 消息传递给收件人时要调用的 PendingIntent
在调用 sendTextMessage()
方法之前,piSent
和 piDelivered
PendingIntent 创建如下
PendingIntent piSent=PendingIntent.getBroadcast(this, 0, new Intent("SMS_SENT"), 0);
PendingIntent piDelivered=PendingIntent.getBroadcast(this, 0, new Intent("SMS_DELIVERED"), 0);
PendingIntent
对象 piSent
用于通知发送者消息已发送,PendingIntent
对象 piDelivered
用于通知发送者消息已传递给接收者,当接收者实际收到消息时。
**注意**:*piDelivered PendingIntent
不会在 Android 模拟器中触发。 您必须在真实的设备上测试该应用程序才能查看它。 但是,piSent PendingIntent
在模拟器和真实设备上都可以工作。*
在 *onResume()
* 方法中创建两个 *BroadcastReceiver
* 对象,smsSentReceiver
和 smsDeliveredReceiver
。 这些使用 registerReceiver()
方法注册,如下所示
registerReceiver(smsSentReceiver, new IntentFilter("SMS_SENT"));
registerReceiver(smsDeliveredReceiver, new IntentFilter("SMS_DELIVERED"));
在每个 BroadcastReceiver
对象内部,onReceive()
方法被重写以使用 getResultCode()
方法检查结果代码并显示相应的消息。
两个 BroadcastReceiver
对象在 onPause()
方法中取消注册,如下所示
unregisterReceiver(smsSentReceiver);
unregisterReceiver(smsDeliveredReceiver);
以下是应用程序的完整源代码
package com.azim;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class SMSSenderActivity extends Activity implements View.OnClickListener {
/** Called when the activity is first created. */
EditText txtMessage,txtPhone;
Button btnSend;
BroadcastReceiver smsSentReceiver, smsDeliveredReceiver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtMessage=(EditText)findViewById(R.id.editText1);
txtPhone=(EditText)findViewById(R.id.editText2);
btnSend=(Button)findViewById(R.id.button1);
btnSend.setOnClickListener(this);
}
public void onClick(View arg0) {
// TODO Auto-generated method stub
SmsManager sms=SmsManager.getDefault();
String phone=txtPhone.getText().toString();
String message=txtMessage.getText().toString();
PendingIntent piSent=PendingIntent.getBroadcast(this, 0, new Intent("SMS_SENT"), 0);
PendingIntent piDelivered=PendingIntent.getBroadcast(this, 0, new Intent("SMS_DELIVERED"), 0);
sms.sendTextMessage(phone, null, message, piSent, piDelivered);
}
public void onResume() {
super.onResume();
smsSentReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS has been sent", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(getBaseContext(), "Generic Failure", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(), "No Service", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio Off", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
smsDeliveredReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
switch(getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS Delivered", Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show();
break;
}
}
};
registerReceiver(smsSentReceiver, new IntentFilter("SMS_SENT"));
registerReceiver(smsDeliveredReceiver, new IntentFilter("SMS_DELIVERED"));
}
public void onPause() {
super.onPause();
unregisterReceiver(smsSentReceiver);
unregisterReceiver(smsDeliveredReceiver);
}
}
在 Android 模拟器上执行该应用程序。 这将启动默认的 AVD。 使用 Android SDK 和 AVD Manager 选项,启动另一个 AVD,如下所示
在第一个模拟器 (5554) 上,键入消息和第二个模拟器 (5556) 的号码,然后单击“发送 SMS”按钮。 这将在第二个模拟器上显示消息,并在第一个模拟器上显示已发送通知。
关注点
以编程方式发送 SMS 的优点是,您可以通过应用程序发送动态生成的消息。 此外,您不需要真实的设备来测试此功能。 您可以在将应用程序传输到真实设备之前,在模拟器上对其进行测试。