我希望我的代码在模拟器上运行时与在设备上运行时略有不同。(例如,使用10.0.2.2代替公共URL在开发服务器上自动运行。)检测Android应用程序何时在模拟器中运行的最佳方法是什么?
当前回答
最常用的方法是从品牌、名称……等。但是这个方法是静态的,并且适用于模拟器的有限版本。如果有1000多家虚拟机制造商呢?那么你必须写一段代码来匹配1000多个虚拟机?
但这是浪费时间。甚至在一段时间后,会有新的vm启动,你的脚本也会被浪费。
根据我的测试,我知道了 getRadioVersion()在虚拟机上返回空, 并返回版本号在真正的android设备。
public Boolean IsVM()
{
return android.os.Build.getRadioVersion().length() == 0;
}
//return true if VM
//return false if real
虽然有用,但我没有官方解释。
代码:http://github.com/Back-X/anti-vm/blob/main/android/anti-vm.b4a
发布:http://github.com/Back-X/anti-vm/releases/download/1/anti-vm.apk
其他回答
以下是我的解决方案(它只适用于在调试机器上运行web服务器): 我已经创建了一个后台任务,当应用程序启动时启动。它查找http://10.0.2.2,如果它存在,它将全局参数(IsDebug)更改为true。这是一种无声的方式来找出你在哪里跑步。
public class CheckDebugModeTask extends AsyncTask<String, Void, String> {
public static boolean IsDebug = false;
public CheckDebugModeTask()
{
}
@Override
protected String doInBackground(String... params) {
try {
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 1000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 2000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
String url2 = "http://10.0.2.2";
HttpGet httpGet = new HttpGet(url2);
DefaultHttpClient client = new DefaultHttpClient(httpParameters);
HttpResponse response2 = client.execute(httpGet);
if (response2 == null || response2.getEntity() == null || response2.getEntity().getContent() == null)
return "";
return "Debug";
} catch (Exception e) {
return "";
}
}
@Override
protected void onPostExecute (String result)
{
if (result == "Debug")
{
CheckDebugModeTask.IsDebug = true;
}
}
从主活动onCreate:
CheckDebugModeTask checkDebugMode = new CheckDebugModeTask();
checkDebugMode.execute("");
您可以检查IMEI #, http://developer.android.com/reference/android/telephony/TelephonyManager.html#getDeviceId%28%29
如果我在模拟器上调用这个返回0。然而,我找不到任何文件可以保证这一点。虽然模拟器可能不总是返回0,但注册的电话不返回0似乎是相当安全的。在非手机的安卓设备上,或者没有安装SIM卡,或者没有在网络上注册的设备上,会发生什么呢?
似乎这是个坏主意,依赖于它。
这也意味着你需要获得读取手机状态的许可,如果你不需要它来做其他事情,这是很糟糕的。
如果不是这样,那么在你最终生成签名应用之前,总是会有一些翻转。
if ("sdk".equals( Build.PRODUCT )) {
// Then you are running the app on the emulator.
Log.w("MyAPP", "\n\n Emulator \n\n");
}
您可以检查deviceId (IMEI)是否为“000000000000000”(15个零)
用下面的代码来判断你的应用是否使用了调试键?它没有检测模拟器,但它可能为您的目的工作?
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;
}
推荐文章
- 在XML中“图像上缺少contentDescription属性”
- 在Android SQLite中处理日期的最佳方法
- 读取Android APK的包名
- Android-Facebook应用程序的键散列
- 登出时,清除活动历史堆栈,防止“返回”按钮打开已登录的活动
- 如何改变标题的活动在安卓?
- 如何隐藏动作栏之前的活动被创建,然后再显示它?
- 是否有一种方法以编程方式滚动滚动视图到特定的编辑文本?
- 在Android中将字符串转换为Uri
- 如何在NestedScrollView内使用RecyclerView ?
- 移动到另一个EditText时,软键盘下一步点击Android
- Android应用中的GridView VS GridLayout
- Activity和FragmentActivity的区别
- 右对齐文本在android TextView
- 权限拒绝:start前台需要android.permission.FOREGROUND_SERVICE