Android 13下使用SmsManager发送SMS失败问题求助
解决方案
1. 补全动态权限申请
Android 6.0(API 23)及以上版本,SEND_SMS属于危险权限,仅在清单里声明没用,必须在运行时主动申请:
// 检查权限状态 if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS}, 100); } // 处理权限申请结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限通过,执行发送 sendSms(yourBodyContent, targetPhoneNumber); } else { Toast.makeText(this, "需要开启短信发送权限才能继续", Toast.LENGTH_SHORT).show(); } } }
2. 替换硬编码的SIM卡订阅ID
别直接写0或1,先获取当前激活的SIM卡ID,避免选到未启用的卡:
private int getActiveSimId() { TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); if (telephonyManager != null && telephonyManager.getPhoneCount() > 0) { List<SubscriptionInfo> simList = telephonyManager.getSubscriptionInfoList(); if (simList != null) { for (SubscriptionInfo info : simList) { if (info.getSubscriptionId() != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { return info.getSubscriptionId(); } } } } return 0; // 无有效SIM时返回默认值 }
修改发送函数,同时添加状态监听的PendingIntent,明确失败原因:
private void sendSms(String body, String ph) { int activeSimId = getActiveSimId(); SmsManager smsManager = getApplicationContext().getSystemService(SmsManager.class) .createForSubscriptionId(activeSimId); ArrayList<String> parts = smsManager.divideMessage(body); // 准备发送状态监听的PendingIntent ArrayList<PendingIntent> sentIntents = new ArrayList<>(); Intent sentIntent = new Intent("SMS_SENT_ACTION"); PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); for (int i = 0; i < parts.size(); i++) { sentIntents.add(sentPI); } smsManager.sendMultipartTextMessage(ph, null, parts, sentIntents, null); }
注册广播接收器获取具体错误:
private BroadcastReceiver smsSentReceiver = 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: Toast.makeText(context, "发送失败:通用错误", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_NO_SERVICE: Toast.makeText(context, "发送失败:当前无信号", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_NULL_PDU: Toast.makeText(context, "发送失败:PDU数据为空", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_RADIO_OFF: Toast.makeText(context, "发送失败:无线电已关闭", Toast.LENGTH_SHORT).show(); break; } } }; // 在Activity的onCreate里注册 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); registerReceiver(smsSentReceiver, new IntentFilter("SMS_SENT_ACTION")); } // 在onDestroy里注销,避免内存泄漏 @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(smsSentReceiver); }
3. 检查短信中心号码
部分设备需要指定正确的短信中心号码才能发送,你可以在sendMultipartTextMessage的第二个参数位置填入运营商提供的短信中心号码,或者先检查系统自带短信APP里的中心号码是否正常。
4. 排查运营商频率限制
一开始能发后来发不了,大概率是运营商触发了短信发送频率限制,试试拉长发送间隔,或者直接联系运营商确认是否有相关管控规则。
内容的提问来源于stack exchange,提问作者Babu James
相关产品推荐
相关产品推荐

