您的位置:首页 >10.2 SmsManager(短信管理器)
发布于2026-08-12 阅读(0)
扫一扫,手机访问
这一节要讲的是 Android 里的 SmsManager,也就是短信管理器。名字其实已经说明得很直白了:它就是专门用来处理手机短信相关操作的。这个类在日常开发里的出场频率并不算高,通常只有在需要发送短信时,才会真正用到这个 API。这里说的短信,指的是普通文字短信;至于彩信,处理起来要复杂得多。再加上如今 QQ、微信这类社交 APP 早已成了主流,真要按一条一块钱去发彩信的人,确实不多。所以这一节只聚焦一件事:发送普通文字短信。官方文档:SmsManager
就是把写好的收信人和内容发送到系统的发送短信的界面,用户验证收件人内容是否真正确再点击发送! 说白了就是调用系统发短信的窗口,这样做有一定的好处:
用这种方式发短信,APP 在安装时就能少申请一条短信发送权限。这样一来,像 360 这类安全软件在安装提示里,通常也不会再弹出“这个 APP 有短信权限,可能会偷偷发短信喔”这样的提醒。别小看这一句提示,用户对“偷偷发短信”这件事往往非常反感。有的人确实不细看,直接就装了;但也有人一看到这种描述,第一反应就是:这应用居然可能偷发短信,太劝退了,干脆不装。更麻烦的是,还有些用户会直接禁止 APP 发送短信。这样的话,等到应用真正需要发短信时,就可能出现异常,严重一点甚至会直接崩溃。所以,如果你的应用确实需要通过短信来做验证,或者处理付费这类功能,比较稳妥的做法还是建议采用这种方式。
核心代码:
public void SendSMSTo(String phoneNumber,String message){
//判断输入的phoneNumber是否为合法电话号码
if(PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber)){
//Uri.parse("smsto") 这里是转换为指定Uri,固定写法
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:"+phoneNumber));
intent.putExtra("sms_body", message);
startActivity(intent);
}
}
这个就需要发短信的权限啦
uses-permission android:name="android.permission.SEND_SMS"/>
我们直接调用SmsManager为我们提供的短信接口发送短信:
sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliverIntent);
参数依次是:
- destinationAddress:收信人的电话号码
- scAddress:短信中心的号码,null的话使用当前默认的短信服务中心
- text:短信内容
- sentIntent:短信发送状态的信息:(发送状态的Intent) 如果不为null,当消息成功发送或失败这个PendingIntent就广播。结果代码是Activity.RESULT_OK 表示成功,或RESULT_ERROR_GENERIC_FAILURE、RESULT_ERROR_RADIO_OFF、RESULT_ERROR_NULL_PDU 之一表示错误。对应RESULT_ERROR_GENERIC_FAILURE,sentIntent可能包括额外的"错误代码"包含一 个无线电广播技术特定的值,通常只在修复故障时有用。每一个基于SMS的应用程序控制检测sentIntent。 如果sentIntent是空,调用者将检测所有未知的应用程序,这将导致在检测的时候发送较小数量的SMS。
- deliverIntent:短信是否被对方收到的状态信息:(接收状态的Intent) 如果不为null,当这个短信发送到接收者那里,这个PendtingIntent会被广播, 状态报告生成的pdu(指对等层次之间传递的数据单位)会拓展到数据("pdu")
...那么复杂,pdu是什么卵?好吧,别纠结,简单知道这些参数是:
电话号码,信息中心,短信内容,是否发送成功的监听,以及收信人是否接受的监听就好了!
核心代码:
public void sendSMS(String phoneNumber,String message){
//获取短信管理器
android.telephony.SmsManager smsManager = android.telephony.SmsManager.getDefault();
//拆分短信内容(手机短信长度限制),貌似长度限制为140个字符,就是
//只能发送70个汉字,多了要拆分成多条短信发送
//第四五个参数,如果没有需要监听发送状态与接收状态的话可以写null
List divideContents = smsManager.divideMessage(message);
for (String text : divideContents) {
smsManager.sendTextMessage(phoneNumber, null, text, sentPI, deliverPI);
}
}
可能你还需要监听短信是否发送成功,或者收信人是否接收到信息,就把下面的加上吧:
1)处理返回发送状态的sentIntent
//处理返回的发送状态
String SENT_SMS_ACTION = "SENT_SMS_ACTION";
Intent sentIntent = new Intent(SENT_SMS_ACTION);
PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, sentIntent, 0);
//注册发送信息的广播接收者
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context _context, Intent _intent) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(context, "短信发送成功", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE: //普通错误
break;
case SmsManager.RESULT_ERROR_RADIO_OFF: //无线广播被明确地关闭
break;
case SmsManager.RESULT_ERROR_NULL_PDU: //没有提供pdu
break;
case SmsManager.RESULT_ERROR_NO_SERVICE: //服务当前不可用
break;
}
}
}, new IntentFilter(SENT_SMS_ACTION));
2)处理返回接收状态的deliverIntent:
//处理返回的接收状态
String DELIVERED_SMS_ACTION = "DELIVERED_SMS_ACTION";
//创建接收返回的接收状态的Intent
Intent deliverIntent = new Intent(DELIVERED_SMS_ACTION);
PendingIntent deliverPI = PendingIntent.getBroadcast(context, 0,deliverIntent, 0);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context _context, Intent _intent) {
Toast.makeText(context,"收信人已经成功接收", Toast.LENGTH_SHORT).show();
}
}, new IntentFilter(DELIVERED_SMS_ACTION));
另外这里涉及到了广播的知识,如果你对广播不怎么了解的话,可以看下:
Android基础入门教程——BroadcastReceiver牛刀小试
Android基础入门教程——4.3.2 BroadcastReceiver庖丁解牛
好的,本节介绍了SmsManager发送文字短信的两种方式~非常简单~建议还是使用 第一种方案吧,起码用户体验好一点...
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
4
5
6
7
8
9