简单粗暴识别工作室Android识别模拟器

最近有项目需要设备模拟器,此贴用来记录我识别模拟器的方法:

目前还没有发现安卓8.0以上的模拟器,所以可以通过判断设备安卓版本号,过滤>=8.0的设备(默认为真机)


可以从安卓8.0 以下,通过以下几个方面判断:

//Android 8.0 版本以上,不做模拟器判断
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){



}

1、通过能否打电话来判断模拟器:

String url = "tel:" + "10086";
        Intent intent = new Intent();
        intent.setData(Uri.parse(url));
        intent.setAction(Intent.ACTION_DIAL);
        // 隐示意图跳转到打电话界面 Intent (检查是否存在)
        boolean canResolverIntent = intent.resolveActivity(context.getPackageManager()) != null;

canResolverIntent ==true,可以打电话,判断为真机。

目前主流模拟器都没有打电话这个功能:

这个来判断基本可以ban掉很多模拟器了

2、通过cpu来判断:

基本x86可以判定为模拟器

Build.MODEL.contains("x86")
android.os.Build.CPU_ABI.contains("x86")

3、第三通传感器来判断:例如:光传感器,方向传感器。

/**
 * 判断是否存在光传感器来判断是否为模拟器 部分真机也不存在温度和压力传感器。其余传感器模拟器也存在。
 *
 * @return true 为模拟器
 */
public int notHasLightSensorManager(Context context) {
    SensorManager sensorManager = (SensorManager) context
            .getSystemService(Context.SENSOR_SERVICE);
    Sensor sensor8 = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); // 光
    if (null == sensor8) {
        Log.i("", "光传感器判定为false");
        return 0;
    } else {
        Log.i("", "光传感器判定为true");
        return 1;
    }
}

写在最后:

手机是否安装QQ、微信、支付宝、淘宝、抖音、快手 等常用APP,也可以作为一个筛选条件。

已经root 的机器,再过滤一遍。

模拟器识别与判断,判定结果最好在服务端实现。


附上代码

package com.sdk.inner.utils;

import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.sdk.inner.log.LogUtil;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

public class EmulatorUtils {

    public static boolean isEmulator = false;

    /**
     * 判断是否存在光传感器来判断是否为模拟器 部分真机也不存在温度和压力传感器。其余传感器模拟器也存在。
     *
     * @return true 为模拟器
     */
    public static boolean hasLightSensorManager(Context context) {
        SensorManager sensorManager = (SensorManager) context
                .getSystemService(Context.SENSOR_SERVICE);
        Sensor sensor8 = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); // 光
        if (null == sensor8) {
            Log.i("", "光传感器判定为false");
            LogUtil.d("is_emulator:hasLightSensorManager = "+false);

            return false;
        } else {
            Log.i("", "光传感器判定为true");
            LogUtil.d("is_emulator:hasLightSensorManager = "+true);

            return true;
        }
    }

    /**
     * 是否模拟器、
     *
     * @return true 为模拟器
     */
    public static void checkSimulator(Context context) {

        boolean isX86 = Build.MODEL.contains("x86");
        boolean isX86_1 = android.os.Build.CPU_ABI.contains("x86");

        //Android 8.0 版本以上,不做模拟器判断
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){

            LogUtil.d("is_emulator:SDK_INT = "+Build.VERSION.SDK_INT);

            isEmulator=false;
        }else {

            if(isX86 || isX86_1){
                LogUtil.d("is_emulator:isX86 = "+isX86+" isX86_1="+isX86_1);

                isEmulator = true;
            }
            //安卓8以下,检查root
            else if(isRoot()){
                isEmulator = true;
            }
            else if(!hasLightSensorManager(context)){
                isEmulator = true;
            }else if(!canCallPhone(context)){
                isEmulator = true;
            }

            else if(ifFeatures()){
                LogUtil.d("is_emulator:ifFeatures = "+true);

                isEmulator = true;
            }
            //安卓8以下,检查app安装
            else if(!checkInstallNeedApk(context)){
                isEmulator = true;
            }

            else {
                isEmulator = false;
            }
        }

//        Toast.makeText(context,"is_emulator=:"+isEmulator,Toast.LENGTH_SHORT).show();
        LogUtil.d("is_emulator=:"+isEmulator);

    }


    public static boolean canCallPhone(Context context){
        String url = "tel:" + "10086";
        Intent intent = new Intent();
        intent.setData(Uri.parse(url));
        intent.setAction(Intent.ACTION_DIAL);

        // 隐示意图跳转到打电话界面 Intent (检查是否存在)
        boolean canResolverIntent = intent.resolveActivity(context.getPackageManager()) != null;
        LogUtil.d("is_emulator:canCallPhone = "+canResolverIntent);
        return canResolverIntent;
    }

    /**
     * 根据部分特征参数设备信息来判断是否为模拟器
     * @return
     */
    private static boolean ifFeatures(){
        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);
    }

    public static boolean checkInstallNeedApk(Context context){


        LogUtil.d("Build.VERSION.SDK_INT = "+Build.VERSION.SDK_INT+"支付宝:"+isAliPayInstalled(context) +" 微信:"+isWeixinAvilible(context)+" qq:"+isQQClientAvailable(context));
        return isAliPayInstalled(context)||isWeixinAvilible(context)||isQQClientAvailable(context);

    }

    /**
     * 检测是否安装支付宝
     * @param context
     * @return
     */
    public static boolean isAliPayInstalled(Context context) {
        Uri uri = Uri.parse("alipays://platformapi/startApp");
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        ComponentName componentName = intent.resolveActivity(context.getPackageManager());
        return componentName != null;
    }

    /**
     * 检测是否安装微信
     * @param context
     * @return
     */
    public static boolean isWeixinAvilible(Context context) {
        final PackageManager packageManager = context.getPackageManager();// 获取packagemanager
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// 获取所有已安装程序的包信息
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pn = pinfo.get(i).packageName;
                if (pn.equals("com.tencent.mm")) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 判断是否安装了QQ
     *
     * @param context
     * @return
     */
    public static boolean isQQClientAvailable(Context context) {
        final PackageManager packageManager = context.getPackageManager();
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pn = pinfo.get(i).packageName;
                if (pn.equals("com.tencent.mobileqq")) {
                    return true;
                }
            }
        }
        return false;
    }


    //是否root
    public static boolean isRoot() {
        boolean root = false;
        if (new File("/system/bin/su").exists() && isCanExecute("/system/bin/su")) {
            root = true;
        }
        if (new File("/system/xbin/su").exists() && isCanExecute("/system/xbin/su")) {
            root = true;
        }
        LogUtil.d("is_emulator:是否root = "+root);
        return root;
    }

    private static boolean isCanExecute(String filePath) {
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("ls -l " + filePath);
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String str = in.readLine();
            if (str != null && str.length() >= 4) {
                char flag = str.charAt(3);
                if (flag == 's' || flag == 'x')
                    return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
        return false;
    }


}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值