简介:在Android开发中,实现短信发送功能常依赖于 SmsManager 类和 PendingIntent 类。本文深入解析了如何运用这两个类来构建一个能够发送短信并监控发送状态的应用程序。通过实例代码展示如何发送短信以及如何通过广播接收器获取短信发送与送达状态的通知。文章还强调了用户界面设计、异常处理和权限管理在开发过程中的重要性。
1. Android短信发送实现
实现Android平台上的短信发送功能是一项基础而又重要的任务。在这一章节中,我们将探索短信发送功能的实现原理、所涉及到的关键API,以及如何在应用程序中有效地集成这一功能。我们将从整体上概述Android短信发送流程,并解释不同组件之间的交互方式,为接下来的章节内容打下坚实的基础。
短信发送功能的实现涉及几个核心步骤:请求发送短信的权限、创建并发送短信、以及跟踪短信的发送状态。我们会通过示例代码和具体的编程实践来深入理解这些步骤,确保开发者能够灵活地在Android应用中实现这一功能。
在本章的最后,你将掌握如何使用Android SDK提供的工具和类,如SmsManager和PendingIntent,来构建一个稳定可靠的短信发送系统。同时,你也将了解如何在AndroidManifest.xml中声明必要的权限,并处理好程序稳定性和易用性的考量,以确保应用在各种情况下都能可靠运行,提供流畅的用户体验。
2. SmsManager类应用示例
2.1 SmsManager类基础使用
2.1.1 SmsManager类概述
SmsManager 是Android SDK中用于管理短信发送的类。它提供了各种发送短信的方法,包括普通短信和分段短信的发送。这一类是Android 2.2(API level 8)及以上版本所提供的API的一部分。 SmsManager 类主要负责将短信内容传递到电信运营商的短信网关,但不包括短信发送的状态报告。
SmsManager 类提供的方法可以让我们将短信分为若干段,并在接收端按顺序重组,这对于超出70个字符的短信内容尤其重要,因为一条短信的最大长度是160个字符。如果发送的短信超过这个长度,系统会自动分割成多个部分,并且按照正确的顺序组合。 SmsManager 还允许我们发送带有状态报告的短信,这样我们可以确保短信已经被成功送达。
2.1.2 发送短信的基本方法
要发送短信,我们首先需要获取 SmsManager 实例,然后使用它的 sendTextMessage 方法。以下是发送短信的基本代码示例:
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNumber, null, message, null, null);
这里的 phoneNumber 是接收短信的手机号码, message 是要发送的短信内容,最后两个参数用于接收消息发送和送达的状态报告,可以为null,如果需要状态报告,则必须添加相应的PendingIntent。
2.2 SmsManager类进阶技巧
2.2.1 分段发送短信
当短信内容超过160个字符时,必须将其分割成多个部分,以确保它们可以被正确发送和接收。 SmsManager 类提供了 divideMessage 方法来帮助我们分割短信内容,然后我们可以通过 sendMultipartTextMessage 方法发送分割后的多个短信段:
SmsManager smsManager = SmsManager.getDefault();
List<String> messageParts = smsManager.divideMessage(message);
smsManager.sendMultipartTextMessage(phoneNumber, null, messageParts, null, null);
2.2.2 发送带有状态报告的短信
如果你希望得到短信是否成功送达的反馈,可以通过注册状态报告来实现。状态报告是一个包含发送和接收状态信息的 SmsMessage 对象。在发送短信时,可以通过设置PendingIntent来接收发送状态的回调:
SmsManager smsManager = SmsManager.getDefault();
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent("SMS_SENT"), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent("SMS_DELIVERED"), 0);
smsManager.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
这里的 SMS_SENT 和 SMS_DELIVERED 是广播接收器将接收的动作,你需要在广播接收器中处理这两个动作。发送动作会立即返回,而送达动作则会在短信成功送达或失败时触发。
章节小结
本章节介绍了 SmsManager 类在短信发送中的基础和进阶应用。首先,通过 sendTextMessage 方法我们能够发送基本的短信。随后,借助 divideMessage 和 sendMultipartTextMessage 方法,实现了对超长短信的自动分割和分段发送。为了增强应用的交互性和用户体验,我们还学习了如何通过设置PendingIntent来发送带有发送和送达状态报告的短信,以提供反馈。
在实际应用中,利用这些 SmsManager 类的方法,开发者可以创建出符合业务需求的短信功能模块。接下来的章节,我们将深入学习如何使用 PendingIntent 类来实现更多短信相关的高级功能。
3. PendingIntent类应用示例
3.1 PendingIntent类概念解析
3.1.1 PendingIntent的作用和特性
PendingIntent 是 Android 中的一个类,用于向其他应用组件(如 Activity , Service 或 BroadcastReceiver )传递一个对未来某个时间点执行操作的意图。它主要用于实现跨应用的事件通知和处理。例如,在短信应用中,你可能需要在短信发送出去之后收到一个通知,这时就可以使用 PendingIntent 来实现。
PendingIntent 的核心特性包括: - 时间延迟 :它描述的是一个在未来某个时间点应该被完成的操作。 - 数据封装 :通过 Intent 封装了目标组件需要的数据。 - 跨应用性 :可以用于在不同应用之间启动一个组件。
3.1.2 创建和使用PendingIntent实例
创建 PendingIntent 通常需要以下步骤: 1. 创建一个 Intent 对象,指定要启动的目标组件和附加数据。 2. 使用 Intent 对象构造 PendingIntent 对象,根据目标组件的不同,选择合适的方法。
这里以 Activity 为例,展示如何创建一个 PendingIntent :
Intent intent = new Intent(this, TargetActivity.class);
intent.putExtra("key", "value"); // 传递数据
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
上述代码创建了一个 PendingIntent ,其中 FLAG_UPDATE_CURRENT 表示如果之前的 PendingIntent 已经存在,则更新它。
3.2 PendingIntent在短信功能中的应用
3.2.1 利用PendingIntent处理短信送达
当发送短信时,可以通过 SmsManager 类的 sendTextMessage 方法发送短信,并使用 PendingIntent 来接收短信送达的报告:
Intent deliveryIntent = new Intent(Delivery_INTENT_ACTION);
PendingIntent deliveryPendingIntent = PendingIntent.getBroadcast(context, 0, deliveryIntent, 0);
smsManager.sendTextMessage(phoneNumber, null, message, deliveryPendingIntent, null);
3.2.2 如何在应用中设置PendingIntent
在应用中设置 PendingIntent 的具体步骤如下:
- 创建一个
BroadcastReceiver,用于接收短信送达的状态。 - 在
BroadcastReceiver中使用Intent传递短信的状态信息。 - 使用
PendingIntent.getBroadcast方法创建PendingIntent,并将其作为参数传递给sendTextMessage方法。
下面是一个简单的 BroadcastReceiver 示例:
public class DeliveryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
switch (getResultCode()) {
case Activity.RESULT_OK:
// 短信成功送达
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
// 通用错误
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
// 没有服务
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
// PDU为null
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
// 无线电关闭
break;
}
}
}
然后,在 AndroidManifest.xml 中注册这个 BroadcastReceiver ,并配置相应的 intent-filter :
<receiver android:name=".DeliveryReceiver">
<intent-filter>
<action android:name="com.example.SMS_DELIVERY_ACTION" />
</intent-filter>
</receiver>
以上代码创建了一个 BroadcastReceiver ,用于接收短信送达状态,并在 onReceive 方法中处理短信送达的成功或失败。
请注意,对于真实的环境,你应当根据实际业务需求,为 PendingIntent 设置合适的标志位以确保应用行为的正确性。对于更深层次的应用场景, PendingIntent 的功能非常强大,可用于构建复杂的事件处理逻辑和跨应用通知。
4. 发送和送达状态监控
4.1 短信发送状态监听
4.1.1 注册发送状态监听器
在Android开发中,确保短信发送状态的可靠性是非常重要的。为了实现这一功能,我们可以注册一个发送状态的监听器( OnSendStatusChangeListener ),该监听器会在短信发送操作完成后被调用,从而让开发者得知短信是否成功发送。
// 创建SmsManager实例
SmsManager smsManager = SmsManager.getDefault();
// 注册发送状态监听器
smsManager.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
在这里, phoneNumber 是目标手机号码, message 是要发送的短信内容, sentPI 和 deliveredPI 分别是用于追踪短信发送状态和送达状态的 PendingIntent 实例。这两个 PendingIntent 将在后续段落中详细描述。
监听器的回调方法解析
OnSendStatusChangeListener 接口只有一个方法 onSendStatusChanged ,该方法会在短信发送后被调用,其定义如下:
public interface OnSendStatusChangeListener {
void onSendStatusChanged(int status, @Nullable Bundle extras);
}
参数 status 表示短信发送的状态,是一个整型值,可能的值包括: - SmsManager.STATUS_ON_DELIVERY :表示短信正在传递。 - SmsManager.STATUS_ERROR_GENERIC_FAILURE :表示发送过程中发生了通用错误。 - SmsManager.STATUS_ERROR_NO_SERVICE :表示由于设备无法连接到网络服务,短信无法发送。 - SmsManager.STATUS_ERROR_NULL_PDU :表示短信内容为空。 - SmsManager.STATUS_ERROR_RADIO_OFF :表示设备的无线收发器(Radio)关闭。
extras 参数为 Bundle 类型,可能包含额外的信息,例如错误代码等。
4.1.2 状态监听器的回调方法解析
状态监听器的回调方法 onSendStatusChanged 需要根据状态码进行相应的处理。例如,若状态码为 SmsManager.STATUS_ON_DELIVERY ,则可以认为短信已经发送成功,并且正在传递到目标手机上。而如果状态码是 SmsManager.STATUS_ERROR_GENERIC_FAILURE ,则可能需要提示用户短信发送失败,并检查可能的原因。
// 实现OnSendStatusChangeListener接口
OnSendStatusChangeListener sendListener = new OnSendStatusChangeListener() {
@Override
public void onSendStatusChanged(int status, @Nullable Bundle extras) {
switch (status) {
case SmsManager.STATUS_ON_DELIVERY:
// 短信正在传递
// 在这里可以添加代码以更新UI或通知用户
break;
case SmsManager.STATUS_ERROR_GENERIC_FAILURE:
// 发送过程中出现通用错误
// 在这里可以添加代码以提示用户发送失败并记录错误信息
break;
// 其他状态码的处理逻辑
}
}
};
4.2 短信送达状态跟踪
4.2.1 设置送达报告接收器
短信送达报告是可选功能,可以让应用知道短信是否成功到达用户的设备。为了接收送达报告,我们需要创建一个 BroadcastReceiver ,它在接收到送达报告时被触发。
// 创建送达报告接收器
BroadcastReceiver送达报告Receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(Telephony.Sms.DELIVERED.EXTRA_STATUS, -1);
switch (status) {
case Telephony.Sms.DELIVERED报告显示成功:
// 短信成功送达
break;
// 其他状态的处理逻辑
}
}
};
4.2.2 解析送达状态报告
送达状态报告将通过 BroadcastReceiver 提供的 Intent 来获取。这个 Intent 包含了一个额外的数据 EXTRA_STATUS ,表示送达的状态。
// 注册送达报告接收器
context.registerReceiver(送达报告Receiver, new IntentFilter(Telephony.Sms.DELIVERED_ACTION));
送达报告可能的状态包括:
-
Telephony.Sms.DELIVERED报告显示成功:短信成功送达。 -
Telephony.Sms.DELIVERED报告显示失败:短信未能送达,原因可能包括用户禁用了短信接收或者SIM卡有问题。
使用送达报告时,开发者需要考虑用户隐私和权限问题。确保应用具有接收短信的权限,并在用户界面上清晰地告知用户你的应用将如何使用这些信息。
至此,我们已经探讨了如何通过监听和解析发送和送达状态来增强短信应用的用户体验和可靠性。下一章节我们将深入了解广播接收器的使用与创建,以及如何进一步提升短信应用的交互性和功能完整性。
5. 广播接收器的使用与创建
5.1 广播接收器基础知识
5.1.1 广播接收器的作用
广播接收器(BroadcastReceiver)是Android中实现应用程序之间通信的一种机制。当系统或应用程序产生一个特定的事件时(如开机完成、电池电量低、短信送达等),它会发出一条广播(Broadcast),然后广播接收器就能够接收这些广播,并作出相应的响应。
利用广播接收器,开发者可以创建能够响应各种系统级或自定义事件的组件。例如,对于短信应用而言,当短信送达时,系统会发出一条送达报告的广播,应用可以通过注册相应的广播接收器来监听这个事件,并执行进一步的逻辑处理,如更新UI显示送达状态,或者记录送达日志等。
5.1.2 创建自定义广播接收器
创建一个自定义的广播接收器涉及到以下几个步骤:
- 创建一个新的Java类继承自
BroadcastReceiver。 - 重写
onReceive方法,它将在接收到广播时被调用。 - 在
AndroidManifest.xml中注册广播接收器,或者使用IntentFilter在代码中动态注册。
以下是一个简单的广播接收器示例代码:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
// 逻辑处理
Log.d(TAG, "Received broadcast");
Toast.makeText(context, "Broadcast received!", Toast.LENGTH_SHORT).show();
}
}
然后在 AndroidManifest.xml 中添加对应的注册信息:
<receiver android:name=".MyBroadcastReceiver">
<!-- Intent filters can be registered here -->
</receiver>
或者在代码中动态注册:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.SMS_DELIVERED");
registerReceiver(new MyBroadcastReceiver(), intentFilter);
5.2 广播接收器在短信应用中的实践
5.2.1 接收短信送达报告的广播
为了接收短信送达报告,你需要创建一个广播接收器并监听 SMS_DELIVERED_ACTION 广播。这个动作由系统在短信成功送达收件人时发出。实现这一功能的代码逻辑如下:
public class SmsDeliveredReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.provider.Telephony.SMS_DELIVERED")) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
// 获取短信送达状态
int status = bundle.getInt("status");
// 通过状态码判断短信送达情况
if (status == TelephonyManager.SMS_DELIVERED_PORT导演) {
// 短信成功送达
} else {
// 短信发送失败
}
}
}
}
}
为了处理送达报告,还需要在发送短信时设置 sentIntents 和 deliveryIntents 参数为 true 。
5.2.2 自定义广播接收器的实现步骤
实现自定义广播接收器的详细步骤包括:
- 创建广播接收器类: 这是监听特定广播的入口。
- 定义接收广播的条件: 通过
IntentFilter指定要监听的广播动作。 - 注册广播接收器: 将广播接收器和
IntentFilter关联起来,可以在AndroidManifest.xml静态注册,也可以在代码中动态注册。 - 实现
onReceive方法: 当接收到匹配的广播时,系统会调用此方法,并传入上下文和意图。 - 处理接收到的数据: 在
onReceive方法中解析接收到的数据,并根据逻辑执行相应的动作。
例如,自定义广播接收器处理短信送达的实现代码片段如下:
// 定义接收器
private class MySmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(TelephonyManager.ACTION SimsSmsSent)) {
int result = intent.getIntExtra("result", -1);
if (result == Activity.RESULT_OK) {
// 短信发送成功
} else {
// 短信发送失败
}
} else if (intent.getAction().equals(TelephonyManager.ACTION SimsSmsDelivered)) {
int deliveryStatus = intent.getIntExtra("deliveryStatus", -1);
if (deliveryStatus == TelephonyManager.SMS_DELIVERED) {
// 短信送达成功
} else {
// 短信送达失败
}
}
}
}
最后,通过如下代码动态注册广播接收器:
IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyManager.ACTION SimsSmsSent);
filter.addAction(TelephonyManager.ACTION SimsSmsDelivered);
registerReceiver(new MySmsReceiver(), filter);
或者静态注册在 AndroidManifest.xml 中:
<receiver android:name=".MySmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_SENT" />
<action android:name="android.provider.Telephony.SMS_DELIVERED" />
</intent-filter>
</receiver>
这样,每当有短信发送或送达时,系统会发送相应的广播,而 MySmsReceiver 中的 onReceive 方法会被调用,执行相应的逻辑处理。
6. AndroidManifest.xml中的权限注册
6.1 必要权限的添加与说明
6.1.1 发送短信权限
在Android应用中,发送短信功能是一个非常敏感的操作,需要向用户明确声明这一权限请求。在AndroidManifest.xml中,你需要声明 SEND_SMS 权限以允许应用发送短信。这一权限的声明,通常会伴随着用户在运行时对权限的明确授权,以确保应用的操作符合用户的意愿。
<uses-permission android:name="android.permission.SEND_SMS" />
上述代码行应直接放置在 <manifest> 标签内,以确保应用在运行时能够执行短信发送操作。使用了这一权限声明后,当你尝试通过代码发起短信发送请求时,系统会自动触发权限请求对话框,提示用户授权。
6.1.2 接收短信权限
除了发送短信权限外,如果你的应用也需要接收短信功能,例如接收并处理短信验证码,那么你还需要在AndroidManifest.xml中声明 RECEIVE_SMS 权限。这一权限声明同样需要用户在运行时的授权。
<uses-permission android:name="android.permission.RECEIVE_SMS" />
通过声明 RECEIVE_SMS 权限,应用将能够监听到来自系统的短信事件,允许开发者根据业务需求对短信进行解析和处理。
6.2 权限注册的最佳实践
6.2.1 如何在AndroidManifest.xml中声明权限
声明权限是保证应用安全性和功能完整性的重要步骤。对于短信应用而言,权限声明不仅有助于保护用户隐私,也能防止应用在没有适当授权的情况下执行敏感操作。在AndroidManifest.xml中添加权限声明,是一种静态的权限声明方式。
<manifest package="com.example.mysmsapp">
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<!-- 其他必要的权限声明 -->
</manifest>
开发者需确保在应用包内正确声明了所有需要的权限,同时也要在代码中做好运行时权限请求的处理,以保证应用的兼容性和安全性。
6.2.2 动态权限请求与适配
从Android 6.0 (API 级别 23) 开始,Android引入了运行时权限模型。这意味着仅仅在AndroidManifest.xml中声明权限是不够的,还需要在代码中动态请求用户授权。对于短信功能,你需要在代码中检查权限,并在没有权限时请求它。
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
}
上述代码段是动态请求 SEND_SMS 权限的一个例子。当 requestPermissions 方法被调用后,系统会弹出一个对话框让用户决定是否授予该权限。如果用户同意,应用即可继续执行发送短信的操作;如果用户拒绝,则应用无法执行需要该权限的操作。
对于开发者而言,了解并实践动态权限请求机制是关键,它将帮助你的应用在所有Android版本上都能良好地运行。适配运行时权限也是提高用户体验的重要环节,因为这样可以在用户不同意授权时提供合理的替代方案或说明。
7. 程序稳定性和易用性的考量
在构建一个稳健且用户体验良好的Android短信发送应用程序时,程序稳定性和易用性是不可忽视的关键因素。一个应用程序是否能够稳定运行,直接影响到用户对应用程序的信赖度。同时,用户界面的友好性和操作流程的优化则关乎用户是否愿意持续使用该应用。
7.1 提高短信发送程序的稳定性
7.1.1 异常处理机制
为了确保短信发送程序的稳定性,我们需要考虑所有可能的异常情况,并实现相应的异常处理机制。在Android中,通常会使用try-catch语句来捕获和处理异常。
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
} catch (SecurityException e) {
// 处理权限问题
e.printStackTrace();
} catch (IllegalArgumentException e) {
// 处理不合法的参数
e.printStackTrace();
} catch (RemoteException e) {
// 处理与SMS服务通信失败
e.printStackTrace();
}
7.1.2 程序的健壮性测试
在应用发布之前,进行充分的测试是确保程序稳定性的关键步骤。这包括单元测试、集成测试和用户接受测试(UAT)。单元测试可以确保每个模块按预期工作,集成测试确保各个模块协同工作无误,而用户接受测试则关注于用户体验和应用的整体流程。
7.2 优化用户界面和体验
7.2.1 界面友好性改进
为了提高用户界面的友好性,需要考虑以下几个方面:
- 简洁明了的布局 :避免过于复杂的布局,使用简单直观的用户界面元素。
- 清晰的指示 :提供明确的指示,告知用户操作的结果,如短信发送成功或失败。
- 反馈权限控制的体验 :当需要请求权限时,提供清晰的解释说明为何需要这些权限。
7.2.2 用户操作流程的优化
在用户操作流程上,应遵循以下原则:
- 最小化操作步骤 :减少用户需要点击或输入的次数,提供一键式操作。
- 反馈及时性 :在进行如短信发送等操作时,给予即时的反馈,如使用进度条或动画显示操作状态。
- 容错设计 :对于用户的错误操作提供纠正的机会,如短信发送失败时允许用户重试。
通过结合以上的方法,我们可以设计并实现一个既稳定又易用的短信发送程序。这些原则和技巧不仅适用于短信发送应用,也适用于其他类型的Android应用开发。在开发过程中,持续迭代和用户反馈是不断优化应用,提高用户体验的重要手段。
简介:在Android开发中,实现短信发送功能常依赖于 SmsManager 类和 PendingIntent 类。本文深入解析了如何运用这两个类来构建一个能够发送短信并监控发送状态的应用程序。通过实例代码展示如何发送短信以及如何通过广播接收器获取短信发送与送达状态的通知。文章还强调了用户界面设计、异常处理和权限管理在开发过程中的重要性。




1185

被折叠的 条评论
为什么被折叠?



