我希望我的代码在模拟器上运行时与在设备上运行时略有不同。(例如,使用10.0.2.2代替公共URL在开发服务器上自动运行。)检测Android应用程序何时在模拟器中运行的最佳方法是什么?
当前回答
我尝试了几种技术,但最终选择了稍微修改过的检查Build的版本。产品如下。这似乎变化很大,从模拟器到模拟器,这就是为什么我有3个检查,我目前有。我想我本可以只检查product.contains("sdk"),但认为下面的检查更安全一些。
public static boolean isAndroidEmulator() {
String model = Build.MODEL;
Log.d(TAG, "model=" + model);
String product = Build.PRODUCT;
Log.d(TAG, "product=" + product);
boolean isEmulator = false;
if (product != null) {
isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_");
}
Log.d(TAG, "isEmulator=" + isEmulator);
return isEmulator;
}
供你参考——我发现我的Kindle Fire有Build功能。BRAND = "generic",一些模拟器没有网络运营商的"Android"。
其他回答
我找到了新的模拟器Build。硬件= "ranchu"。
参考:https://groups.google.com/forum/ # !主题/ android-emulator-dev / dltBnUW_HzU
而且我还找到了Android官方的方法来检查是否是模拟器。我认为这对我们是很好的参考。
Android API Level 23 [Android 6.0]
package com.android.internal.util;
/**
* @hide
*/
public class ScreenShapeHelper {
private static final boolean IS_EMULATOR = Build.HARDWARE.contains("goldfish");
}
我们有ScreenShapeHelper。IS_EMULATOR来检查emulator是否。
Android API Level 24 [Android 7.0]
package android.os;
/**
* Information about the current build, extracted from system properties.
*/
public class Build {
/**
* Whether this build was for an emulator device.
* @hide
*/
public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1");
}
我们有Build。IS_EMULATOR来检查emulator是否。
官方检查模拟器的方式是不是新的,也可能不够,上面的答案也提到了。
但这可能告诉我们,官方将提供官方检查是否模拟器的方法。
正如使用上面提到的所有方法一样,现在我们也可以使用这两种方法来检查模拟器是否正确。
如何访问com.android.internal包和@hide
并等待官方的开放SDK。
检查答案,当使用LeapDroid, Droid4x或Andy模拟器时,没有一个可以工作,
适用于所有情况的方法如下:
private static String getSystemProperty(String name) throws Exception {
Class systemPropertyClazz = Class.forName("android.os.SystemProperties");
return (String) systemPropertyClazz.getMethod("get", new Class[]{String.class}).invoke(systemPropertyClazz, new Object[]{name});
}
public boolean isEmulator() {
boolean goldfish = getSystemProperty("ro.hardware").contains("goldfish");
boolean emu = getSystemProperty("ro.kernel.qemu").length() > 0;
boolean sdk = getSystemProperty("ro.product.model").equals("sdk");
return goldfish || emu || sdk;
}
用下面的代码来判断你的应用是否使用了调试键?它没有检测模拟器,但它可能为您的目的工作?
public void onCreate Bundle b ) {
super.onCreate(savedInstanceState);
if ( signedWithDebugKey(this,this.getClass()) ) {
blah blah blah
}
blah
blah
blah
}
static final String DEBUGKEY =
"get the debug key from logcat after calling the function below once from the emulator";
public static boolean signedWithDebugKey(Context context, Class<?> cls)
{
boolean result = false;
try {
ComponentName comp = new ComponentName(context, cls);
PackageInfo pinfo = context.getPackageManager().getPackageInfo(comp.getPackageName(),PackageManager.GET_SIGNATURES);
Signature sigs[] = pinfo.signatures;
for ( int i = 0; i < sigs.length;i++)
Log.d(TAG,sigs[i].toCharsString());
if (DEBUGKEY.equals(sigs[0].toCharsString())) {
result = true;
Log.d(TAG,"package has been signed with the debug key");
} else {
Log.d(TAG,"package signed with a key other than the debug key");
}
} catch (android.content.pm.PackageManager.NameNotFoundException e) {
return false;
}
return result;
}
实际上,ANDROID_ID在2.2上总是等于9774D56D682E549C(根据这个线程+我自己的实验)。
所以,你可以这样检查:
String androidID = ...;
if(androidID == null || androidID.equals("9774D56D682E549C"))
do stuff;
虽然不是最漂亮的,但也很管用。
这对我来说是有效的,而不是startwith: Build.FINGERPRINT.contains("generic")
欲了解更多信息,请查看这个链接:https://gist.github.com/espinchi/168abf054425893d86d1
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件