您的当前位置:首页Android判断模拟器还是真机的方法

Android判断模拟器还是真机的方法

2024-12-13 来源:哗拓教育

作为一个App,我们在做推广的同时,肯定会担心刷量的问题。一般常见的刷量手段就是通过安卓模拟器进行刷量。

那就会想到,怎么判断一个设备是模拟器还是真机。

先吐槽一下,百度上搜出来的都是什么垃圾答案。各种抄袭来的代码,连原理都没讲清楚,或者代码功能都没有实现的,都一篇篇的文章发表在哪里。浪费了我不知道多少时间,真的,我快恶心的不行了。可以吗?能不能有点职业操守,抄代码自己用也就算了,你还当自己的文章发表了,你发表能用也就算了。功能还都是BUG。有没有素质啊。时间很贵的。

下面我把我研究的成果,当然有部分是参考别人的代码提供给大家。

先说思路。

1.那些说用IMei的,Mac值,Device_Id,以及Telephony_Service中的运营商,国家的,什么乱七八糟不靠谱的。首先都是错误的思路。

你们还以为现在的模拟器是Studio上的模拟器吗?求你们写代码之前,先研究一下模拟器的功能。夜神,逍遥,这些模拟器上面明明白白的写着,修改IMEI码,修改设备信息,修改运营商,手机号码等等等等。你和我说通过判断这些信息的默认值。

2.那些不靠谱的去除了,我们该如何去判断呢?

那就要判断一下是不是有什么硬件设备是模拟器上没有的呢?很容易想到的就是蓝牙功能。我们通过获取系统服务获取到蓝牙,判断蓝牙是否存在,然后发现模拟器也有蓝牙。不要慌,获取一下蓝牙的名称发现null。好了。再看看真机的效果。这就出来了。

/**

* 判断蓝牙是否有效来判断是否为模拟器

*

* @return true 为模拟器

*/

public boolean notHasBlueTooth() {

    BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();

    if (ba == null) {

        return true;

    } else {

        // 如果有蓝牙不一定是有效的。获取蓝牙名称,若为null 则默认为模拟器

        String name = ba.getName();

        if (TextUtils.isEmpty(name)) {

            return true;

        } else {

            return false;

        }

    }

}

我在做的时候就考虑,一个蓝牙是否足够!废话,当然不够啦。那还有什么呢?瞬间想到了传感器。温度,重力,光,还有其他一堆。经过测试发现,模拟器上也有很多传感器,同时有部分传感器没有。而在真机上,同样也有部分手机没有温度,压力等传感器。经过一个个的测试选择。我选择了光传感器。

/**

* 判断是否存在光传感器来判断是否为模拟器

* 部分真机也不存在温度和压力传感器。其余传感器模拟器也存在。

* @return true 为模拟器

*/

public static Boolean notHasLightSensorManager(Context context) {

    SensorManager sensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);

    Sensor sensor8 = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); //光

    if (null == sensor8) {

        return true;

    } else {

        return false;

    }

}

既然模拟器都能模拟手机,那是不是模拟器出来的所有设备信息是不是有什么特征呢?通过打印一堆的Device参数。经过网上的参考。就是下面这个代码了。

/**

* 根据部分特征参数设备信息来判断是否为模拟器

*

* @return true 为模拟器

*/

public static boolean isFeatures() {

    return 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);

}

好了,和设备硬件相关的就差不多这几个方法了。那其他方法呢?那模拟器基本上都是运行在电脑上的,电脑的架构是X86。手机正常的是arm的。那是不是可以通过获取CPU来判断呢?基本上就是intel和amd两种吧?

public static String readCpuInfo() {

    String result = "";

    try {

        String[] args = {"/system/bin/cat", "/proc/cpuinfo"};

        ProcessBuilder cmd = new ProcessBuilder(args);

        Process process = cmd.start();

        StringBuffer sb = new StringBuffer();

        String readLine = "";

        BufferedReader responseReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "utf-8"));

        while ((readLine = responseReader.readLine()) != null) {

            sb.append(readLine);

        }

        responseReader.close();

        result = sb.toString().toLowerCase();

    } catch (IOException ex) {

    }

    return result;

}

/**

* 判断cpu是否为电脑来判断 模拟器

*

* @return true 为模拟器

*/

public static boolean checkIsNotRealPhone() {

    String cpuInfo = readCpuInfo();

    if ((cpuInfo.contains("intel") || cpuInfo.contains("amd"))) {

        return true;

    }

    return false;

}

好了,通过以上方法,你可以过滤一大堆的模拟器了。

当然我这些方法只是比较基础了。我在百度谷歌的时候当然也有部分大神的思路。

下面推荐一个通过 (匹配Qemu的一些特征文件以及属性) 来判断。这个我也不会。也没看懂。如果有需要的自己去查看吧。

!!!!!!重要说明!!!!!!!!

经过N台设备测试以及N款模拟器测试。

1.逍遥模拟器竟然可以无视蓝牙检测。所以蓝牙的方法已经失效。

2.还是这个逍遥模拟器,又TMD设备特征参数也已经失效了。

3.所以经过多方测试发现,通过硬件信息去判断模拟器的方法已经失效了。现在唯一比较靠谱的应该就剩这个CPU的检测以及这个光传感器了吧?

4.如果有某位同学测试发现有模拟器可以过CPU检测以及光传感器的麻烦说一下。

5.测试的时候又发现了一个情况。如果你的项目里面加载了so。那就别用CPU检测了,那当然就是ARM的架构了。到了这里,那就只有光传感器了。

如果觉得不放心。那就请同学认真学习下面这篇文章中的关键点。

我们最后的方案也是通过学习这个文章的思想,然后再自己拓展。

在Windows和Mac上测试不同的模拟器,检测出模拟器的有1.逍遥模拟器 2. 蓝叠模拟器 3. 夜神模拟器 4. 靠谱助手 5. 天天模拟器 6. 海马模拟器

通过这几款模拟器的检测,应该能说明这个方案比较可靠。

---------------------

作者:秋名山小尼玛

来源:CSDN

版权声明:本文为博主原创文章,转载请附上博文链接!

显示全文