如何发送不显示在短信应用中的Multipart SMS?
好问题!要实现不写入短信提供商(不在短信应用中显示)的多部分SMS,核心是要把「拆分长短信」和「跳过持久化存储」这两个逻辑结合起来——毕竟Android SDK并没有直接给我们一个现成的sendMultipartTextMessageWithoutPersisting方法。下面是具体的实现思路和代码示例:
实现原理
Android的SmsManager类中,sendTextMessageWithoutPersisting的本质是在发送时传递了一个persist=false的参数,跳过了将短信写入系统短信数据库的步骤;而sendMultipartTextMessage则负责将超长短信拆分为多个部分并依次发送。我们可以通过反射调用SmsManager内部的重载方法,同时传入拆分后的短信列表和persist=false的参数,从而实现需求。
具体代码实现
1. 拆分超长短信
首先用SmsManager的内置方法把长文本拆分成符合单条短信长度限制的片段:
SmsManager smsManager = SmsManager.getDefault(); String longContent = "这里是你的超长短信内容,长度超过了单条SMS的字符限制,需要拆分成多部分发送"; ArrayList<String> messageParts = smsManager.divideMessage(longContent);
2. 反射调用带持久化参数的多部分发送方法
通过反射获取SmsManager中带有persist参数的sendMultipartTextMessage重载方法,传入false来禁止持久化:
try { // 获取目标方法,注意参数签名要匹配对应Android版本的内部实现 Method sendMethod = SmsManager.class.getDeclaredMethod( "sendMultipartTextMessage", String.class, String.class, ArrayList.class, ArrayList.class, ArrayList.class, boolean.class ); sendMethod.setAccessible(true); // 允许访问私有/受保护方法 // 调用方法,参数依次为:接收号码、短信中心地址、拆分后的短信列表、 // 发送状态Intent列表、送达状态Intent列表、是否持久化(false=不写入短信应用) sendMethod.invoke( smsManager, "13800138000", // 替换为实际接收号码 null, // 使用默认短信中心地址 messageParts, null, // 不需要监听发送状态可传null null, // 不需要监听送达状态可传null false ); } catch (NoSuchMethodException e) { // 处理方法不存在的情况,比如适配不同Android版本 e.printStackTrace(); } catch (IllegalAccessException | InvocationTargetException e) { // 处理调用异常 e.printStackTrace(); }
关键注意事项
- 权限要求:确保你的应用已经声明并获取了
SEND_SMS权限,Android 6.0及以上版本需要动态申请该权限。 - 兼容性风险:反射依赖于Android系统的内部API,不同厂商或Android版本可能会修改方法签名,建议在多个版本的设备上做兼容性测试。如果反射失败,可以考虑降级为普通的
sendMultipartTextMessage(但短信会显示在短信应用中)。 - 状态监听:如果需要监听每个短信片段的发送/送达状态,可以传入对应的
sentIntents和deliveryIntents列表,每个片段对应一个Intent。
内容的提问来源于stack exchange,提问作者Vladimir Gatev
相关产品推荐
相关产品推荐

