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.mzph.cn/news/50524.shtml

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

相关文章

【Unity】制作一个简单的菜单栏页面并实现其功能

这是一个简单的菜单页面制作&#xff0c;接下来我们将制作一个完整的菜单页面&#xff0c;并且通过一定的代码去实现它对应的效果。这个主要的功能就是我们在游戏中如果想暂停一下或者重新开始&#xff0c;那么就要用到我们这个功能。接下来我们将实现在游戏中按ESC退出键可以调…

Linux Kernel的local_irq_enable()和local_irq_disable()函数

代码如下图所示&#xff0c;最终操作的是msr daifset, #3 和 msr daifclr, #3 寄存器。 (include/linux/irqflags.h) #define local_irq_enable() do { raw_local_irq_enable(); } while (0) #define local_irq_disable() do { raw_local_irq_disable(); } while (0)#define ra…

解决SEGGER Embedded Studio无法显示Nordic MCU外设寄存器问题

如果使用SES调试NRF52840的时候发现&#xff0c;官方例程只能显示CPU寄存器&#xff0c;但是无法显示外设寄存器时&#xff0c;解决办法如下&#xff1a; 1.在解决方案右键→Options→Debug→Debugger&#xff0c;然后Target Device选择正确的型号。 2.Register Definition Fil…

10个最好的云GPU服务

随着深度学习、人工智能和机器学习等新技术的出现&#xff0c;云 GPU 的需求量很大。 GPU&#xff08;图形处理单元&#xff09;是专用处理器&#xff0c;用于处理计算机图形和游戏等活动所需的大量数据集和复杂计算。不过&#xff0c;它们现在对人工智能&#xff08;A.I.&…

【C++】命名空间 namespace 与 标准流 iostream ( 命名空间概念简介 | 命名空间定义 | 命名空间使用 | iostream 中的命名空间分析 )

文章目录 一、命名空间 namespace1、命名空间基本概念2、名称概念4、C 语言的命名空间3、命名空间避免标识符冲突 二、命名空间定义1、命名空间基本概念2、命名空间定义语法3、代码示例 - 命名空间定义使用 三、命名空间使用1、命名空间默认访问方式2、使用命名空间3、使用默认…

实战项目ssm权限系统 3-总结篇,权限模块保护业务模块

一 工程模块介绍 1.1 工程模块关系 在业务微服务模块中引入安全认证模块&#xff0c;起到对业务模块的认证授权保护

在线设计APP ui的网站,分享这7款

在数字时代&#xff0c;用户界面&#xff08;UI&#xff09;设计变得非常重要&#xff0c;因为良好的UI设计可以改善用户体验&#xff0c;增强产品吸引力。随着科学技术的发展&#xff0c;越来越多的应用在线设计网站出现&#xff0c;为设计师和团队提供了一种新的创作方式。本…

postgresql基于postgis常用空间函数

1、ST_AsGeoJSON 图元转geojson格式 select ST_AsGeoJSON(l.geom) from g_zd l limit 10 2、 ST_Transform 坐标转换 select st_transform(l.shape, 3857) from sde_wf_cyyq l limit 10select st_astext(st_transform(l.shape, 3857)) from sde_wf_cyyq l limit 103、st_aste…

使用动态IP是否会影响网络

今天我们要谈论的话题是关于动态IP和网络的关系。也许有些小伙伴对这个概念还比较陌生&#xff0c;但别担心&#xff0c;我会简单明了的给你理清楚。让我们一起看看动态IP到底能否影响到网络。 首先&#xff0c;我们先来搞明白什么是动态IP。在互联网世界中&#xff0c;每一个连…

【NLP】1、BERT | 双向 transformer 预训练语言模型

文章目录 一、背景二、方法 论文&#xff1a;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 出处&#xff1a;Google 一、背景 在 BERT 之前的语言模型如 GPT 都是单向的模型&#xff0c;但 BERT 认为虽然单向&#xff08;从左到右预测…

WPF中手写地图控件(3)——动态加载地图图片

瓦片增加一个Loading动画 可以查看我的另一个博客WPF中自定义Loading图 从中心扩散 进行从里到外的扩散&#xff0c;方向是上左下右。如下图所示 于是我们可以定义一个拥有坐标X跟Y的集合&#xff0c;他允许这个集合&#xff0c;内部使用枚举器的MoveNext自动排序&#xf…

stm32之5.长按按键(使用时钟源)调整跑马灯速度

------------------------------ 源码 #include <stm32f4xx.h> #include "led.h" #include "delay.h" #include "my_str.h" #include "beep.h" #include "key.h" int main(void) { key_init(); Led_init();…

Ubuntu-Server 22.04安装详细过程-图文版

一.下载Ubuntu Server镜像&#xff0c;官方地址下载即可 https://ubuntu.com/download/server 乌班图镜像网址&#xff0c;点击下载即可 二.安装乌班图镜像&#xff0c;最好自己准备u盘在ISO软件内制作完成 1.选择 Install Ubuntu Server 2.选择安装语言为英语 3.安装程序更新选…

数据库第十五课-------------非关系型数据库----------Redis

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

港联证券|指数或进入磨底阶段 短期关注环保、煤炭等板块

磨底历来都不是一天能达到的&#xff0c;比方2018年的政策底到商场底&#xff0c;半途也阅历两个多月时间。当下政策底出现之后至今也有近一个月时间&#xff0c;并且下跌量能不断缩短&#xff0c;心情面也降至冰点&#xff0c;种种迹象阐明离真正商场底的构成已经不远了。此时…

ElasticSearch常用方法

ElasticSearch:是一个储存、检索、数据分析引擎。 在互联网项目中我们经常会按一定的条件去索引我们指定的数据&#xff0c;但是在大量的数据中我们如果直接查询数据库效率是非常低的&#xff0c;ElasticSearch就可以很好的帮我们完成检索。 es封装了api提供给我我们直接操作…

测试框架pytest教程(3)夹具-@pytest.fixture

内置fixture Fixture使用pytest.fixture装饰&#xff0c;pytest有一些内置的fixture 命令可以查看内置fixture pytest --fixtures fixture范围 在pytest中&#xff0c;夹具&#xff08;fixtures&#xff09;具有不同的作用范围&#xff08;scope&#xff09;&#xff0c;用于…

【MySQL】JSON 格式字段处理

MySQL 5.7 版本后已支持 JSON 格式&#xff0c;这虽是 MySQL 的一小步&#xff0c;但可以说是程序开发的一大步&#xff0c;再也不用将 JSON 内容塞到 VARCHAR 类型字段了&#xff0c;程序设计也会变得更加灵活。网上大多只针对JSONObject 对象类型&#xff0c;本文也将详解 JS…

RabbitMQ 消费者

RabbitMQ的消费模式分两种&#xff1a;推模式和拉模式&#xff0c;推模式采用Basic.Consume进行消费&#xff0c;拉模式则是调用Basic.Get进行消费。   消费者通过订阅队列从RabbitMQ中获取消息进行消费&#xff0c;为避免消息丢失可采用消费确认机制 消费者 拉模式拉模式的实…

企业数字化转型中,VR数字展厅能有哪些体验?

在数字化转型的浪潮下&#xff0c;企业纷纷开始注重数字展厅的开展&#xff0c;VR虚拟展厅结合VR全景技术&#xff0c;可以创造出许多有趣的玩法和体验&#xff0c;无论是虚拟参观、互动体验还是VR云会议对接&#xff0c;都为企业客户带来了全新的感知方式。 同传统展厅相比&am…