You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Marshmallow及以上设备SmsManager失效致应用崩溃问题排查

解决Android 6.0+系统中短信发送应用崩溃的问题

嘿,我一眼就看出问题所在了——你的APP在Android 4.3上正常,但到Marshmallow(6.0)及以上就崩溃,核心原因是Android 6.0引入的动态权限机制。在API 23之前,权限只需要在Manifest里声明就行,但从6.0开始,像SEND_SMS这种「危险权限」必须在运行时向用户主动申请,用户同意后才能使用。

你的代码里已经做了权限检查和请求的第一步,但漏掉了最关键的权限回调处理——如果用户拒绝权限后你还是尝试发送短信,必然会触发崩溃。下面是完整的修复方案:

第一步:确认Manifest权限声明

先确保你已经在AndroidManifest.xml里添加了短信权限(这步你大概率已经做了,但还是确认下):

<uses-permission android:name="android.permission.SEND_SMS" />

第二步:完善短信发送逻辑

把你的sendSMS方法改成带权限判断和回调的完整逻辑:

首先定义一个权限请求码(放在你的Activity类里):

private static final int MY_PERMISSION_REQUEST_SEND_SMS = 1001; // 数值可以自定义
// 用来保存请求权限前的短信内容和手机号,避免用户重新输入
private String mPendingPhoneNumber;
private String mPendingMessage;

然后修改sendSMS方法:

private void sendSMS(String phoneNumber, String message) {
    // 先保存要发送的内容,后续回调里要用
    mPendingPhoneNumber = phoneNumber;
    mPendingMessage = message;

    // 检查是否已获得短信发送权限
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
        // 权限未授予,向用户申请
        ActivityCompat.requestPermissions(
                this,
                new String[]{Manifest.permission.SEND_SMS},
                MY_PERMISSION_REQUEST_SEND_SMS
        );
    } else {
        // 权限已授予,直接执行发送
        performSMSDelivery(phoneNumber, message);
    }
}

第三步:处理权限请求回调

必须重写onRequestPermissionsResult方法,处理用户的权限选择结果:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
    if (requestCode == MY_PERMISSION_REQUEST_SEND_SMS) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 用户同意了权限,执行发送
            performSMSDelivery(mPendingPhoneNumber, mPendingMessage);
        } else {
            // 用户拒绝了权限,给个友好提示
            Toast.makeText(this, "没有短信权限无法发送消息哦", Toast.LENGTH_SHORT).show();
        }
    }
}

第四步:实现真正的短信发送逻辑

把发送短信的核心逻辑抽成单独方法,避免重复代码:

private void performSMSDelivery(String phoneNumber, String message) {
    SmsManager smsManager = SmsManager.getDefault();
    try {
        smsManager.sendTextMessage(phoneNumber, null, message, null, null);
        Toast.makeText(this, "短信发送成功!", Toast.LENGTH_SHORT).show();
    } catch (Exception e) {
        Toast.makeText(this, "发送失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
        e.printStackTrace();
    }
}

额外提示

如果用户之前已经拒绝过权限请求,下次申请时可以弹出一个对话框,解释为什么需要这个权限(比如「我们需要短信权限来帮你发送验证码」),引导用户授予权限,提升用户体验。

内容的提问来源于stack exchange,提问作者Dylan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:59:43