Android 判断App运行在模拟器还是真机上的最终解决方案

本文分享了一套针对模拟器的检测方法,通过蓝牙有效性、光传感器存在性、设备特征参数、CPU类型及特有文件的检查,有效防止了模拟器上的作弊行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

        最近公司搞了一波送福利的活动

        被人用模拟器恶意刷注册量了

        后来我经过研究和实测,得出以下方法

        目前还没有发现有模拟器能突破这个检测

        方法如下:

方法使用:

    if(Android_ID_Utils.notHasBlueTooth()
      ||Android_ID_Utils.notHasLightSensorManager(this)
      ||Android_ID_Utils.isFeatures()
      ||Android_ID_Utils.checkIsNotRealPhone()
      ||Android_ID_Utils.checkPipes()){
            ToastUtils.ToastLong(this,"检查到您的设备违规,将限制您的所有功能使用!");
            return;
        }

方法实体:

        2024年11月28日注:

        以下是当时有效的方案,时间过去这么久,不确保一定好使

    /*
     *作者:赵星海
     *时间:2019/2/21 17:50
     *用途:判断蓝牙是否有效来判断是否为模拟器
     *返回:true 为模拟器
     */
    public static 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;
            }
        }
    }

    /*
     *作者:赵星海
     *时间:2019/2/21 17:55
     *用途:依据是否存在光传感器来判断是否为模拟器
     *返回:true 为模拟器
     */
    public static Boolean notHasLightSensorManager(Context context) {
        SensorManager sensorManager = (SensorManager) context.getSystemService(context.SENSOR_SERVICE);
        Sensor sensor8 = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); //光
        if (null == sensor8) {
            return true;
        } else {
            return false;
        }
    }

    /*
     *作者:赵星海
     *时间:2019/2/21 17:56
     *用途:根据部分特征参数设备信息来判断是否为模拟器
     *返回: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);
    }

    /*
     *作者:赵星海
     *时间:2019/2/21 17:58
     *用途:根据CPU是否为电脑来判断是否为模拟器
     *返回:true 为模拟器
     */
    public static boolean checkIsNotRealPhone() {
        String cpuInfo = readCpuInfo();
        if ((cpuInfo.contains("intel") || cpuInfo.contains("amd"))) {
            return true;
        }
        return false;
    }
    /*
     *作者:赵星海
     *时间:2019/2/21 17:58
     *用途:根据CPU是否为电脑来判断是否为模拟器(子方法)
     *返回:String
     */
    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;
    }

    /*
     *作者:赵星海
     *时间:2019/2/21 17:50
     *用途:检测模拟器的特有文件
     *返回:true 为模拟器
     */
    private static String[] known_pipes = {"/dev/socket/qemud", "/dev/qemu_pipe"};
    public static boolean checkPipes() {
        for (int i = 0; i < known_pipes.length; i++) {
            String pipes = known_pipes[i];
            File qemu_socket = new File(pipes);
            if (qemu_socket.exists()) {
                Log.v("Result:", "Find pipes!");
                return true;
            }
        }
        Log.i("Result:", "Not Find pipes!");
        return false;
    }    


更多内容推荐:
https://blog.csdn.net/qq_39731011/category_7565212.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=7565212&sharerefer=PC&sharesource=qq_39731011&sharefrom=from_linkicon-default.png?t=O83Ahttps://blog.csdn.net/qq_39731011/category_7565212.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=7565212&sharerefer=PC&sharesource=qq_39731011&sharefrom=from_link


  •         如果您有什么建议的话,欢迎留言评论.谢谢.
  •         如果深海写的东西对您有用,请您给该博客点个赞吧
  •         大家的支持就是深海写博客的动力,谢过各位

评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵星海(深海呐)

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值