package com.cheng.utils;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.regex.Pattern;
import javax.security.auth.x500.X500Principal;
/**
* 获取设备有关信息
*/
public class DeviceUtil {
private static String[] kKNOWN_PIPES = {
"/dev/socket/qemud",
"/dev/qemu_pipe"};
private static String[] kKNOWN_QEMU_DRIVERS = { "goldfish" };
private static String[] kKNOWN_FILES = {
"/system/lib/libc_malloc_debug_qemu.so",
"/sys/qemu_trace",
"/system/bin/qemu-props"};
private static String[] kKNOWN_NUMBERS = { "15555215554", "15555215556",
"15555215558", "15555215560", "15555215562", "15555215564",
"15555215566", "15555215568", "15555215570", "15555215572",
"15555215574", "15555215576", "15555215578", "15555215580",
"15555215582", "15555215584"};
private static String[] kKNOWN_IMSI_IDS = {"310260000000000"}; // 默认的 imsi id
private static String[] kKNOWN_DEVICE_IDs = {"000000000000000"}; // 默认ID
public static String getPhoneInfo() {
StringBuilder phoneInfoSB = new StringBuilder();
phoneInfoSB.append("Product: ").append(android.os.Build.PRODUCT);
phoneInfoSB.append(", CPU_ABI: ").append(android.os.Build.CPU_ABI);
phoneInfoSB.append(", TAGS: ").append(android.os.Build.TAGS);
phoneInfoSB.append(", VERSION_CODES.BASE: ").append(android.os.Build.VERSION_CODES.BASE);
phoneInfoSB.append(", MODEL: ").append(android.os.Build.MODEL);
phoneInfoSB.append(", SDK: ").append(android.os.Build.VERSION.SDK_INT);
phoneInfoSB.append(", VERSION.RELEASE: ").append(android.os.Build.VERSION.RELEASE);
phoneInfoSB.append(", DEVICE: ").append(android.os.Build.DEVICE);
phoneInfoSB.append(", DISPLAY: ").append(android.os.Build.DISPLAY);
phoneInfoSB.append(", BRAND: ").append(android.os.Build.BRAND);
phoneInfoSB.append(", BOARD: ").append(android.os.Build.BOARD);
phoneInfoSB.append(", FINGERPRINT: ").append(android.os.Build.FINGERPRINT);
phoneInfoSB.append(", ID: ").append(android.os.Build.ID);
phoneInfoSB.append(", MANUFACTURER: ").append(android.os.Build.MANUFACTURER);
phoneInfoSB.append(", USER: ").append(android.os.Build.USER);
return phoneInfoSB.toString();
}
/**
* 得到CPU核心数
* @return CPU核心数
*/
public static int getNumCores() {
try {
File dir = new File("/sys/devices/system/cpu/");
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (Pattern.matches("cpu[0-9]", pathname.getName())) {
return true;
}
return false;
}
});
return files.length;
} catch (Exception e) {
return 1;
}
}
/**
* 获取手机系统SDK版本
* @return 如API 17 则返回 17
*/
public static int getSDKVersion() {
return android.os.Build.VERSION.SDK_INT;
}
/**
* 是否Dalvik模式
* @return 结果
*/
public static boolean isDalvik() {
return "Dalvik".equals(getCurrentRuntimeValue());
}
/**
* 是否ART模式
* @return 结果
*/
public static boolean isART() {
String currentRuntime = getCurrentRuntimeValue();
return "ART".equals(currentRuntime) || "ART debug build".equals(currentRuntime);
}
/**
* 获取手机当前的Runtime
* @return 正常情况下可能取值Dalvik, ART, ART debug build;
*/
public static String getCurrentRuntimeValue() {
try {
Class<?> systemProperties = Class.forName("android.os.SystemProperties");
try {
Method get = systemProperties.getMethod("get",
String.class, String.class);
if (get == null) {
return "WTF?!";
}
try {
final String value = (String) get.invoke(
systemProperties, "persist.sys.dalvik.vm.lib",
/* Assuming default is */"Dalvik");
if ("libdvm.so".equals(value)) {
return "Dalvik";
} else if ("libart.so".equals(value)) {
return "ART";
} else if ("libartd.so".equals(value)) {
return "ART debug build";
}
return value;
} catch (IllegalAccessException e) {
return "IllegalAccessException";
} catch (IllegalArgumentException e) {
return "IllegalArgumentException";
} catch (InvocationTargetException e) {
return "InvocationTargetException";
}
} catch (NoSuchMethodException e) {
return "SystemProperties.get(String key, String def) method is not found";
}
} catch (ClassNotFoundException e) {
return "SystemProperties class is not found";
}
}
/**
* 获取手机的MIME
* 需要权限 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
* @param context
* @return
*/
private static String mime(Context context) {
String mimeStr = "";
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mimeStr = telephonyManager.getDeviceId();
return mimeStr;
}
/**
* Android ID
* 这个是不靠谱的,因为有时候它是null的,文档中明确说明,如果你恢复了出厂设置,那他就会改变的。而且如果你root了手机,你也可以改变这个ID
* @param context
* @return
*/
private static String androidID(Context context) {
String androidIDStr = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
return androidIDStr;
}
/**
* 获取手机WLAN的MAC地址
* 当没有wifi的时候,是无法获得数据的
* 需要权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
* @param context
* @return
*/
private static String wlanMAC(Context context) {
String wlanMACStr = "";
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wlanMACStr = wifiManager.getConnectionInfo().getMacAddress();
return wlanMACStr;
}
/**
* 蓝牙MAC地址
* 需要权限 <uses-permission android:name="android.permission.BLUETOOTH "/>
* @param context
* @return
*/
private static String bluetoothMAC(Context context) {
String bluetoothMACStr = "";
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothMACStr = bluetoothAdapter.getAddress();
return bluetoothMACStr;
}
/**
* Pseudo-Unique ID
* API >=9:通过“Build.SERIAL”这个属性来保证ID的独一无二
* API < 9:我们可以通过读取设备的ROM版本号、厂商名、CPU型号
* 和其他硬件信息来组合出一串15位的号码,
* 这15位号码有可能重复,但是几率太小了,小到可以忽略
* @param context
* @return
*/
private static String uniquePsuedoID(Context context) {
String serialStr = null;
String devIDShort = "" +
Build.BOARD.length()%10 +
Build.BRAND.length()%10 +
Build.CPU_ABI.length()%10 +
Build.DEVICE.length()%10 +
Build.DISPLAY.length()%10 +
Build.HOST.length()%10 +
Build.ID.length()%10 +
Build.MANUFACTURER.length()%10 +
Build.MODEL.length()%10 +
Build.PRODUCT.length()%10 +
Build.TAGS.length()%10 +
Build.TYPE.length()%10 +
Build.USER.length()%10 ; //13 位
try {
serialStr = android.os.Build.class.getField("SERIAL").get(null).toString();
//API>=9 使用serial号
return new UUID(devIDShort.hashCode(), serialStr.hashCode()).toString();
} catch (Exception exception) {
//serial需要一个初始化
serialStr = "serial"; // 随便一个初始化
}
//使用硬件信息拼凑出来的15位号码
serialStr = new UUID(devIDShort.hashCode(), serialStr.hashCode()).toString();
return serialStr;
}
/**
* 检测是否为模拟器
* @param context
* @return
*/
public static boolean isEmulator(Context context) {
boolean isEmulator =
checkByDeviceIDS(context) ||
checkByEmulatorBuild() ||
checkByPipes() ||
checkByQEmuDriverFile() ||
checkByEmulatorFiles() ||
checkByPhoneNumber(context) ||
checkByImsiIDS(context);
return isEmulator;
}
private static boolean checkByDeviceIDS(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String deviceId = telephonyManager.getDeviceId();
if (TextUtils.isEmpty(deviceId)) {
return true;
}
for (String knowdeviceid : kKNOWN_DEVICE_IDs) {
if (knowdeviceid.equalsIgnoreCase(deviceId)) {
Logger.v("Find ids: 000000000000000!");
return true;
}
}
Logger.v("Not Find ids: 000000000000000!");
return false;
}
/**
* 检测手机上的一些硬件信息
*/
private static boolean checkByEmulatorBuild() {
String BOARD = android.os.Build.BOARD;
String BOOTLOADER = android.os.Build.BOOTLOADER;
String BRAND = android.os.Build.BRAND;
String DEVICE = android.os.Build.DEVICE;
String HARDWARE = android.os.Build.HARDWARE;
String MODEL = android.os.Build.MODEL;
String PRODUCT = android.os.Build.PRODUCT;
if (BOARD == "unknown" || BOOTLOADER == "unknown"
|| BRAND == "generic" || DEVICE == "generic"
|| MODEL == "sdk" || PRODUCT == "sdk"
|| HARDWARE == "goldfish") {
Logger.v("Find Emulator by EmulatorBuild!");
return true;
}
Logger.v("Not Find Emulator by EmulatorBuild!");
return false;
}
/**
* 检测“/dev/socket/qemud”,“/dev/qemu_pipe”这两个通道
*/
private static boolean checkByPipes() {
for (int i = 0; i < kKNOWN_PIPES.length; i++) {
String pipes = kKNOWN_PIPES[i];
File qemusocket = new File(pipes);
if (qemusocket.exists()) {
Logger.v("Find pipes!");
return true;
}
}
Logger.v("Not Find pipes!");
return false;
}
/**
* 检测驱动文件内容
* 读取文件内容,然后检查已知QEmu的驱动程序的列表
*/
private static boolean checkByQEmuDriverFile() {
File driverfile = new File("/proc/tty/drivers");
if (driverfile.exists() && driverfile.canRead()) {
byte[] data = new byte[(int) driverfile.length()];
try {
InputStream inStream = new FileInputStream(driverfile);
inStream.read(data);
inStream.close();
} catch (FileNotFoundException e) {
Logger.e(e);
} catch (IOException e) {
Logger.e(e);
}
String driverdata = new String(data);
for (String known_qemu_driver : kKNOWN_QEMU_DRIVERS) {
if (driverdata.indexOf(known_qemu_driver) != -1) {
Logger.v("Find known_qemu_drivers!");
return true;
}
}
}
Logger.v("Not Find known_qemu_drivers!");
return false;
}
/**
* 检测模拟器上特有的几个文件
*/
private static Boolean checkByEmulatorFiles() {
for (int i = 0; i < kKNOWN_FILES.length; i++) {
String file_name = kKNOWN_FILES[i];
File qemu_file = new File(file_name);
if (qemu_file.exists()) {
Logger.v("Find Emulator Files!");
return true;
}
}
Logger.v("Not Find Emulator Files!");
return false;
}
/**
* 检测模拟器默认的电话号码
*/
private static Boolean checkByPhoneNumber(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
String phonenumber = telephonyManager.getLine1Number();
for (String number : kKNOWN_NUMBERS) {
if (number.equalsIgnoreCase(phonenumber)) {
Logger.v("Find PhoneNumber!");
return true;
}
}
Logger.v("Not Find PhoneNumber!");
return false;
}
/**
* 检测imsi id是不是“310260000000000”
*/
private static Boolean checkByImsiIDS(Context context){
TelephonyManager telephonyManager = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
String imsiid = telephonyManager.getSubscriberId();
for (String knowimsi : kKNOWN_IMSI_IDS) {
if (knowimsi.equalsIgnoreCase(imsiid)) {
Logger.v("Find imsi ids: 310260000000000!");
return true;
}
}
Logger.v("Not Find imsi ids: 310260000000000!");
return false;
}
/**
* 检测手机运营商家
*/
private static boolean CheckOperatorNameAndroid(Context context) {
String szOperatorName = ((TelephonyManager)
context.getSystemService("phone")).getNetworkOperatorName();
if (szOperatorName.toLowerCase().equals("android") == true) {
Logger.v("Find Emulator by OperatorName!");
return true;
}
Logger.v("Not Find Emulator by OperatorName!");
return false;
}
}