本篇主要的工具类有: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; } }