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

Android应用自动读取OTP功能实现故障排查求助

老兄,我来帮你排查OTP自动填充没反应的问题!咱们一步步梳理可能的原因和解决办法:

第一步:检查权限配置是否完整

OTP读取核心依赖短信权限,先确认权限配置到位:

  • 在AndroidManifest.xml里声明静态权限:
    <!-- 接收短信权限 -->
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <!-- 读取短信内容权限 -->
    <uses-permission android:name="android.permission.READ_SMS" />
    
  • 注意Android 6.0(API 23)及以上必须动态申请权限,不能只靠Manifest声明,在Activity里补充权限申请逻辑:
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECEIVE_SMS}, 100);
    }
    
第二步:确认广播接收器注册正确

广播接收器有两种注册方式,你得确保其中一种配置无误:

  • 静态注册(Manifest中):
    <receiver android:name=".ReadSms"
              android:exported="true">
        <intent-filter android:priority="999"> <!-- 高优先级确保优先接收短信广播 -->
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>
    
  • 动态注册(代码中,Android 12+更推荐这种方式):
    private ReadSms smsReceiver;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        smsReceiver = new ReadSms();
        IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
        filter.setPriority(999);
        registerReceiver(smsReceiver, filter);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(smsReceiver); // 记得注销避免内存泄漏
    }
    
第三步:检查SMS内容解析逻辑是否正确

你的ReadSms类的onReceive方法里,得正确解析短信提取OTP,给你一个标准的解析示例,对比下自己的代码:

@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) {
                SmsMessage[] messages = new SmsMessage[pdus.length];
                for (int i = 0; i < pdus.length; i++) {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    String smsBody = messages[i].getMessageBody();
                    String sender = messages[i].getOriginatingAddress();
                    
                    // 替换成你的服务器号码或短信关键词,比如包含"你的APP名称"或"OTP"
                    if (sender != null && sender.contains("123456789") && smsBody.contains("OTP")) {
                        // 提取6位数字OTP,根据实际格式调整正则
                        Pattern pattern = Pattern.compile("\\d{6}");
                        Matcher matcher = pattern.matcher(smsBody);
                        if (matcher.find()) {
                            String otp = matcher.group();
                            // 通过本地广播把OTP传递给EditText
                            Intent otpIntent = new Intent("OTP_RECEIVED");
                            otpIntent.putExtra("otp", otp);
                            LocalBroadcastManager.getInstance(context).sendBroadcast(otpIntent);
                        }
                    }
                }
            }
        }
    }
}
第四步:确保EditText能接收并填充OTP

在你的Activity里监听本地广播,把提取到的OTP设置到EditText:

private BroadcastReceiver otpReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String otp = intent.getStringExtra("otp");
        EditText otpEditText = findViewById(R.id.otp_edittext);
        otpEditText.setText(otp);
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...其他初始化代码
    LocalBroadcastManager.getInstance(this).registerReceiver(otpReceiver, new IntentFilter("OTP_RECEIVED"));
}

@Override
protected void onDestroy() {
    super.onDestroy();
    LocalBroadcastManager.getInstance(this).unregisterReceiver(otpReceiver);
}
第五步:调试技巧帮你定位问题
  • 用adb命令模拟发送测试短信,快速验证广播是否触发:
    adb shell am broadcast -a android.provider.Telephony.SMS_RECEIVED --es sms_body "你的OTP是123456" --es address "123456789"
    
  • 在onReceive方法里加日志,确认是否收到广播、是否正确解析OTP:
    Log.d("ReadSms", "收到短信内容:" + smsBody);
    Log.d("ReadSms", "提取到的OTP:" + otp);
    

如果排查完这些还是没反应,可以把ReadSms的完整代码贴出来,我再帮你细查!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:57:19