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

PhoneNumberFormattingTextWatcher对特定美国手机号格式化失效问题

PhoneNumberFormattingTextWatcher fails to format 1111111111 (US number) but works for others like 2222222222

Problem Description

I'm using PhoneNumberFormattingTextWatcher to format US phone numbers as users type. However, when entering 1111111111, the formatting doesn't work at all. For other numbers like 2222222222, it correctly outputs the format (222)222-2222.

Here's my code snippet:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    edit_phone.addTextChangedListener(new PhoneNumberFormattingTextWatcher("US") {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // Custom logic (if any)
        }
        // Other overridden methods (if any)
    });
}

Analysis & Solutions

1. Root Cause: libphonenumber's Validity Checks

The PhoneNumberFormattingTextWatcher relies on Google's libphonenumber library under the hood. The number 111-111-1111 is an invalid NANP (North American Numbering Plan) number—US area codes (the first 3 digits) can't be 111 (these are reserved/non-functional area codes). The library skips formatting for invalid numbers entirely, which is why numbers with valid area codes work as expected.

2. Fix Options

Option 1: Force Formatting (Ignore Validity)

If you just need consistent formatting regardless of whether the number is actually valid, implement a custom TextWatcher to handle the formatting manually:

edit_phone.addTextChangedListener(new TextWatcher() {
    private boolean isFormatting;

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable s) {
        if (isFormatting) return;
        isFormatting = true;

        // Strip all non-digit characters
        String digits = s.toString().replaceAll("\\D", "");
        StringBuilder formatted = new StringBuilder();

        if (!digits.isEmpty()) {
            formatted.append("(").append(digits.substring(0, Math.min(3, digits.length())));
            if (digits.length() >= 3) {
                formatted.append(")");
                formatted.append(digits.substring(3, Math.min(6, digits.length())));
                if (digits.length() >= 6) {
                    formatted.append("-").append(digits.substring(6, Math.min(10, digits.length())));
                }
            }
        }

        s.replace(0, s.length(), formatted.toString());
        isFormatting = false;
    }
});

Option 2: Skip Validity Checks (Advanced)

If you want to stick with the official PhoneNumberFormattingTextWatcher, you could try bypassing the validity check via reflection or a custom PhoneNumberUtil instance. Note that this is risky—it relies on internal APIs that might break with system updates.

Option 3: Guide Users to Enter Valid Numbers

Add a real-time validity check and show a friendly prompt (e.g., "Please enter a valid US area code") when users input invalid prefixes, guiding them to use legitimate area codes.

3. Quick Validation Test

You can confirm the validity issue directly with libphonenumber's core methods:

PhoneNumberUtil util = PhoneNumberUtil.getInstance();
try {
    Phonenumber.PhoneNumber number = util.parse("1111111111", "US");
    Log.d("PHONE", "Is valid: " + util.isValidNumber(number)); // Returns false
    Log.d("PHONE", "Formatted: " + util.format(number, PhoneNumberUtil.PhoneNumberFormat.NATIONAL));
} catch (NumberParseException e) {
    e.printStackTrace();
}

This will confirm that 1111111111 is marked as invalid, so the library won't format it.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:23:32