我想在Android应用内部的运行时确定它是否在BlueStacks Android模拟器中运行。这样我就可以修改应用程序在BlueStacks中运行时的运行方式。
BlueStacks不支持多点触控,所以我想实现当前应用程序标准的缩放到缩放功能的替代方案。
E.g。
If (appIsRunningInBlueStacks){
mySurfaceView.enableMultiTouchAlternatives();
} else{
mySurfaceView.enableMultiTouchFeatures();
}
确定appIsRunningInBlueStacks值的可靠方法是什么?
编辑有关问题的评论答案摘要:
Ben,Taras,感谢您的建议。 BlueStacks的Build.MODEL等值为:
型号:“GT-I9100”
制造商:“samsung”
设备:“GT-I9100”
产品:“GT-I9100”
这是与三星Galaxy SII相同的型号,所以使用它不会是理想的,因为害怕使用与BlueStacks相同的SII处理所有用户。
CommonsWare,该应用程序继续在BlueStacks中运行,即使使用<使用特征>用于清单中的多点触控。事实上(也回答了iagreen的问题)......
packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
...返回true!我想这是可以预料的,因为模拟器确信它是三星Galaxy SII!
因此,我们仍然没有办法可靠地检测应用程序是否在BlueStacks上运行而不会将所有三星Galaxy SII用户放在同一个存储桶中。还有其他想法吗?
答案 0 :(得分:2)
您可以检查Bluestacks共享文件夹是否存在 / SD卡/窗/ BstSharedFolder
Boolean onBlueStacks()
{
File sharedFolder = new File(Environment
.getExternalStorageDirectory().toString()
+ File.separatorChar
+ "windows"
+ File.separatorChar
+ "BstSharedFolder");
if (sharedFolder.exists())
{
return true;
}
return false;
}
答案 1 :(得分:1)
我的BlueStacks版本将Build.Model
报告为GT-N7100
。
使用:android.opengl.GLES20.glGetString(android.opengl.GLES20.GL_RENDERER)
我得到Bluestacks
。
答案 2 :(得分:1)
尝试了所有在线可用的建议解决方案之后,我们发现Google's SafetyNet Attestation API是检测BlueStack(任何版本)和NoxPlayer等VM的唯一解决方案。
关心内容盗版(和其他安全问题)的应用可以像Netflix filters devices on the PlayStore一样过滤其在Google Play上的可用性。
控制台的新“设备目录”部分包含一个选项 称为“ SafetyNet排除”,可用于防止“设备 未通过完整性测试或未经Google认证的测试,” 从下载特定的应用程序:其中将有根设备 以及那些运行自定义ROM的计算机。
但是有一个catch用户仍会从交叉共享或其他分发系统中找到APK,因此客户端必须在应用级别实现SafetyNet Attestation API
。
它如何工作?
SafetyNet检查设备上的软件和硬件信息 应用安装位置,以创建该设备的配置文件。的 服务然后尝试在以下列表中找到此相同的配置文件 已通过Android兼容性测试的设备型号。 API 也使用此软件和硬件信息来帮助您评估 设备的基本完整性以及APK的信息 调用应用程序。此证明可帮助您确定是否或 不是特定设备已被篡改或以其他方式 修改。
这是Google提供的(易于实现的)付费API,到目前为止,每天允许10,000次免费点击:\
如果有人有兴趣自行检测虚拟机,那么这些是提供启发式方法的好论文:
Evading Android Runtime Analysis via Sandbox Detection
Rage Against the Virtual Machine: Hindering Dynamic Analysis of Android Malware
答案 3 :(得分:0)
可能为时已晚,但为了遇到同样问题的其他人:
public boolean isRunningOnEmulator() {
return Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| 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)
|| Build.PRODUCT.contains("vbox86p")
|| Build.DEVICE.contains("vbox86p")
|| Build.HARDWARE.contains("vbox86");
}
答案 4 :(得分:0)
基于Regis'先生的回答,当存在共享文件夹时,您可以检测到它。但是,在Bluestacks 4中,使用file.exists()
仅返回false。这是因为共享文件夹没有权限(000
或----------
)。但是列出目录中的文件将检测到该文件夹。
String path = Environment.getExternalStorageDirectory().toString();
Log.d("FILES", "Path: " + path);
File directory = new File(path);
File[] files = directory.listFiles();
for (File file : files) {
if (file.getName().contains("windows")) {
Log.d("FILES", "windows file exists, it's a bluestacks emu");
}
}
答案 5 :(得分:-1)
这将是独一无二的。
Bluestack中没有蓝牙设备。
因此,请尝试获取始终为' null的蓝牙地址字符串。在Bluestack或任何模拟器上。确保您在项目清单上添加蓝牙权限。
BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_bluetoothAdd = m_BluetoothAdapter.getAddress();
答案 6 :(得分:-2)
我也在寻找解决方案,我在搜索时在一些中文博客上找到了这段代码片段,我不知道它在做什么,但也许其他人可以吗?
public boolean isEmulator() {
String android_id = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
Log.d("ares","ANDROID_ID: "+android_id);
Log.d("ares","Build.PRODUCT: "+Build.PRODUCT);
boolean emulator = TextUtils.isEmpty(android_id) || "google_sdk".equals( Build.PRODUCT ) || "sdk".equals(Build.PRODUCT);
return emulator;
}
如果完全没有帮助,请忽略......