本篇主要的工具类有:HexUtil、TelephoneUtil、DeviceUtil、
HexUtil工具类:
public class HexUtil {
/**
* 用于建立十六进制字符的输出的小写字符数组
*/
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* 用于建立十六进制字符的输出的大写字符数组
*/
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* 将字节数组转换为十六进制字符数组
* @param data byte[]
* @param toLowerCase <code>true</code> 转换成小写格式 , <code>false</code> 转换成大写格式
* @return 十六进制char[]
*/
public static char[] encodeHex(byte[] data, boolean toLowerCase) {
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
/**
* 将字节数组转换为十六进制字符数组
*
* @param data
* byte[]
* @param toDigits
* 用于控制输出的char[]
* @return 十六进制char[]
*/
protected static char[] encodeHex(byte[] data, char[] toDigits) {
int l = data.length;
char[] out = new char[l << 1];
// 两个字符序列形成十六进制值
for (int i = 0, j = 0; i < l; i++) {
out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
out[j++] = toDigits[0x0F & data[i]];
}
return out;
}
/**
* 将字节数组转换为十六进制字符串
* @param data byte[]
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data) {
return encodeHexStr(data, true);
}
/**
* 将字节数组转换为十六进制字符串
* @param data byte[]
* @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
* @return 十六进制String
*/
public static String encodeHexStr(byte[] data, boolean toLowerCase) {
return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
/**
* 将字节数组转换为十六进制字符串
* @param data byte[]
* @param toDigits 用于控制输出的char[]
* @return 十六进制String
*/
protected static String encodeHexStr(byte[] data, char[] toDigits) {
return new String(encodeHex(data, toDigits));
}
/**
* 将十六进制字符数组转换为字节数组
* @param data 十六进制char[]
* @return byte[]
* @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
*/
public static byte[] decodeHex(char[] data) {
int len = data.length;
if ((len & 0x01) != 0) {
throw new RuntimeException("Odd number of characters.");
}
byte[] out = new byte[len >> 1];
// 两个字符序列形成十六进制值
for (int i = 0, j = 0; j < len; i++) {
int f = toDigit(data[j], j) << 4;
j++;
f = f | toDigit(data[j], j);
j++;
out[i] = (byte) (f & 0xFF);
}
return out;
}
/**
* 将十六进制字符转换成一个整数
* @param ch 十六进制char
* @param index 十六进制字符在字符数组中的位置
* @return 一个整数
* @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
*/
protected static int toDigit(char ch, int index) {
int digit = Character.digit(ch, 16);
if (digit == -1) {
throw new RuntimeException("Illegal hexadecimal character " + ch
+ " at index " + index);
}
return digit;
}
}
TelephoneUtil工具类:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.content.Context;
import android.telephony.TelephonyManager;
/**
* 获取手机信息工具类,例如IMEI、IMSI、手机号、Sim卡状态等等.
* 需要添加的权限
* <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
*/
public class TelephoneUtil {
/**
* IMSI是国际移动用户识别码的简称(International Mobile Subscriber Identity)
* IMSI共有15位,其结构如下:
* MCC+MNC+MIN
* MCC:Mobile Country Code,移动国家码,共3位,中国为460;
* MNC:Mobile Network Code,移动网络码,共2位
* 在中国,移动的代码为电00和02,联通的代码为01,电信的代码为03
* 合起来就是(也是Android手机中APN配置文件中的代码):
* 中国移动:46000 46002
* 中国联通:46001
* 中国电信:46003
* 举例,一个典型的IMSI号码为460030912121001
*/
public static String getIMSI(Context context) {
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String IMSI = manager.getSubscriberId();
return IMSI;
}
/**
* IMEI是International Mobile Equipment Identity (国际移动设备标识)的简称
* IMEI由15位数字组成的”电子串号”,它与每台手机一一对应,而且该码是全世界唯一的
* 其组成为:
* 1. 前6位数(TAC)是”型号核准号码”,一般代表机型
* 2. 接着的2位数(FAC)是”最后装配号”,一般代表产地
* 3. 之后的6位数(SNR)是”串号”,一般代表生产顺序号
* 4. 最后1位数(SP)通常是”0″,为检验码,目前暂备用
*/
public static String getIMEI(Context context) {
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String IMEI = manager.getDeviceId();
return IMEI;
}
/**
* 获取电话信息
*/
public static String getTelephoneInfo(Context context) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = sdf.format(date);
StringBuilder sb = new StringBuilder();
sb.append("__ 手机信息 ").append(time).append("__");
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String IMSI = manager.getSubscriberId();
//IMSI前面三位460是国家号码,其次的两位是运营商代号,00、02是中国移动,01是联通,03是电信。
String providerName = null;
if (IMSI != null) {
if (IMSI.startsWith("46000") || IMSI.startsWith("46002")) {
providerName = "中国移动";
} else if (IMSI.startsWith("46001")) {
providerName = "中国联通";
} else if (IMSI.startsWith("46003")) {
providerName = "中国电信";
}
}
sb.append(providerName).append(" 手机号:").append(manager.getLine1Number()).append(" IMSI是:").append(IMSI);
sb.append("\nDeviceID(IMEI) :").append(manager.getDeviceId());
sb.append("\nDeviceSoftwareVersion:").append(manager.getDeviceSoftwareVersion());
sb.append("\ngetLine1Number :").append(manager.getLine1Number());
sb.append("\nNetworkCountryIso :").append(manager.getNetworkCountryIso());
sb.append("\nNetworkOperator :").append(manager.getNetworkOperator());
sb.append("\nNetworkOperatorName :").append(manager.getNetworkOperatorName());
sb.append("\nNetworkType :").append(manager.getNetworkType());
sb.append("\nPhoneType :").append(manager.getPhoneType());
sb.append("\nSimCountryIso :").append(manager.getSimCountryIso());
sb.append("\nSimOperator :").append(manager.getSimOperator());
sb.append("\nSimOperatorName :").append(manager.getSimOperatorName());
sb.append("\nSimSerialNumber :").append(manager.getSimSerialNumber());
sb.append("\ngetSimState :").append(manager.getSimState());
sb.append("\nSubscriberId :").append(manager.getSubscriberId());
sb.append("\nVoiceMailNumber :").append(manager.getVoiceMailNumber());
return sb.toString();
}
//双卡双待系统IMEI和IMSI方案(see more on http://benson37.iteye.com/blog/1923946)
/**
* 双卡双待神机IMSI、IMSI、PhoneType信息
*/
public static class TeleInfo {
public String imsi_1;
public String imsi_2;
public String imei_1;
public String imei_2;
public int phoneType_1;
public int phoneType_2;
@Override
public String toString() {
return "TeleInfo{" +
"imsi_1='" + imsi_1 + '\'' +
", imsi_2='" + imsi_2 + '\'' +
", imei_1='" + imei_1 + '\'' +
", imei_2='" + imei_2 + '\'' +
", phoneType_1=" + phoneType_1 +
", phoneType_2=" + phoneType_2 +
'}';
}
}
/**
* MTK Phone.
* 获取 MTK 神机的双卡 IMSI、IMSI 信息
*/
public static TeleInfo getMtkTeleInfo(Context context) {
TeleInfo teleInfo = new TeleInfo();
try {
Class<?> phone = Class.forName("com.android.internal.telephony.Phone");
Field fields1 = phone.getField("GEMINI_SIM_1");
fields1.setAccessible(true);
int simId_1 = (Integer) fields1.get(null);
Field fields2 = phone.getField("GEMINI_SIM_2");
fields2.setAccessible(true);
int simId_2 = (Integer) fields2.get(null);
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Method getSubscriberIdGemini = TelephonyManager.class.getDeclaredMethod("getSubscriberIdGemini", int.class);
String imsi_1 = (String) getSubscriberIdGemini.invoke(manager, simId_1);
String imsi_2 = (String) getSubscriberIdGemini.invoke(manager, simId_2);
teleInfo.imsi_1 = imsi_1;
teleInfo.imsi_2 = imsi_2;
Method getDeviceIdGemini = TelephonyManager.class.getDeclaredMethod("getDeviceIdGemini", int.class);
String imei_1 = (String) getDeviceIdGemini.invoke(manager, simId_1);
String imei_2 = (String) getDeviceIdGemini.invoke(manager, simId_2);
teleInfo.imei_1 = imei_1;
teleInfo.imei_2 = imei_2;
Method getPhoneTypeGemini = TelephonyManager.class.getDeclaredMethod("getPhoneTypeGemini", int.class);
int phoneType_1 = (Integer) getPhoneTypeGemini.invoke(manager, simId_1);
int phoneType_2 = (Integer) getPhoneTypeGemini.invoke(manager, simId_2);
teleInfo.phoneType_1 = phoneType_1;
teleInfo.phoneType_2 = phoneType_2;
} catch (Exception e) {
e.printStackTrace();
}
return teleInfo;
}
/**
* MTK Phone.
* 获取 MTK 神机的双卡 IMSI、IMSI 信息
*/
public static TeleInfo getMtkTeleInfo2(Context context) {
TeleInfo teleInfo = new TeleInfo();
try {
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> phone = Class.forName("com.android.internal.telephony.Phone");
Field fields1 = phone.getField("GEMINI_SIM_1");
fields1.setAccessible(true);
int simId_1 = (Integer) fields1.get(null);
Field fields2 = phone.getField("GEMINI_SIM_2");
fields2.setAccessible(true);
int simId_2 = (Integer) fields2.get(null);
Method getDefault = TelephonyManager.class.getMethod("getDefault", int.class);
TelephonyManager tm1 = (TelephonyManager) getDefault.invoke(manager, simId_1);
TelephonyManager tm2 = (TelephonyManager) getDefault.invoke(manager, simId_2);
String imsi_1 = tm1.getSubscriberId();
String imsi_2 = tm2.getSubscriberId();
teleInfo.imsi_1 = imsi_1;
teleInfo.imsi_2 = imsi_2;
String imei_1 = tm1.getDeviceId();
String imei_2 = tm2.getDeviceId();
teleInfo.imei_1 = imei_1;
teleInfo.imei_2 = imei_2;
int phoneType_1 = tm1.getPhoneType();
int phoneType_2 = tm2.getPhoneType();
teleInfo.phoneType_1 = phoneType_1;
teleInfo.phoneType_2 = phoneType_2;
} catch (Exception e) {
e.printStackTrace();
}
return teleInfo;
}
/**
* Qualcomm Phone.
* 获取 高通 神机的双卡 IMSI、IMSI 信息
*/
public static TeleInfo getQualcommTeleInfo(Context context) {
TeleInfo teleInfo = new TeleInfo();
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> simTMclass = Class.forName("android.telephony.MSimTelephonyManager");
Object sim = context.getSystemService("phone_msim");
int simId_1 = 0;
int simId_2 = 1;
Method getSubscriberId = simTMclass.getMethod("getSubscriberId", int.class);
String imsi_1 = (String) getSubscriberId.invoke(sim, simId_1);
String imsi_2 = (String) getSubscriberId.invoke(sim, simId_2);
teleInfo.imsi_1 = imsi_1;
teleInfo.imsi_2 = imsi_2;
Method getDeviceId = simTMclass.getMethod("getDeviceId", int.class);
String imei_1 = (String) getDeviceId.invoke(sim, simId_1);
String imei_2 = (String) getDeviceId.invoke(sim, simId_2);
teleInfo.imei_1 = imei_1;
teleInfo.imei_2 = imei_2;
Method getDataState = simTMclass.getMethod("getDataState");
int phoneType_1 = tm.getDataState();
int phoneType_2 = (Integer) getDataState.invoke(sim);
teleInfo.phoneType_1 = phoneType_1;
teleInfo.phoneType_2 = phoneType_2;
} catch (Exception e) {
e.printStackTrace();
}
return teleInfo;
}
/**
* Spreadtrum Phone.
* 获取 展讯 神机的双卡 IMSI、IMSI 信息
*/
public static TeleInfo getSpreadtrumTeleInfo(Context context) {
TeleInfo teleInfo = new TeleInfo();
try {
TelephonyManager tm1 = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imsi_1 = tm1.getSubscriberId();
String imei_1 = tm1.getDeviceId();
int phoneType_1 = tm1.getPhoneType();
teleInfo.imsi_1 = imsi_1;
teleInfo.imei_1 = imei_1;
teleInfo.phoneType_1 = phoneType_1;
Class<?> phoneFactory = Class.forName("com.android.internal.telephony.PhoneFactory");
Method getServiceName = phoneFactory.getMethod("getServiceName", String.class, int.class);
getServiceName.setAccessible(true);
String spreadTmService = (String) getServiceName.invoke(phoneFactory, Context.TELEPHONY_SERVICE, 1);
TelephonyManager tm2 = (TelephonyManager) context.getSystemService(spreadTmService);
String imsi_2 = tm2.getSubscriberId();
String imei_2 = tm2.getDeviceId();
int phoneType_2 = tm2.getPhoneType();
teleInfo.imsi_2 = imsi_2;
teleInfo.imei_2 = imei_2;
teleInfo.phoneType_2 = phoneType_2;
} catch (Exception e) {
e.printStackTrace();
}
return teleInfo;
}
}