Android开发关于鉴定设备是否是模拟器的问题

近期需要鉴定设备是否是模拟器,从网上看了下大部分的方法是不准确的,也可能是测试环境的原因, 这些包括

1.检测模拟器的特有文件

2.检测设备的驱动

3.检测手机的一些硬件

4.检测手机的运营商家

5.检测模拟器的默认号码

6.检测设备的imsi ID

代码如下

 

public class MainActivity extends Activity {

    private TextView tv;

    private static String[] known_files = {
            "/system/lib/libc_malloc_debug_qemu.so", "/sys/qemu_trace",
            "/system/bin/qemu-props"};
    private static String[] known_pipes = {
            "/dev/socket/qemud",
            "/dev/qemu_pipe"
    };

    private static String[] known_numbers = {"15555215554", "15555215556",
            "15555215558", "15555215560", "15555215562", "15555215564",
            "15555215566", "15555215568", "15555215570", "15555215572",
            "15555215574", "15555215576", "15555215578", "15555215580",
            "15555215582", "15555215584",};
    private static String[] known_imsi_ids = {"310260000000000", // 默认的 imsi id
            "460076067205994",// 夜神模拟器
            "460001067113753"// 雷电模拟器
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 10002121);
        }
        tv = findViewById(R.id.main_text);
        tv.setText("检测模拟器上特有的几个文件\n");
        CheckEmulatorFiles();
        tv.append("\n检测驱动文件内容\n");
        checkQEmuDriverFile();
        tv.append("\n检测手机上的一些硬件信息\n");
        CheckEmulatorBuild();
        tv.append("\n检测手机运营商家\n");
        CheckOperatorNameAndroid(this);
        tv.append("\n检测模拟器默认的电话号码\n");
        CheckPhoneNumber();
        tv.append("\n检测imsi id\n");
        CheckImsiIDS();
    }

    // 检测模拟器上特有的几个文件
    public Boolean CheckEmulatorFiles() {
        for (int i = 0; i < known_files.length; i++) {
            String file_name = known_files[i];
            File qemu_file = new File(file_name);
            if (qemu_file.exists()) {
                tv.append("Emulator\n");
                return true;
            }
        }
        tv.append("Not Find Emulator Files\n");
        return false;
    }

    //检测手机上的一些硬件信息
    public Boolean CheckEmulatorBuild() {
        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") {
            tv.append("Emulator\n");
            return true;
        }
        tv.append("Not Find Emulator by EmulatorBuild\n");
        return false;
    }

    //检测手机运营商家
    @SuppressLint("WrongConstant")
    public boolean CheckOperatorNameAndroid(Context context) {
        String szOperatorName = ((TelephonyManager) context.getSystemService("phone")).getNetworkOperatorName();

        if (szOperatorName.toLowerCase().equals("android") == true) {
            tv.append("Emulator\n");
            return true;
        }
        tv.append("Not Find Emulator by OperatorName\n");
        return false;
    }

    // 检测驱动文件内容
    // 读取文件内容,然后检查已知QEmu的驱动程序的列表
    public Boolean checkQEmuDriverFile() {
        File driver_file = new File("/proc/tty/drivers");
        if (driver_file.exists() && driver_file.canRead()) {
            byte[] data = new byte[1024];  //(int)driver_file.length()
            try {
                InputStream inStream = new FileInputStream(driver_file);
                inStream.read(data);
                inStream.close();
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
            String driver_data = new String(data);
            for (String known_qemu_driver : known_pipes) {
                if (driver_data.indexOf(known_qemu_driver) != -1) {
                    tv.append("Emulator\n");
                    return true;
                }
            }
        }
        tv.append("Not Find known_qemu_drivers\n");
        return false;
    }

    // 检测模拟器默认的电话号码
    @SuppressLint("MissingPermission")
    public Boolean CheckPhoneNumber() {
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

        String phonenumber = telephonyManager.getLine1Number();

        for (String number : known_numbers) {
            if (number.equalsIgnoreCase(phonenumber)) {
                tv.append("Emulator\n");
                return true;
            }
        }
        tv.append("Not Find PhoneNumber\n");
        return false;
    }

    // 检测imsi id是不是“310260000000000”
    public Boolean CheckImsiIDS() {
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

        @SuppressLint("MissingPermission") String imsi_ids = telephonyManager.getSubscriberId();

        for (String know_imsi : known_imsi_ids) {
            if (know_imsi.equalsIgnoreCase(imsi_ids)) {
                tv.append("Emulator\n");
                return true;
            }
        }
        tv.append("Not Find imsi ids\n");
        return false;
    }
}

其中方法1在部分模拟器上生效,2.3.4.5全部失效,6只有在知道模拟器的imsi ID时,将其放入比对的数组中才会生效

雷电模拟器的运行结果如下

Android开发关于鉴定设备是否是模拟器的问题_第1张图片

夜神模拟器的如下

Android开发关于鉴定设备是否是模拟器的问题_第2张图片

联想A8手机如下

Android开发关于鉴定设备是否是模拟器的问题_第3张图片

VIVO_X21如下

Android开发关于鉴定设备是否是模拟器的问题_第4张图片

 

你可能感兴趣的:(Android开发)