package com.blankj.utilcode.util; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Build; import android.provider.Settings; import android.support.annotation.RequiresApi; import android.support.annotation.RequiresPermission; import android.telephony.TelephonyManager; import android.text.TextUtils; import java.io.File; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; import java.util.UUID; import static android.Manifest.permission.ACCESS_WIFI_STATE; import static android.Manifest.permission.INTERNET; import static android.content.Context.WIFI_SERVICE; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2016/8/1
 *     desc  : utils about device
 * 
*/ public final class DeviceUtils { private DeviceUtils() { throw new UnsupportedOperationException("u can't instantiate me..."); } /** * Return whether device is rooted. * * @return {@code true}: yes
{@code false}: no */ public static boolean isDeviceRooted() { String su = "su"; String[] locations = {"/system/bin/", "/system/xbin/", "/sbin/", "/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/xbin/", "/data/local/bin/", "/data/local/", "/system/sbin/", "/usr/bin/", "/vendor/bin/"}; for (String location : locations) { if (new File(location + su).exists()) { return true; } } return false; } /** * Return whether ADB is enabled. * * @return {@code true}: yes
{@code false}: no */ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) public static boolean isAdbEnabled() { return Settings.Secure.getInt( Utils.getApp().getContentResolver(), Settings.Global.ADB_ENABLED, 0 ) > 0; } /** * Return the version name of device's system. * * @return the version name of device's system */ public static String getSDKVersionName() { return android.os.Build.VERSION.RELEASE; } /** * Return version code of device's system. * * @return version code of device's system */ public static int getSDKVersionCode() { return android.os.Build.VERSION.SDK_INT; } /** * Return the android id of device. * * @return the android id of device */ @SuppressLint("HardwareIds") public static String getAndroidID() { String id = Settings.Secure.getString( Utils.getApp().getContentResolver(), Settings.Secure.ANDROID_ID ); if ("9774d56d682e549c".equals(id)) return ""; return id == null ? "" : id; } /** * Return the MAC address. *

Must hold {@code }, * {@code }

* * @return the MAC address */ @RequiresPermission(allOf = {ACCESS_WIFI_STATE, INTERNET}) public static String getMacAddress() { String macAddress = getMacAddress((String[]) null); if (!macAddress.equals("") || getWifiEnabled()) return macAddress; setWifiEnabled(true); setWifiEnabled(false); return getMacAddress((String[]) null); } private static boolean getWifiEnabled() { @SuppressLint("WifiManagerLeak") WifiManager manager = (WifiManager) Utils.getApp().getSystemService(WIFI_SERVICE); if (manager == null) return false; return manager.isWifiEnabled(); } private static void setWifiEnabled(final boolean enabled) { @SuppressLint("WifiManagerLeak") WifiManager manager = (WifiManager) Utils.getApp().getSystemService(WIFI_SERVICE); if (manager == null) return; manager.setWifiEnabled(enabled); } /** * Return the MAC address. *

Must hold {@code }, * {@code }

* * @return the MAC address */ @RequiresPermission(allOf = {ACCESS_WIFI_STATE, INTERNET}) public static String getMacAddress(final String... excepts) { String macAddress = getMacAddressByNetworkInterface(); if (isAddressNotInExcepts(macAddress, excepts)) { return macAddress; } macAddress = getMacAddressByInetAddress(); if (isAddressNotInExcepts(macAddress, excepts)) { return macAddress; } macAddress = getMacAddressByWifiInfo(); if (isAddressNotInExcepts(macAddress, excepts)) { return macAddress; } macAddress = getMacAddressByFile(); if (isAddressNotInExcepts(macAddress, excepts)) { return macAddress; } return ""; } private static boolean isAddressNotInExcepts(final String address, final String... excepts) { if (excepts == null || excepts.length == 0) { return !"02:00:00:00:00:00".equals(address); } for (String filter : excepts) { if (address.equals(filter)) { return false; } } return true; } @SuppressLint({"MissingPermission", "HardwareIds"}) private static String getMacAddressByWifiInfo() { try { final WifiManager wifi = (WifiManager) Utils.getApp() .getApplicationContext().getSystemService(WIFI_SERVICE); if (wifi != null) { final WifiInfo info = wifi.getConnectionInfo(); if (info != null) return info.getMacAddress(); } } catch (Exception e) { e.printStackTrace(); } return "02:00:00:00:00:00"; } private static String getMacAddressByNetworkInterface() { try { Enumeration nis = NetworkInterface.getNetworkInterfaces(); while (nis.hasMoreElements()) { NetworkInterface ni = nis.nextElement(); if (ni == null || !ni.getName().equalsIgnoreCase("wlan0")) continue; byte[] macBytes = ni.getHardwareAddress(); if (macBytes != null && macBytes.length > 0) { StringBuilder sb = new StringBuilder(); for (byte b : macBytes) { sb.append(String.format("%02x:", b)); } return sb.substring(0, sb.length() - 1); } } } catch (Exception e) { e.printStackTrace(); } return "02:00:00:00:00:00"; } private static String getMacAddressByInetAddress() { try { InetAddress inetAddress = getInetAddress(); if (inetAddress != null) { NetworkInterface ni = NetworkInterface.getByInetAddress(inetAddress); if (ni != null) { byte[] macBytes = ni.getHardwareAddress(); if (macBytes != null && macBytes.length > 0) { StringBuilder sb = new StringBuilder(); for (byte b : macBytes) { sb.append(String.format("%02x:", b)); } return sb.substring(0, sb.length() - 1); } } } } catch (Exception e) { e.printStackTrace(); } return "02:00:00:00:00:00"; } private static InetAddress getInetAddress() { try { Enumeration nis = NetworkInterface.getNetworkInterfaces(); while (nis.hasMoreElements()) { NetworkInterface ni = nis.nextElement(); // To prevent phone of xiaomi return "10.0.2.15" if (!ni.isUp()) continue; Enumeration addresses = ni.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress inetAddress = addresses.nextElement(); if (!inetAddress.isLoopbackAddress()) { String hostAddress = inetAddress.getHostAddress(); if (hostAddress.indexOf(':') < 0) return inetAddress; } } } } catch (SocketException e) { e.printStackTrace(); } return null; } private static String getMacAddressByFile() { ShellUtils.CommandResult result = ShellUtils.execCmd("getprop wifi.interface", false); if (result.result == 0) { String name = result.successMsg; if (name != null) { result = ShellUtils.execCmd("cat /sys/class/net/" + name + "/address", false); if (result.result == 0) { String address = result.successMsg; if (address != null && address.length() > 0) { return address; } } } } return "02:00:00:00:00:00"; } /** * Return the manufacturer of the product/hardware. *

e.g. Xiaomi

* * @return the manufacturer of the product/hardware */ public static String getManufacturer() { return Build.MANUFACTURER; } /** * Return the model of device. *

e.g. MI2SC

* * @return the model of device */ public static String getModel() { String model = Build.MODEL; if (model != null) { model = model.trim().replaceAll("\\s*", ""); } else { model = ""; } return model; } /** * Return an ordered list of ABIs supported by this device. The most preferred ABI is the first * element in the list. * * @return an ordered list of ABIs supported by this device */ public static String[] getABIs() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { return Build.SUPPORTED_ABIS; } else { if (!TextUtils.isEmpty(Build.CPU_ABI2)) { return new String[]{Build.CPU_ABI, Build.CPU_ABI2}; } return new String[]{Build.CPU_ABI}; } } /** * Return whether device is tablet. * * @return {@code true}: yes
{@code false}: no */ public static boolean isTablet() { return (Utils.getApp().getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; } /** * Return whether device is emulator. * * @return {@code true}: yes
{@code false}: no */ public static boolean isEmulator() { boolean checkProperty = Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.toLowerCase().contains("vbox") || Build.FINGERPRINT.toLowerCase().contains("test-keys") || Build.MODEL.contains("google_sdk") || Build.MODEL.contains("Emulator") || Build.MODEL.contains("Android SDK built for x86") || Build.MANUFACTURER.contains("Genymotion") || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) || "google_sdk".equals(Build.PRODUCT); if (checkProperty) return true; String operatorName = ""; TelephonyManager tm = (TelephonyManager) Utils.getApp().getSystemService(Context.TELEPHONY_SERVICE); if (tm != null) { String name = tm.getNetworkOperatorName(); if (name != null) { operatorName = name; } } boolean checkOperatorName = operatorName.toLowerCase().equals("android"); if (checkOperatorName) return true; String url = "tel:" + "123456"; Intent intent = new Intent(); intent.setData(Uri.parse(url)); intent.setAction(Intent.ACTION_DIAL); boolean checkDial = intent.resolveActivity(Utils.getApp().getPackageManager()) == null; if (checkDial) return true; // boolean checkDebuggerConnected = Debug.isDebuggerConnected(); // if (checkDebuggerConnected) return true; return false; } private static final String KEY_UDID = "KEY_UDID"; private volatile static String udid; /** * Return the unique device id. *
{1}{UUID(macAddress)}
*
{2}{UUID(deviceId  )}
*
{3}{UUID(androidId )}
*
{4}{UUID(random    )}
* * @return the unique device id */ @SuppressLint({"MissingPermission", "HardwareIds"}) public static String getUniqueDeviceId() { return getUniqueDeviceId(""); } /** * Return the unique device id. *
{prefix}{1}{UUID(macAddress)}
*
{prefix}{2}{UUID(deviceId  )}
*
{prefix}{3}{UUID(androidId )}
*
{prefix}{4}{UUID(random    )}
* * @param prefix The prefix of the unique device id. * @return the unique device id */ @SuppressLint({"MissingPermission", "HardwareIds"}) public static String getUniqueDeviceId(String prefix) { if (udid == null) { synchronized (DeviceUtils.class) { if (udid == null) { final String id = Utils.getSpUtils4Utils().getString(KEY_UDID, null); if (id != null) { udid = id; return udid; } try { String macAddress = getMacAddress(); if (!macAddress.equals("")) { return saveUdid(prefix + 1, macAddress); } final String androidId = getAndroidID(); if (!TextUtils.isEmpty(androidId)) { return saveUdid(prefix + 2, androidId); } final String deviceId = ((TelephonyManager) Utils.getApp().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId(); if (!TextUtils.isEmpty(deviceId)) { return saveUdid(prefix + 3, deviceId); } } catch (Exception ignore) {/**/} return saveUdid(prefix + 4, ""); } } } return udid; } @SuppressLint({"MissingPermission", "HardwareIds"}) public static boolean isSameDevice(final String uniqueDeviceId) { // {prefix}{type}{32id} if (TextUtils.isEmpty(uniqueDeviceId) && uniqueDeviceId.length() < 33) return false; if (uniqueDeviceId.equals(udid)) return true; final String cachedId = Utils.getSpUtils4Utils().getString(KEY_UDID, null); if (uniqueDeviceId.equals(cachedId)) return true; int st = uniqueDeviceId.length() - 33; String type = uniqueDeviceId.substring(st, st + 1); if (type.startsWith("1")) { String macAddress = getMacAddress(); if (macAddress.equals("")) { return false; } return uniqueDeviceId.substring(st + 1).equals(getUdid("", macAddress)); } else if (type.startsWith("2")) { final String androidId = getAndroidID(); if (TextUtils.isEmpty(androidId)) { return false; } return uniqueDeviceId.substring(st + 1).equals(getUdid("", androidId)); } else if (type.startsWith("3")) { final String deviceId = ((TelephonyManager) Utils.getApp().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId(); if (TextUtils.isEmpty(deviceId)) { return false; } return uniqueDeviceId.substring(st + 1).equals(getUdid("", deviceId)); } return false; } private static String saveUdid(String prefix, String id) { udid = getUdid(prefix, id); SPUtils.getInstance().put(KEY_UDID, udid); return udid; } private static String getUdid(String prefix, String id) { if (id.equals("")) { return prefix + UUID.randomUUID().toString().replace("-", ""); } return prefix + UUID.nameUUIDFromBytes(id.getBytes()).toString().replace("-", ""); } }