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

Android调用OTP接口前如何校验EditText输入的无效手机号

问题核心

你当前使用的android.util.Patterns.PHONE仅做最宽松的通用格式校验,只会判断字符组成、长度是否符合电话号码的通用规则,完全不会校验号码是否符合对应国家运营商的实际放号逻辑,所以像+91-0000000000、+91-0000000011、+91-1234567890这类格式合规但实际不存在的假号会直接漏过。

可行前置校验方案

针对印度(+91)手机号场景,做三层递进校验即可在调用OTP接口前拦截绝大多数假号,不需要引入额外第三方库,本地执行无性能损耗,完全适配输入实时校验、点击按钮前置拦截的场景:

第一层:输入归一化预处理

先清洗用户输入的内容,移除分隔符、特殊符号,剥离国家码拿到纯数字本地号,提前筛掉长度不符合要求的非法输入:

// 印度手机号配置常量
private static final String IN_COUNTRY_CODE = "91";
private static final int IN_LOCAL_MOBILE_LENGTH = 10;

private String normalizeIndianPhone(String input) {
    // 移除所有非数字字符(横杠、空格、括号、+号全部过滤)
    String digitsOnly = input.replaceAll("[^0-9]", "");
    // 处理带国家码的输入:12位长度且开头为91时,截掉前两位国家码
    if (digitsOnly.length() == IN_LOCAL_MOBILE_LENGTH + 2 && digitsOnly.startsWith(IN_COUNTRY_CODE)) {
        digitsOnly = digitsOnly.substring(2);
    }
    // 归一化后必须刚好是10位纯数字,否则直接判定无效
    return digitsOnly.length() == IN_LOCAL_MOBILE_LENGTH ? digitsOnly : null;
}

第二层:特征假号规则拦截

针对典型无效号的固定特征做定向拦截,覆盖你提到的所有无效样例:

  • 10位本地号首位为0/1:印度当前有效手机号首位仅开放6/7/8/9号段,0、1开头的号码不存在
  • 全号为重复数字:比如0000000000、1111111111这类测试用假号
  • 全号为连续顺/逆序数字:比如1234567890、9876543210这类随意输入的顺号
  • 前5位全为0:不存在00000开头的印度手机号段

第三层:整合后的完整校验逻辑

替换原有isValidMobile方法内的系统正则逻辑,整合所有校验规则:

private boolean isValidMobile(String phone) {
    // 第一步:格式归一化校验
    String localPhone = normalizeIndianPhone(phone);
    if (localPhone == null) {
        return false;
    }

    // 第二步:校验首位号段合法性
    char firstDigit = localPhone.charAt(0);
    if (firstDigit != '6' && firstDigit != '7' && firstDigit != '8' && firstDigit != '9') {
        return false;
    }

    // 第三步:拦截全重复数字假号
    boolean isAllSame = true;
    for (int i = 1; i < localPhone.length(); i++) {
        if (localPhone.charAt(i) != localPhone.charAt(0)) {
            isAllSame = false;
            break;
        }
    }
    if (isAllSame) {
        return false;
    }

    // 第四步:拦截连续顺/逆序假号
    boolean isSequentialAsc = true;
    boolean isSequentialDesc = true;
    for (int i = 1; i < localPhone.length(); i++) {
        if (localPhone.charAt(i) - localPhone.charAt(i-1) != 1) {
            isSequentialAsc = false;
        }
        if (localPhone.charAt(i-1) - localPhone.charAt(i) != 1) {
            isSequentialDesc = false;
        }
        if (!isSequentialAsc && !isSequentialDesc) {
            break;
        }
    }
    if (isSequentialAsc || isSequentialDesc) {
        return false;
    }

    // 第五步:拦截前5位全0的假号
    if (localPhone.startsWith("00000")) {
        return false;
    }

    // 所有规则校验通过才判定为有效号码
    return true;
}
补充说明
  • 这套规则可以直接放在发送OTP按钮的点击回调里,也可以绑定EditText的TextWatcher做实时输入提示
  • 如果后续需要支持其他国家的手机号,只需要对应修改国家码常量、本地号长度、号段校验规则即可
  • 系统自带的Patterns.PHONE可以作为最外层兜底校验,但不要单独依赖它做号码有效性判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:18:52