java 使用google libphonenumber获取运营商前缀

3pvhb19x  于 2023-01-16  发布在  Java
关注(0)|答案(2)|浏览(215)

我需要确定任何电话号码的国家运营商代码(而不是运营商名称),使用libphonenumber Java SDK.我该怎么做?我可以找到如何检索运营商名称的唯一方法:

Locale.PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
        PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper.getInstance();
        Phonenumber.PhoneNumber numberProto = phoneUtil.parse(+375445111111, "");
        String name = carrierMapper.getNameForValidNumber(numberProto, Locale.US);
        System.out.println(name);//Velcome, but I need just number like 44, or 37544, or 375445
35g0bw71

35g0bw711#

你不能。不是每个国家的电话号码都像这样在运营商之间分割,所以不是每个国家都有运营商代码。
特别是在欧盟,不可能从电话号码推导出运营商,因为欧盟规定,人们可以在不改变电话号码的情况下切换运营商。虽然每个运营商可能都有特定的号码序列,由国家当局分配给客户(而不是根据需要按顺序或随机获得),但这些号码绝不保证属于任何特定的运营商。
我不知道libphonenumber是如何试图找到运营商名称的,也许它会查询数据库或进行有根据的猜测,如果它是开源的,你也许可以自己找到并从那里开始。

ckocjqey

ckocjqey2#

我最后的肮脏解决方案。从com.google.i18n.phonenumbers类复制粘贴的部分代码应该位于package com.google.i18n.phonenumbers.prefixmapper;中,否则无法访问类的方法、字段或变量。

package com.google.i18n.phonenumbers.prefixmapper;

import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.SortedSet;
@Slf4j
public class Mapper {
    public static final String[] EMPTY = new String[]{null, null, null};

    public static void main(String ... args) {
        Mapper mapper = new Mapper();
        new ArrayList<String>(){{
            add("375-44-111-12-22");
            add("+3754411112233");
            add("995-593111222");
            add("+995593111222");
        }}.forEach(phone -> {
            try {
                String[] result = mapper.parsePhone(phone);
                System.out.print("input: " + phone + " country code: " + result[0]);
                System.out.print(" carrier: " + result[1] + " ");
                System.out.println(" phone: " + result[2]);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
    }
    private PhonePrefixMapStorageStrategy phonePrefixMapStorage;
    
    public String[] parsePhone(String phone) throws IOException {
        if(phone == null || phone.isEmpty()) {
            return EMPTY;
        }
        int countryCode;

        PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
        Long phoneNumber;
        try {
            if(phone.indexOf("+") != 0) {
                phone = "+" + phone;
            }
            Phonenumber.PhoneNumber numberProto = phoneUtil.parse(phone, "");
            countryCode = numberProto.getCountryCode();
            phoneNumber = Long.parseLong(countryCode + String.valueOf(numberProto.getNationalNumber()));
        } catch (NumberParseException e) {
            log.error("fail to parse phone number {}.", phone, e);
            return EMPTY;
        }

        String carrier;
        try (InputStream inputStream = Mapper.class.getResourceAsStream("/com/google/i18n/phonenumbers/carrier/data/" + countryCode + "_en")) {
            try (ObjectInputStream streamReader = new ObjectInputStream(inputStream)) {
                boolean useFlyweightMapStorage = streamReader.readBoolean();
                if (useFlyweightMapStorage) {
                    this.phonePrefixMapStorage = new FlyweightMapStorage();
                } else {
                    this.phonePrefixMapStorage = new DefaultMapStorage();
                }
                phonePrefixMapStorage.readExternal(streamReader);
                String result = lookup(phoneNumber);
                carrier = result == null ? null : result.substring(String.valueOf(countryCode).length());
            }
        }
        String prefix = "+" + countryCode + (carrier == null ? "" : carrier);
        return new String[]{String.valueOf(countryCode), carrier, String.valueOf(phoneNumber).substring(prefix.length() - 1)};
    }
    
    private int binarySearch(int start, int end, long value) {
        int current = 0;

        while(start <= end) {
            current = start + end >>> 1;
            int currentValue = this.phonePrefixMapStorage.getPrefix(current);
            if ((long)currentValue == value) {
                return current;
            }

            if ((long)currentValue > value) {
                --current;
                end = current;
            } else {
                start = current + 1;
            }
        }

        return current;
    }

    private String lookup(long number) {
        int numOfEntries = this.phonePrefixMapStorage.getNumOfEntries();
        if (numOfEntries == 0) {
            return null;
        } else {
            long phonePrefix = number;
            int currentIndex = numOfEntries - 1;

            Integer possibleLength;
            for(SortedSet<Integer> currentSetOfLengths = this.phonePrefixMapStorage.getPossibleLengths(); ((SortedSet)currentSetOfLengths).size() > 0; currentSetOfLengths = ((SortedSet)currentSetOfLengths).headSet(possibleLength)) {
                possibleLength = (Integer)((SortedSet)currentSetOfLengths).last();
                String phonePrefixStr = String.valueOf(phonePrefix);
                if (phonePrefixStr.length() > possibleLength) {
                    phonePrefix = Long.parseLong(phonePrefixStr.substring(0, possibleLength));
                }

                currentIndex = this.binarySearch(0, currentIndex, phonePrefix);
                if (currentIndex < 0) {
                    return null;
                }

                int currentPrefix = this.phonePrefixMapStorage.getPrefix(currentIndex);
                if (phonePrefix == (long)currentPrefix) {
                    return String.valueOf(currentPrefix);
                }
            }

            return null;
        }
    }
}

相关问题