内容简介:看到这个标题,可能很多人会疑惑,为啥?判断安卓模拟器本身就不一定准确,更何况还要知道它是什么品牌?是蓝叠、腾讯手游助手、网易Mumu还是夜神模拟器呢?先谈如何识别模拟器,百度、谷歌搜索,能找到不少参考资料。这里我搜索到一篇相关比较全的介绍文章:
看到这个标题,可能很多人会疑惑,为啥?判断安卓模拟器本身就不一定准确,更何况还要知道它是什么品牌?
是蓝叠、腾讯手游助手、网易Mumu还是夜神模拟器呢?
先谈如何识别模拟器,百度、谷歌搜索,能找到不少参考资料。这里我搜索到一篇相关比较全的介绍文章: Android | 检测 Android 虚拟机的方法和代码实现
github 上相关的仓库也有很多:
https://github.com/framgia/android-emulator-detector
https://github.com/gingo/android-emulator-detector
以上这些,准确率在90%以上吧,要求不高,基本也是够用的。那接下来的问题就是,如何判断是什么模拟器呢?
…
…
…
如果以正常思维来想的话,此路是不通的。我最初是有一个想法,就是任何公司/团队提供一个模拟器让用户使用和下载,那它如何盈利,如何品牌露出呢?基于这点,我试了一个网易的 Mumu
我就想,那其它模拟器是不是也这样呢?
似乎无解了。。。
同事贴出一段代码,从 bugly 里面扒出来的,思路很奇特。就是判断,是否存在某个包名的 app,如果存在就是该品牌的模拟器。
然后我试了一下,模拟器提供的应用商店是不让卸载的,不让卸载的,不让卸载的( 盈利主要靠从应用商店里下载游戏 )。也就意味着存在某个应用商店,大概率就是该模拟器了(绝大部分正常情况下)。极端情况下就是,我用A模拟器,下载并安装了B模拟器的应用商店,存在这种情况,但概率很低,那我们就遍历所有包名,最后人肉去判断也行。
其它几款模拟器,均测试验证通过,详情可见代码。
package com.utils; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Build; import android.text.TextUtils; import java.io.File; import java.util.ArrayList; import java.util.List; public class CheckSimulator { private static final String[] PKG_NAMES = {"com.mumu.launcher", "com.ami.duosupdater.ui", "com.ami.launchmetro", "com.ami.syncduosservices", "com.bluestacks.home", "com.bluestacks.windowsfilemanager", "com.bluestacks.settings", "com.bluestacks.bluestackslocationprovider", "com.bluestacks.appsettings", "com.bluestacks.bstfolder", "com.bluestacks.BstCommandProcessor", "com.bluestacks.s2p", "com.bluestacks.setup", "com.bluestacks.appmart", "com.kaopu001.tiantianserver", "com.kpzs.helpercenter", "com.kaopu001.tiantianime", "com.android.development_settings", "com.android.development", "com.android.customlocale2", "com.genymotion.superuser", "com.genymotion.clipboardproxy", "com.uc.xxzs.keyboard", "com.uc.xxzs", "com.blue.huang17.agent", "com.blue.huang17.launcher", "com.blue.huang17.ime", "com.microvirt.guide", "com.microvirt.market", "com.microvirt.memuime", "cn.itools.vm.launcher", "cn.itools.vm.proxy", "cn.itools.vm.softkeyboard", "cn.itools.avdmarket", "com.syd.IME", "com.bignox.app.store.hd", "com.bignox.launcher", "com.bignox.app.phone", "com.bignox.app.noxservice", "com.android.noxpush", "com.haimawan.push", "me.haima.helpcenter", "com.windroy.launcher", "com.windroy.superuser", "com.windroy.launcher", "com.windroy.ime", "com.android.flysilkworm", "com.android.emu.inputservice", "com.tiantian.ime", "com.microvirt.launcher", "me.le8.androidassist", "com.vphone.helper", "com.vphone.launcher", "com.duoyi.giftcenter.giftcenter"}; private static final String[] PATHS = {"/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", "/system/lib/libc_malloc_debug_qemu.so", "/sys/qemu_trace", "/system/bin/qemu-props", "/dev/socket/qemud", "/dev/qemu_pipe", "/dev/socket/baseband_genyd", "/dev/socket/genyd"}; private static final String[] FILES = {"/data/data/com.android.flysilkworm", "/data/data/com.bluestacks.filemanager"}; public static boolean isSimulator(Context paramContext) { try { List pathList = new ArrayList(); pathList = getInstalledSimulatorPackages(paramContext); if (pathList.size() == 0) { for (int i = 0; i < PATHS.length; i++) if (i == 0) { if (new File(PATHS[i]).exists()) continue; pathList.add(Integer.valueOf(i)); } else { if (!new File(PATHS[i]).exists()) continue; pathList.add(Integer.valueOf(i)); } } if (pathList.size() == 0) { pathList = loadApps(paramContext); } return (pathList.size() == 0 ? null : pathList.toString()) != null; } catch (Exception e) { e.printStackTrace(); } return false; } public static List getSimulatorInfo(Context paramContext) { List pathList = new ArrayList(); List simulatorMaps = new ArrayList(); try { pathList = getInstalledSimulatorPackages(paramContext); String brand = getSimulatorBrand(pathList); if (TextUtils.isEmpty(brand)) { List<String> list = loadApps(paramContext); if (list.size() > 0) { simulatorMaps.add(list.get(0)); } } else { simulatorMaps.add(brand); } } catch (Exception e) { e.printStackTrace(); } return simulatorMaps; } private static List getInstalledSimulatorPackages(Context context) { ArrayList localArrayList = new ArrayList(); try { for (int i = 0; i < PKG_NAMES.length; i++) try { context.getPackageManager().getPackageInfo(PKG_NAMES[i], 1); localArrayList.add(PKG_NAMES[i]); } catch (PackageManager.NameNotFoundException localNameNotFoundException) { } if (localArrayList.size() == 0) { for (int i = 0; i < FILES.length; i++) { if (new File(FILES[i]).exists()) localArrayList.add(FILES[i]); } } } catch (Exception e) { e.printStackTrace(); } return localArrayList; } public static List loadApps(Context context) { Intent intent = new Intent(Intent.ACTION_MAIN, null); intent.addCategory(Intent.CATEGORY_LAUNCHER); List<String> list = new ArrayList<>(); List<ResolveInfo> apps = context.getPackageManager().queryIntentActivities(intent, 0); //for循环遍历ResolveInfo对象获取包名和类名 for (int i = 0; i < apps.size(); i++) { ResolveInfo info = apps.get(i); String packageName = info.activityInfo.packageName; CharSequence cls = info.activityInfo.name; CharSequence name = info.activityInfo.loadLabel(context.getPackageManager()); if (!TextUtils.isEmpty(packageName)) { if (packageName.contains("bluestacks")) { list.add("蓝叠"); return list; } } } return list; } private static String getSimulatorBrand(List<String> list) { if (list.size() == 0) return ""; String pkgName = list.get(0); if (pkgName.contains("mumu")) { return "mumu"; } else if (pkgName.contains("ami")) { return "AMIDuOS"; } else if (pkgName.contains("bluestacks")) { return "蓝叠"; } else if (pkgName.contains("kaopu001") || pkgName.contains("tiantian")) { return "天天"; } else if (pkgName.contains("kpzs")) { return "靠谱助手"; } else if (pkgName.contains("genymotion")) { if (Build.MODEL.contains("iTools")) { return "iTools"; } else if ((Build.MODEL.contains("ChangWan"))) { return "畅玩"; } else { return "genymotion"; } } else if (pkgName.contains("uc")) { return "uc"; } else if (pkgName.contains("blue")) { return "blue"; } else if (pkgName.contains("microvirt")) { return "逍遥"; } else if (pkgName.contains("itools")) { return "itools"; } else if (pkgName.contains("syd")) { return "手游岛"; } else if (pkgName.contains("bignox")) { return "夜神"; } else if (pkgName.contains("haimawan")) { return "海马玩"; } else if (pkgName.contains("windroy")) { return "windroy"; } else if (pkgName.contains("flysilkworm")) { return "雷电"; } else if (pkgName.contains("emu")) { return "emu"; } else if (pkgName.contains("le8")) { return "le8"; } else if (pkgName.contains("vphone")) { return "vphone"; } else if (pkgName.contains("duoyi")) { return "多益"; } return ""; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- iOS 获取设备型号最新总结
- 司法鉴定牵手深度学习:Kaggle 相机型号识别大赛深度分析
- 树莓派推出仅售25美元的Raspberry Pi 3 Model A+新型号
- 漏洞预警 | D-Link多型号路由器任意文件下载漏洞(CVE-2018-10822)
- Android模拟器检测方案优化
- QEMU 4.0.0 发布,几乎可以模拟任何硬件设备的模拟器
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Hit Refresh
Satya Nadella、Greg Shaw / HarperBusiness / 2017-9-26 / USD 20.37
Hit Refresh is about individual change, about the transformation happening inside of Microsoft and the technology that will soon impact all of our lives—the arrival of the most exciting and disruptive......一起来看看 《Hit Refresh》 这本书的介绍吧!