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

Android 13及以上版本读取短信的方法与权限限制解决方案

Android 12+ 读取特定号码短信的可行方案

针对Android 12及以上版本无法通过常规权限申请获取READ_SMS权限的问题,结合你读取特定号码状态短信的业务场景,以下是几个合法可行的解决方案:

方案一:利用SMS_RECEIVED广播实时接收短信(无需READ_SMS权限)

Android 12+允许应用通过动态注册android.provider.Telephony.SMS_RECEIVED广播实时接收新短信,且无需申请READ_SMS权限。你的代码已实现核心逻辑,可做以下适配优化:

优化后的代码示例

// 在Activity的onCreate中调用动态注册广播
private void registerSmsReceiver() {
    smsReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
                Bundle bundle = intent.getExtras();
                if (bundle != null) {
                    Object[] pdus = (Object[]) bundle.get("pdus");
                    if (pdus != null) {
                        // Android 10+ 推荐使用带format参数的createFromPdu方法
                        String format = bundle.getString("format");
                        for (Object pdu : pdus) {
                            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu, format);
                            String sender = smsMessage.getDisplayOriginatingAddress();
                            String messageBody = smsMessage.getMessageBody();
                            handleSmsMessage(sender, messageBody);
                        }
                    }
                }
            }
        }
    };

    IntentFilter filter = new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
    // 设置优先级(可选,多应用监听时高优先级可先接收短信)
    filter.setPriority(1000);
    registerReceiver(smsReceiver, filter);
}

// 务必在Activity销毁时注销广播,避免内存泄漏
@Override
protected void onDestroy() {
    super.onDestroy();
    if (smsReceiver != null) {
        unregisterReceiver(smsReceiver);
    }
}

// 保留原有短信处理逻辑,过滤特定号码并处理内容
private void handleSmsMessage(String sender, String messageBody) {
    String messageHash = sender + "|" + messageBody;
    if (receivedMessageHashes.contains(messageHash)) {
        Log.d("SmsReceiver", "检测到重复消息,忽略处理。");
        return;
    }
    receivedMessageHashes.add(messageHash);

    Log.d("SmsReceiver", "发送方: " + sender);
    Log.d("SmsReceiver", "消息内容: " + messageBody);

    if (!currentStater.getStarter_phone_number().isEmpty() && sender.contains(currentStater.getStarter_phone_number())) {
        Log.d("SmsReceiver", "收到来自指定号码的短信: " + currentStater.getStarter_phone_number());

        if (messageBody.contains("3-PHASE OK")) {
            status.setText("3-PHASE OK");
            phase1.setImageResource(R.drawable.img_btn_background);
            phase2.setImageResource(R.drawable.img_btn_background);
            phase3.setImageResource(R.drawable.img_btn_background);
            isActivated = false;
            isActivated1 = false;
            isActivated2 = false;
        } else if (messageBody.contains("Line Fault")) {
            status.setText("Line Fault");
            phase1.setImageResource(R.drawable.img_btn_background);
            phase2.setImageResource(R.drawable.img_btn_background);
            phase3.setImageResource(R.drawable.img_btn_background);
        }
    }
}

注意事项

  • Android 8.0+静态注册该广播会失效,必须使用动态注册。
  • 仅能接收实时短信,无法读取历史短信。

方案二:引导用户手动开启SMS特殊权限(读取历史短信)

若必须读取历史短信,Android 12+将READ_SMS归为特殊权限,无法通过常规弹窗申请,需引导用户到应用设置页面手动开启:

权限申请优化代码

private void checkSmsPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
        // Android 12+ 直接跳转至应用特殊权限设置页
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            Intent intent = new Intent(Settings.ACTION_APP_SPECIAL_ACCESS_SETTINGS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_READ_SMS_PERMISSION);
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_READ_SMS_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            queryLatestSmsMessages();
        } else {
            showToast("读取短信权限被拒绝,请前往设置手动开启。");
        }
    }
}

注意事项

  • 此方案用户操作成本较高,仅在必须读取历史短信时使用。

方案三:SMS Retriever API(需短信格式配合)

若你能控制发送短信的格式,可使用Google提供的SMS Retriever API。该API无需任何短信权限,只需短信内容包含应用的签名哈希即可自动获取短信,适合验证码场景;若无法调整短信内容,则此方案不适用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:50:59