上一篇
安卓发送短信 状态
- 行业动态
- 2025-04-22
- 4
安卓发送短信状态含发送中、成功、失败,通过系统广播或回调机制通知应用处理
安卓发送短信的流程与状态处理
发送短信的核心方法
安卓中发送短信主要通过 SmsManager
类实现,核心方法是 sendTextMessage
,其定义为:
public void sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)
- destinationAddress: 目标手机号
- scAddress: 短信服务中心地址(可为 null)
- text: 短信内容
- sentIntent: 发送状态回调的
PendingIntent
- deliveryIntent: 送达回执的
PendingIntent
(可选)
发送状态回调机制
sentIntent
用于接收短信发送结果,系统会在发送完成后通过广播通知结果,需注册一个 BroadcastReceiver
处理回调。
示例代码
// 创建发送状态的 PendingIntent PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_SENT), PendingIntent.FLAG_UPDATE_CURRENT); // 注册广播接收器 registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (getResultCode()) { case Activity.RESULT_OK: // 发送成功 Log.d("SMS", "发送成功"); break; default: // 发送失败 Log.e("SMS", "发送失败,错误码:" + getResultCode()); break; } } }, new IntentFilter(ACTION_SENT)); // 发送短信 SmsManager.getDefault().sendTextMessage("123456789", null, "Hello", sentPI, null);
短信发送状态码与含义
状态码 | 含义 | 常见场景 |
---|---|---|
RESULT_OK |
发送成功 | 正常发送且无错误 |
RESULT_CANCELED |
发送被取消(如用户拦截) | 第三方应用拦截或系统限制 |
RESULT_ERROR |
发送失败 | 网络问题、目标地址无效、权限不足 |
RESULT_NO_SIM |
无 SIM 卡或 SIM 卡不可用 | 设备未插卡或 SIM 卡故障 |
RESULT_RADIO_OFF |
飞行模式或基站关闭 | 设备处于飞行模式或信号极差 |
关键注意事项
权限要求
- 必要权限:
android.permission.SEND_SMS
- 动态申请:Android 6.0+ 需在运行时申请权限。
- 默认短信应用限制:Android 10+ 需设置为默认短信应用(通过
role manager
)。
异步处理
- 短信发送是异步操作,主线程不会阻塞。
- 必须通过
PendingIntent
或BroadcastReceiver
获取结果。
兼容性问题
- Android 10+:需通过
RoleManager
设置为默认短信应用,否则发送失败。 - 模拟器限制:部分模拟器可能无法发送真实短信,需真机测试。
常见问题与解决方案
问题 | 解决方案 |
---|---|
发送失败,错误码 -1 | 检查是否声明 SEND_SMS 权限,并确保动态授权通过。 |
广播未触发 | 确保 PendingIntent 的 FLAG_UPDATE_CURRENT 正确设置,且广播接收器已注册。 |
目标地址无效 | 验证手机号格式是否正确(如国际格式 +8612345678900 )。 |
相关问题与解答
问题1:如何判断短信是否成功送达(对方是否收到)?
解答:sendTextMessage
的 deliveryIntent
参数可用于接收送达回执,但需对方设备支持并开启送达报告功能,实际开发中,送达回执可靠性较低,通常仅依赖发送状态(RESULT_OK
)作为成功依据。
问题2:如何发送多条短信并跟踪每条的状态?
解答:
使用 SmsManager.divideMessage
分割长短信为多条,并为每条单独创建 PendingIntent
。
ArrayList<String> messages = SmsManager.getDefault().divideMessage("超长短信内容"); for (String msg : messages) { SmsManager.getDefault().sendTextMessage(phoneNumber, null, msg, pendingIntentForEachPart, null); }
每条短信的 PendingIntent
需唯一,以便区分发送结果