エミュレータで実行する場合とデバイスで実行する場合で、コードの実行方法を少し変えたいと思います。(たとえば、開発サーバーに対して自動的に実行するために、パブリック URL の代わりに 10.0.2.2 を使用します。) Android アプリケーションがエミュレータで実行されているかどうかを検出する最適な方法は何ですか?
ベストアンサー1
この解決策はどうでしょうか(のクラス実装はSystemProperties
利用可能ですここ):
val isProbablyRunningOnEmulator: Boolean by lazy {
// Android SDK emulator
return@lazy ((Build.MANUFACTURER == "Google" && Build.BRAND == "google" &&
((Build.FINGERPRINT.startsWith("google/sdk_gphone_")
&& Build.FINGERPRINT.endsWith(":user/release-keys")
&& Build.PRODUCT.startsWith("sdk_gphone_")
&& Build.MODEL.startsWith("sdk_gphone_"))
//alternative
|| (Build.FINGERPRINT.startsWith("google/sdk_gphone64_")
&& (Build.FINGERPRINT.endsWith(":userdebug/dev-keys") || Build.FINGERPRINT.endsWith(":user/release-keys"))
&& Build.PRODUCT.startsWith("sdk_gphone64_")
&& Build.MODEL.startsWith("sdk_gphone64_"))))
//
|| 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")
//bluestacks
|| "QC_Reference_Phone" == Build.BOARD && !"Xiaomi".equals(Build.MANUFACTURER, ignoreCase = true)
//bluestacks
|| Build.MANUFACTURER.contains("Genymotion")
|| Build.HOST.startsWith("Build")
//MSI App Player
|| Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
|| Build.PRODUCT == "google_sdk"
// another Android SDK emulator check
|| SystemProperties.getProp("ro.kernel.qemu") == "1")
}
一部のエミュレータは実際のデバイスの正確な仕様を偽装しているため、検出できない可能性があります。可能な限り追加しましたが、それが本当にエミュレータであるかどうかを 100% 検出する方法はないと思います。
以下は、APK でさまざまな情報を表示するために作成できる小さなスニペットです。独自のルールを追加することもできます。
textView.text = "FINGERPRINT:${Build.FINGERPRINT}\n" +
"MODEL:${Build.MODEL}\n" +
"MANUFACTURER:${Build.MANUFACTURER}\n" +
"BRAND:${Build.BRAND}\n" +
"DEVICE:${Build.DEVICE}\n" +
"BOARD:${Build.BOARD}\n" +
"HOST:${Build.HOST}\n" +
"PRODUCT:${Build.PRODUCT}\n"