android cocoscreator 检测模拟器还是真机

转载至 一行代码帮你检测Android模拟器   

具体原理看原博主文章,这里只讲cocoscreator3.6的安卓工程怎么使用

1.新建一个com.lahm.library包,和com.cocos.game同目录,如图示

那四个文件的代码如下:

EmulatorCheckUtil类,检测模拟器和真机的工具类,是入口:
package com.lahm.library;import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.text.TextUtils;
import android.util.Log;import com.facebook.internal.LockOnGetVariable;import static android.content.Context.SENSOR_SERVICE;
import static com.lahm.library.CheckResult.RESULT_EMULATOR;
import static com.lahm.library.CheckResult.RESULT_MAYBE_EMULATOR;
import static com.lahm.library.CheckResult.RESULT_UNKNOWN;/*** Project Name:检查是否是模拟器* Package Name:com.lahm.library* Created by lahm on 2018/6/8 15:01 .*/
public class EmulatorCheckUtil {private static String TAG = "EmulatorCheckUtil:";private EmulatorCheckUtil() {}private static class SingletonHolder {private static final EmulatorCheckUtil INSTANCE = new EmulatorCheckUtil();}public static final EmulatorCheckUtil getSingleInstance() {return SingletonHolder.INSTANCE;}public boolean readSysProperty(Context context, EmulatorCheckCallback callback) {if (context == null)throw new IllegalArgumentException("context must not be null");int suspectCount = 0;//检测硬件名称CheckResult hardwareResult = checkFeaturesByHardware();switch (hardwareResult.result) {case RESULT_MAYBE_EMULATOR:++suspectCount;break;case RESULT_EMULATOR:if (callback != null) callback.findEmulator("hardware = " + hardwareResult.value);return true;}//检测渠道CheckResult flavorResult = checkFeaturesByFlavor();switch (flavorResult.result) {case RESULT_MAYBE_EMULATOR:++suspectCount;break;case RESULT_EMULATOR:if (callback != null) callback.findEmulator("flavor = " + flavorResult.value);return true;}//检测设备型号CheckResult modelResult = checkFeaturesByModel();switch (modelResult.result) {case RESULT_MAYBE_EMULATOR:++suspectCount;break;case RESULT_EMULATOR:if (callback != null) callback.findEmulator("model = " + modelResult.value);return true;}//检测硬件制造商CheckResult manufacturerResult = checkFeaturesByManufacturer();switch (manufacturerResult.result) {case RESULT_MAYBE_EMULATOR:++suspectCount;break;case RESULT_EMULATOR:if (callback != null)callback.findEmulator("manufacturer = " + manufacturerResult.value);return true;}//检测主板名称CheckResult boardResult = checkFeaturesByBoard();switch (boardResult.result) {case RESULT_MAYBE_EMULATOR:++suspectCount;break;case RESULT_EMULATOR:if (callback != null) callback.findEmulator("board = " + boardResult.value);return true;}//检测主板平台CheckResult platformResult = checkFeaturesByPlatform();switch (platformResult.result) {case RESULT_MAYBE_EMULATOR:++suspectCount;break;case RESULT_EMULATOR:if (callback != null) callback.findEmulator("platform = " + platformResult.value);return true;}//检测基带信息CheckResult baseBandResult = checkFeaturesByBaseBand();switch (baseBandResult.result) {case RESULT_MAYBE_EMULATOR:suspectCount += 2;//模拟器基带信息为null的情况概率相当大break;case RESULT_EMULATOR:if (callback != null) callback.findEmulator("baseBand = " + baseBandResult.value);return true;}//检测传感器数量int sensorNumber = getSensorNumber(context);if (sensorNumber <= 7) ++suspectCount;//检测已安装第三方应用数量int userAppNumber = getUserAppNumber();if (userAppNumber <= 5) ++suspectCount;//检测是否支持闪光灯boolean supportCameraFlash = supportCameraFlash(context);if (!supportCameraFlash) ++suspectCount;//检测是否支持相机boolean supportCamera = supportCamera(context);if (!supportCamera) ++suspectCount;//检测是否支持蓝牙boolean supportBluetooth = supportBluetooth(context);if (!supportBluetooth) ++suspectCount;//检测光线传感器boolean hasLightSensor = hasLightSensor(context);if (!hasLightSensor) ++suspectCount;//检测进程组信息CheckResult cgroupResult = checkFeaturesByCgroup();if (cgroupResult.result == RESULT_MAYBE_EMULATOR) ++suspectCount;if (callback != null) {StringBuffer stringBuffer = new StringBuffer("Test start").append("\r\n").append("hardware = ").append(hardwareResult.value).append("\r\n").append("flavor = ").append(flavorResult.value).append("\r\n").append("model = ").append(modelResult.value).append("\r\n").append("manufacturer = ").append(manufacturerResult.value).append("\r\n").append("board = ").append(boardResult.value).append("\r\n").append("platform = ").append(platformResult.value).append("\r\n").append("baseBand = ").append(baseBandResult.value).append("\r\n").append("sensorNumber = ").append(sensorNumber).append("\r\n").append("userAppNumber = ").append(userAppNumber).append("\r\n").append("supportCamera = ").append(supportCamera).append("\r\n").append("supportCameraFlash = ").append(supportCameraFlash).append("\r\n").append("supportBluetooth = ").append(supportBluetooth).append("\r\n").append("hasLightSensor = ").append(hasLightSensor).append("\r\n").append("cgroupResult = ").append(cgroupResult.value).append("\r\n").append("suspectCount = ").append(suspectCount);callback.findEmulator(stringBuffer.toString());}Log.i(TAG, "EmulatorCheck suspectCount:" + suspectCount);//嫌疑值大于3,认为是模拟器return suspectCount >= 3;}private int getUserAppNum(String userApps) {if (TextUtils.isEmpty(userApps)) return 0;String[] result = userApps.split("package:");return result.length;}private String getProperty(String propName) {String property = CommandUtil.getSingleInstance().getProperty(propName);return TextUtils.isEmpty(property) ? null : property;}/*** 特征参数-硬件名称** @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机*/private CheckResult checkFeaturesByHardware() {String hardware = getProperty("ro.hardware");if (null == hardware) return new CheckResult(RESULT_MAYBE_EMULATOR, null);int result;String tempValue = hardware.toLowerCase();switch (tempValue) {case "ttvm"://天天模拟器case "nox"://夜神模拟器case "cancro"://网易MUMU模拟器case "intel"://逍遥模拟器case "vbox":case "vbox86"://腾讯手游助手case "android_x86"://雷电模拟器result = RESULT_EMULATOR;break;default:result = RESULT_UNKNOWN;break;}return new CheckResult(result, hardware);}/*** 特征参数-渠道** @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机*/private CheckResult checkFeaturesByFlavor() {String flavor = getProperty("ro.build.flavor");if (null == flavor) return new CheckResult(RESULT_MAYBE_EMULATOR, null);int result;String tempValue = flavor.toLowerCase();if (tempValue.contains("vbox")) result = RESULT_EMULATOR;else if (tempValue.contains("sdk_gphone")) result = RESULT_EMULATOR;else result = RESULT_UNKNOWN;return new CheckResult(result, flavor);}/*** 特征参数-设备型号** @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机*/private CheckResult checkFeaturesByModel() {String model = getProperty("ro.product.model");if (null == model) return new CheckResult(RESULT_MAYBE_EMULATOR, null);int result;String tempValue = model.toLowerCase();if (tempValue.contains("google_sdk")) result = RESULT_EMULATOR;else if (tempValue.contains("emulator")) result = RESULT_EMULATOR;else if (tempValue.contains("android sdk built for x86")) result = RESULT_EMULATOR;else result = RESULT_UNKNOWN;return new CheckResult(result, model);}/*** 特征参数-硬件制造商** @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机*/private CheckResult checkFeaturesByManufacturer() {String manufacturer = getProperty("ro.product.manufacturer");if (null == manufacturer) return new CheckResult(RESULT_MAYBE_EMULATOR, null);int result;String tempValue = manufacturer.toLowerCase();if (tempValue.contains("genymotion")) result = RESULT_EMULATOR;else if (tempValue.contains("netease")) result = RESULT_EMULATOR;//网易MUMU模拟器else result = RESULT_UNKNOWN;return new CheckResult(result, manufacturer);}/*** 特征参数-主板名称** @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机*/private CheckResult checkFeaturesByBoard() {String board = getProperty("ro.product.board");if (null == board) return new CheckResult(RESULT_MAYBE_EMULATOR, null);int result;String tempValue = board.toLowerCase();if (tempValue.contains("android")) result = RESULT_EMULATOR;else if (tempValue.contains("goldfish")) result = RESULT_EMULATOR;else result = RESULT_UNKNOWN;return new CheckResult(result, board);}/*** 特征参数-主板平台** @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机*/private CheckResult checkFeaturesByPlatform() {String platform = getProperty("ro.board.platform");if (null == platform) return new CheckResult(RESULT_MAYBE_EMULATOR, null);int result;String tempValue = platform.toLowerCase();if (tempValue.contains("android")) result = RESULT_EMULATOR;else result = RESULT_UNKNOWN;return new CheckResult(result, platform);}/*** 特征参数-基带信息** @return 0表示可能是模拟器,1表示模拟器,2表示可能是真机*/private CheckResult checkFeaturesByBaseBand() {String baseBandVersion = getProperty("gsm.version.baseband");if (null == baseBandVersion) return new CheckResult(RESULT_MAYBE_EMULATOR, null);int result;if (baseBandVersion.contains("1.0.0.0")) result = RESULT_EMULATOR;else result = RESULT_UNKNOWN;return new CheckResult(result, baseBandVersion);}/*** 获取传感器数量*/private int getSensorNumber(Context context) {SensorManager sm = (SensorManager) context.getSystemService(SENSOR_SERVICE);return sm.getSensorList(Sensor.TYPE_ALL).size();}/*** 获取已安装第三方应用数量*/private int getUserAppNumber() {String userApps = CommandUtil.getSingleInstance().exec("pm list package -3");return getUserAppNum(userApps);}/*** 是否支持相机*/private boolean supportCamera(Context context) {return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);}/*** 是否支持闪光灯*/private boolean supportCameraFlash(Context context) {return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);}/*** 是否支持蓝牙*/private boolean supportBluetooth(Context context) {return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);}/*** 判断是否存在光传感器来判断是否为模拟器* 部分真机也不存在温度和压力传感器。其余传感器模拟器也存在。** @return false为模拟器*/private boolean hasLightSensor(Context context) {SensorManager sensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); //光线传感器if (null == sensor) return false;else return true;}/*** 特征参数-进程组信息*/private CheckResult checkFeaturesByCgroup() {String filter = CommandUtil.getSingleInstance().exec("cat /proc/self/cgroup");if (null == filter) return new CheckResult(RESULT_MAYBE_EMULATOR, null);return new CheckResult(RESULT_UNKNOWN, filter);}
}

 关键是 readSysProperty这个方法,返回false就不是模拟器是真机,true是模拟器

此包内的四个文件如下:
CheckResult.java
 

package com.lahm.library;public class CheckResult {public static final int RESULT_MAYBE_EMULATOR = 0;//可能是模拟器public static final int RESULT_EMULATOR = 1;//模拟器public static final int RESULT_UNKNOWN = 2;//可能是真机public int result;public String value;public CheckResult(int result, String value) {this.result = result;this.value = value;}
}
CommandUtil.java
package com.lahm.library;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;/*** Project Name:EasyProtector* Package Name:com.lahm.library* Created by lahm on 2018/6/8 16:23 .*/
public class CommandUtil {private CommandUtil() {}private static class SingletonHolder {private static final CommandUtil INSTANCE = new CommandUtil();}public static final CommandUtil getSingleInstance() {return SingletonHolder.INSTANCE;}public String getProperty(String propName) {String value = null;Object roSecureObj;try {roSecureObj = Class.forName("android.os.SystemProperties").getMethod("get", String.class).invoke(null, propName);if (roSecureObj != null) value = (String) roSecureObj;} catch (Exception e) {value = null;} finally {return value;}}public String exec(String command) {BufferedOutputStream bufferedOutputStream = null;BufferedInputStream bufferedInputStream = null;Process process = null;try {process = Runtime.getRuntime().exec("sh");bufferedOutputStream = new BufferedOutputStream(process.getOutputStream());bufferedInputStream = new BufferedInputStream(process.getInputStream());bufferedOutputStream.write(command.getBytes());bufferedOutputStream.write('\n');bufferedOutputStream.flush();bufferedOutputStream.close();process.waitFor();String outputStr = getStrFromBufferInputSteam(bufferedInputStream);return outputStr;} catch (Exception e) {return null;} finally {if (bufferedOutputStream != null) {try {bufferedOutputStream.close();} catch (IOException e) {e.printStackTrace();}}if (bufferedInputStream != null) {try {bufferedInputStream.close();} catch (IOException e) {e.printStackTrace();}}if (process != null) {process.destroy();}}}private static String getStrFromBufferInputSteam(BufferedInputStream bufferedInputStream) {if (null == bufferedInputStream) {return "";}int BUFFER_SIZE = 512;byte[] buffer = new byte[BUFFER_SIZE];StringBuilder result = new StringBuilder();try {while (true) {int read = bufferedInputStream.read(buffer);if (read > 0) {result.append(new String(buffer, 0, read));}if (read < BUFFER_SIZE) {break;}}} catch (Exception e) {e.printStackTrace();}return result.toString();}
}
EmulatorCheckCallback接口
package com.lahm.library;/*** Project Name:EasyProtector* Package Name:com.lahm.library* Created by lahm on 2018/7/25 15:19 .*/
public interface EmulatorCheckCallback {void findEmulator(String emulatorInfo);
}

在cocos.game.AppActivity这个类里,先声明一个静态变量:
public static boolean isEnumator = false;

在onCreate(Bundle savedInstanceState)方法里这样调用:
this.isEnumator = EmulatorCheckUtil.getSingleInstance().readSysProperty(this, null);
这样就能检测出模拟器还是真机了,为true就是模拟器,false为真机。

再写个方法给typescript层调用:

public static boolean isRunningOnEmulator() {return isEnumator;}

typescript层这样调用即可:
 

getEmulator() { //检查是否是模拟器if(native.reflection) {global.bEmulator =  native.reflection.callStaticMethod("com/cocos/game/AppActivity", "isRunningOnEmulator","()Z");}elseglobal.bEmulator = false;}

大功告成,实测夜神模拟器,蓝叠模拟器能检测出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/100088.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OS 多进程图像

schedule()函数为切换进程函数&#xff0c;pCur.state被置为阻塞态&#xff0c;放入磁盘等待队列 pCur和pNew都为对应pcb&#xff08;为了使参与并发执行的每个程序&#xff0c;包含数据都能独立地运行&#xff0c;在操作系统中必须为之配置一个专门的数据结构&#xff0c;称为…

解决`java.lang.NoClassDefFoundError`在Nacos和Spring Boot集成中的问题

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

函数栈帧的创建与销毁

目录 引言 基础知识 内存模型 ​ 寄存器的种类与功能 常用的汇编指令 函数栈帧创建与销毁 main()函数栈帧的创建 NO1. NO2. NO3. NO4. NO5. NO6. main()函数栈帧变量的创建 调用Add()函数栈帧的预备工作——传参 NO1. NO2. NO3. Add()函数栈帧的创建 …

机器学习:什么是分类/回归/聚类/降维/决策

目录 学习模式分为三大类&#xff1a;监督&#xff0c;无监督&#xff0c;强化学习 监督学习基本问题 分类问题 回归问题 无监督学习基本问题 聚类问题 降维问题 强化学习基本问题 决策问题 如何选择合适的算法 我们将涵盖目前「五大」最常见机器学习任务&#xff1a…

Python Opencv实践 - 图像中值滤波

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR) print(img.shape) pixel_count img.shape[0] * img.shape[1] print(pixel_count)#为图像添加椒盐噪声 #参考资料&#xf…

如何通过振动判断设备健康度?以PreMaint设备数字化平台为例

在工业生产过程中&#xff0c;设备的健康状况直接关系到生产效率和安全。而振动分析作为一种重要的设备健康监测手段&#xff0c;可以通过监测设备的振动情况来判断其健康状况。本文将以PreMaint设备数字化平台为例&#xff0c;探讨如何通过振动分析来判断设备的健康度&#xf…

电商系统架构设计系列(九):如何规划和设计分库分表?

上篇文章中&#xff0c;我给你留了一个思考题&#xff1a;分库分表该如何设计&#xff1f; 今天这篇文章&#xff0c;我们来聊一下如何规划和设计分库分表&#xff0c;以及要考虑哪些问题。 引言 当要解决海量数据的问题&#xff0c;就必须要用到分布式的存储集群了&#xff…

ROS2 中的分布式系统

一、说明 当您运行 ROS2 应用程序时&#xff0c;通常需要在不同机器的不同位置运行 ROS2 节点。由于 ROS2 在抽象的 DDS 层中使用节点之间的通信&#xff0c;因此我们可以非常轻松地安排通信。 为了充分理解 ROS2 的架构&#xff0c;我建议您熟悉本文。 出于本文的目的&#xf…

江西南昌电气机械三维测量仪机械零件3d扫描-CASAIM中科广电

精密机械零部件是指机械设备中起到特定功能的零件&#xff0c;其制造精度要求非常高。这些零部件通常由金属、塑料或陶瓷等材料制成&#xff0c;常见的精密机械零部件包括齿轮、轴承、螺丝、活塞、阀门等。精密机械零部件的制造需要高精度的加工设备和工艺&#xff0c;以确保其…

微信小程序使用npm引入三方包详解

目录 1 前言2 微信小程序npm环境搭建2.1 创建package.json文件2.2 修改 project.config.json2.3 修改project.private.config.json配置2.4 构建 npm 包2.5 typescript 支持2.6 安装组件2.7 引入使用组件 1 前言 从小程序基础库版本 2.2.1 或以上、及开发者工具 1.02.1808300 或…

Mac常见恶意软件再现,办公应用程序潜藏风险如何防范?

Mac电脑正受到臭名昭著的XLoader恶意软件的新变种的攻击&#xff0c;该恶意软件已被重写为在最好的MacBook上本地运行。 虽然XLoader至少从2015年开始出现&#xff0c;但在2021年发现macOS变体之前&#xff0c;它主要用于针对Windows PC。然而&#xff0c;该版本是作为Java程序…

【Redis从头学-7】Redis中的Set数据类型实战场景之用户画像去重、共同关注、专属粉丝

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;Re…

【leetcode 力扣刷题】移除链表元素 多种解法

移除链表元素的多种解法 203. 移除链表元素解法①&#xff1a;头节点单独判断解法②&#xff1a;虚拟头节点解法③&#xff1a;递归 203. 移除链表元素 题目链接&#xff1a;203.移除链表元素 题目内容&#xff1a; 理解题意&#xff1a;就是单纯的删除链表中所有值等于给定的…

0基础学习VR全景平台篇 第88篇:智慧眼-成员管理

一、功能说明 成员管理&#xff0c;是指管理智慧眼项目的成员&#xff0c;拥有相关权限的人可以进行添加成员、分配成员角色、设置成员分类、修改成员以及删除成员五项操作。但是仅限于管理自己的下级成员&#xff0c;上级成员无权管理。 二、前台操作页面 登录智慧眼后台操…

公文校对的艺术:如何确保你的正式文件零错误?

公文是政府和企业中最重要的正式文件之一。一个小小的错误&#xff0c;不仅会影响公文的专业性&#xff0c;甚至可能带来法律和经济后果。因此&#xff0c;如何进行精准的公文校对成为了一门必不可少的技能。接下来&#xff0c;我们将分享一些专业的公文校对技巧&#xff0c;并…

Docker容器与虚拟化技术:容器运行时说明与比较

目录 一、理论 1.容器运行时 2.容器运行时接口 3.容器运行时层级 4.容器运行时比较 5.强隔离容器 二、问题 1.K8S为何难以实现真正的多租户 三、总结 一、理论 1.容器运行时 &#xff08;1&#xff09;概念 Container Runtime 是运行于 k8s 集群每个节点中&#xff…

greenplum gpfdist外部表(只读)的实现---理论

经过项目的验证测试以及初步商用化&#xff0c;本篇将进一步讲解greenplum外部表的实现原理&#xff0c;包括设计原则、交互协议与实现流程。gpfdist工具的简介与使用见回顾greenplum gpfdist工具。 1 设计原则 greenplum作为分布式分析型数据库&#xff0c;其每个节点都是独立…

如何批量加密PDF文件并设置不同密码 - 批量PDF加密工具使用教程

如果你正在寻找一种方法来批量加密和保护你的PDF文件&#xff0c;批量PDF加密工具是一个不错的选择。 它是一个体积小巧但功能强大的Windows工具软件&#xff0c;能够批量给多个PDF文件加密和限制&#xff0c;包括设置打印限制、禁止文字复制&#xff0c;并增加独立的打开密码。…

【Django】Task4 序列化及其高级使用、ModelViewSet

【Django】Task4 序列化及其高级使用、ModelViewSet Task4主要了解序列化及掌握其高级使用&#xff0c;了解ModelViewSet的作用&#xff0c;ModelViewSet 是 Django REST framework&#xff08;DRF&#xff09;中的一个视图集类&#xff0c;用于快速创建处理模型数据的 API 视…

C++ 网络编程项目fastDFS分布式文件系统(四)-fastCGI项目相关技术以及linux搜狗输入法相关问题。

目录 1. Nginx作为web服务器处理请求 2. http协议复习 Get方式提交数据 Post方式提交数据 3. fastCGI 3.1 CGI 3.2 fastCGI 3.3 fastCGI和spawn-fcgi安装 1. 安装fastCGI 2. 安装spawn-fcgi 3.4 nginx && fastcgi 4其他知识点 1. fastCGI环境变量 - fas…