maven依赖
com.googlecode.libphonenumber
libphonenumber
8.12.29
com.googlecode.libphonenumber
carrier
1.155
com.googlecode.libphonenumber
geocoder
2.165
工具类1
import java.io.*;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
/**
* Created by fengjiajie on 16/10/12.
*/
public class PhoneNumberGeo {
private static final String[] PHONE_NUMBER_TYPE = {null, "移动", "联通", "电信", "电信虚拟运营商", "联通虚拟运营商", "移动虚拟运营商"};
private static final int INDEX_SEGMENT_LENGTH = 9;
private static final int DATA_FILE_LENGTH_HINT = 1024 * 1024 * 5;
private static byte[] dataByteArray;
private static int indexAreaOffset;
private static int phoneRecordCount;
private ByteBuffer byteBuffer;
private static synchronized void initData() throws FileNotFoundException {
if (dataByteArray == null) {
ByteArrayOutputStream byteData = new ByteArrayOutputStream(DATA_FILE_LENGTH_HINT);
byte[] buffer = new byte[1024];
int readBytesLength;
//phone.bat 修改自己的路径
File file = new File("D:\\javaData\\phone.dat");
FileInputStream fileInputStream = new FileInputStream(file);
// BufferedInputStream inputStream1 = FileUtil.getInputStream(file);
try (InputStream inputStream = fileInputStream) {
while ((readBytesLength = inputStream.read(buffer)) != -1) {
byteData.write(buffer, 0, readBytesLength);
}
} catch (Exception e) {
System.err.println("Can't find phone.dat in classpath");
e.printStackTrace();
throw new RuntimeException(e);
}
dataByteArray = byteData.toByteArray();
ByteBuffer byteBuffer = ByteBuffer.wrap(dataByteArray);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
int dataVersion = byteBuffer.getInt();
indexAreaOffset = byteBuffer.getInt();
phoneRecordCount = (dataByteArray.length - indexAreaOffset) / INDEX_SEGMENT_LENGTH;
// print data version
// System.out.println(dataVersion);
// print record count
// System.out.println(phoneRecordCount);
}
}
public PhoneNumberGeo() throws FileNotFoundException {
initData();
byteBuffer = ByteBuffer.wrap(dataByteArray);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
}
public PhoneNumberInfo lookup(String phoneNumber) {
if (phoneNumber == null || phoneNumber.length() > 11 || phoneNumber.length() < 7) {
return null;
}
int phoneNumberPrefix;
try {
phoneNumberPrefix = Integer.parseInt(phoneNumber.substring(0, 7));
} catch (Exception e) {
return null;
}
int left = 0;
int right = phoneRecordCount;
while (left <= right) {
int middle = (left + right) >> 1;
int currentOffset = indexAreaOffset + middle * INDEX_SEGMENT_LENGTH;
if (currentOffset >= dataByteArray.length) {
return null;
}
byteBuffer.position(currentOffset);
int currentPrefix = byteBuffer.getInt();
if (currentPrefix > phoneNumberPrefix) {
right = middle - 1;
} else if (currentPrefix < phoneNumberPrefix) {
left = middle + 1;
} else {
int infoBeginOffset = byteBuffer.getInt();
int phoneType = byteBuffer.get();
int infoLength = -1;
for (int i = infoBeginOffset; i < indexAreaOffset; ++i) {
if (dataByteArray[i] == 0) {
infoLength = i - infoBeginOffset;
break;
}
}
String infoString = new String(dataByteArray, infoBeginOffset, infoLength, StandardCharsets.UTF_8);
String[] infoSegments = infoString.split("\\|");
PhoneNumberInfo phoneNumberInfo = new PhoneNumberInfo();
phoneNumberInfo.setPhoneNumber(phoneNumber);
phoneNumberInfo.setProvince(infoSegments[0]);
phoneNumberInfo.setCity(infoSegments[1]);
phoneNumberInfo.setZipCode(infoSegments[2]);
phoneNumberInfo.setAreaCode(infoSegments[3]);
phoneNumberInfo.setPhoneType(PHONE_NUMBER_TYPE[phoneType]);
return phoneNumberInfo;
}
}
return null;
}
}
修改phone.dat路径
工具类2
import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
import java.io.FileNotFoundException;
import java.util.Locale;
/**
* @ClassName: PhoneUtil
* @Description:手机号码归属地工具类
*/
public class PhoneUtils {
private static PhoneNumberGeo phoneNumberGeo;
static {
try {
phoneNumberGeo = new PhoneNumberGeo();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
private static PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper.getInstance();
private static PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();
/**
* 直辖市
*/
private final static String[] MUNICIPALITY = {"北京市", "天津市", "上海市", "重庆市"};
/**
* 自治区
*/
private final static String[] AUTONOMOUS_REGION = {"新疆", "内蒙古", "西藏", "宁夏", "广西"};
/**
* 根据国家代码和手机号 判断手机号是否有效
*
* @param phoneNumber
* @param countryCode
* @return
*/
public static boolean checkPhoneNumber(String phoneNumber, String countryCode) {
int ccode = Integer.parseInt(countryCode);
long phone = Long.parseLong(phoneNumber);
PhoneNumber pn = new PhoneNumber();
pn.setCountryCode(ccode);
pn.setNationalNumber(phone);
return phoneNumberUtil.isValidNumber(pn);
}
/**
* 根据国家代码和手机号 判断手机运营商
*
* @param phoneNumber
* @param countryCode
* @return
*/
public static String getCarrier(String phoneNumber, String countryCode) {
int ccode = Integer.parseInt(countryCode);
long phone = Long.parseLong(phoneNumber);
PhoneNumber pn = new PhoneNumber();
pn.setCountryCode(ccode);
pn.setNationalNumber(phone);
//返回结果只有英文,自己转成成中文
String carrierEn = carrierMapper.getNameForNumber(pn, Locale.ENGLISH);
switch (carrierEn) {
case "China Mobile":
return "移动";
case "China Unicom":
return "联通";
case "China Telecom":
return "电信";
default:
break;
}
return "未知";
}
public static String getGeo(String phoneNumber, String countryCode) {
long phone = Long.parseLong(phoneNumber);
int country = Integer.parseInt(countryCode);
PhoneNumber pn = new PhoneNumber();
pn.setCountryCode(country);
pn.setNationalNumber(phone);
/* geocoder.getDescriptionForNumber()
System.out.println(regionCodeForNumber);*/
return geocoder.getDescriptionForNumber(pn, Locale.CHINESE);
}
public static String getProvince(String phoneNumber, String countryCode) {
String geo = getGeo(phoneNumber, countryCode);
//直辖市
for (String val : MUNICIPALITY) {
if (geo.equals(val)) {
return val;
}
}
// 自治区
for (String val : AUTONOMOUS_REGION) {
if (geo.startsWith(val)) {
return val;
}
}
// 其它
String[] splitArr = geo.split("省");
if (splitArr != null && splitArr.length == 2) {
return splitArr[0];
}
return "未知";
}
public static PhoneNumberInfo getPhoneNumberInfo(String mobile) {
return phoneNumberGeo.lookup(mobile);
}
public static String getPhoneType(String mobile) {
try {
return getPhoneNumberInfo(mobile).getPhoneType();
} catch (Exception e) {
return "未知";
}
}
public static String getProvince(String mobile) {
try {
return getPhoneNumberInfo(mobile).getProvince();
} catch (Exception e) {
return "未知";
}
}
public static String getCity(String mobile) {
try {
return getPhoneNumberInfo(mobile).getCity();
} catch (Exception e) {
return "未知";
}
}
public static String getAreaName(String mobile) {
try {
String province = getProvince(mobile);
String city = getCity(mobile);
if (province.equals(city)) {
return city;
}
return province + city;
} catch (Exception e) {
return "未知";
}
}
/*
18250093106
18729283660
15916356311
18741869630
13572028774
15933232795
15935687067
18273049689
13597498763
*/
/*public static void main(String[] args) {
System.out.println(getGeo("18250093106", "86"));
System.out.println(getCarrier("18250093106", "86"));
}*/
}
phone.bat下载
https://download.csdn.net/download/m0_47104939/87758917
// 直接调用
//运营商
String phoneType = PhoneUtils.getPhoneType(mobile);
//归属地
String areaName = PhoneUtils.getAreaName(mobile);
//城市
String city = PhoneUtils.getCity(mobile);
//省份
String province = PhoneUtils.getProvince(mobile);