1. 程式人生 > >java學習筆記(三)手機歸屬地查詢的程式碼,親測可用

java學習筆記(三)手機歸屬地查詢的程式碼,親測可用

由於公司行業主要是展會行業,展會上的觀眾註冊等,填寫基本資訊的時候會採集手機號等資訊,展會結束後我們需要做資料分析。只有通過手機號查詢歸屬地來獲取客戶的地域資訊。找了好多平臺和api,發現沒有說是能批量處理手機號資訊。最後還是找了githup上找到一個外掛,感謝那位大神的貢獻。

傳送門> https://github.com/xluohome/phonedata 主要涉及到兩個類和一個dat檔案 PhoneNumberGeo.java 和 PhoneNumberInfo.java 以及一個 phone.dat檔案(存放手機歸屬資訊的),dat檔案可在傳送門裡面找到。 PhoneNumberGeo.java 檔案內容如下,主要作用是來讀取phone.dat檔案。

package com.yh.util.phone;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * Created by buring 18/10/12.
 */
public class PhoneNumberGeo {

  private static String[] numberType = {null, "移動", "聯通", "電信", "電信虛擬運營商", "聯通虛擬運營商", "移動虛擬運營商"};
  private static final int INDEX_SEGMENT_LENGTH = 9;

  private static byte[] dataByteArray;
  private ByteBuffer byteBuffer;
  private int indexAreaOffset = -1;
  private int phoneRecordCount = -1;

  public PhoneNumberGeo() {
    if (dataByteArray == null) {
      synchronized (PhoneNumberGeo.class) {
        if (dataByteArray == null) {
          ByteArrayOutputStream byteData = new ByteArrayOutputStream();
          byte[] buffer = new byte[1024];

          int readBytesLength;
          try {
        	  InputStream inputStream = PhoneNumberGeo.class
                      .getResourceAsStream("phone.dat");
            while ((readBytesLength = inputStream.read(buffer)) != -1) {
              byteData.write(buffer, 0, readBytesLength);
            }
            inputStream.close();
          } catch (Exception e) {
            System.err.println("Can't find phone.dat in classpath:phone-number-geo/phone.dat");
            e.printStackTrace();
            throw new RuntimeException(e);
          }

          dataByteArray = byteData.toByteArray();
        }
      }
    }

    byteBuffer = ByteBuffer.wrap(dataByteArray);
    byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
    int dataVersion = byteBuffer.getInt();
    indexAreaOffset = byteBuffer.getInt();

    // print data version
    // System.out.println(dataVersion);

    phoneRecordCount = (dataByteArray.length - indexAreaOffset) / INDEX_SEGMENT_LENGTH;
    // print record count
    // System.out.println(phoneRecordCount);
  }

  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(numberType[phoneType]);
        return phoneNumberInfo;
      }
    }
    return null;
  }

  public static void main(String[] args) {
    PhoneNumberGeo phoneNumberGeo = new PhoneNumberGeo();
    Scanner scanner = new Scanner(System.in);
    while (scanner.hasNext()) {
      System.out.println(phoneNumberGeo.lookup(scanner.next()));
    }
  }
}

PhoneNumberInfo.java 檔案內容如下,主要作用 定義一個model

package com.yh.util.phone;

public class PhoneNumberInfo {
  private String phoneNumber;
  private String province;
  private String city;
  private String zipCode;
  private String areaCode;
  private String phoneType;

  public String getPhoneNumber() {
    return phoneNumber;
  }

  public void setPhoneNumber(String phoneNumber) {
    this.phoneNumber = phoneNumber;
  }

  public String getProvince() {
    return province;
  }

  public void setProvince(String province) {
    this.province = province;
  }

  public String getCity() {
    return city;
  }

  public void setCity(String city) {
    this.city = city;
  }

  public String getZipCode() {
    return zipCode;
  }

  public void setZipCode(String zipCode) {
    this.zipCode = zipCode;
  }

  public String getAreaCode() {
    return areaCode;
  }

  public void setAreaCode(String areaCode) {
    this.areaCode = areaCode;
  }

  public String getPhoneType() {
    return phoneType;
  }

  public void setPhoneType(String phoneType) {
    this.phoneType = phoneType;
  }

  @Override public String toString() {
    return "PhoneNumberInfo{" +
        "phoneNumber='" + phoneNumber + '\'' +
        ", province='" + province + '\'' +
        ", city='" + city + '\'' +
        ", zipCode='" + zipCode + '\'' +
        ", areaCode='" + areaCode + '\'' +
        ", phoneType='" + phoneType + '\'' +
        '}';
  }
}

檔案存放路徑建議 在這裡插入圖片描述 呼叫的程式碼如下

	String phoneNum = '13609257706'
	PhoneNumberGeo phoneNumberGeo = new PhoneNumberGeo();
	PhoneNumberInfo phoneNumberInfo = phoneNumberGeo.lookup(val);
	if(null!=phoneNumberInfo){
		//獲取省份
		String province = phoneNumberInfo.getProvince();
		//獲取城市 需要其他的引數自行查詢PhoneNumberInfo類獲取
		String city = phoneNumberInfo.getCity();
		System.out.println(province+"\t"+city);
	 }else{
	    	System.out.println("請單獨去查詢");
	 }

有問題請隨時@,郵箱[email protected]