3

I have an android app and I have some private information and when people run on emulators my android app they can see that information. Does anyone have a solution on how to block emulators from accessing my APK?

Natig Babayev
  • 3,128
  • 15
  • 23
IplayPC
  • 41
  • 1
  • 4

3 Answers3

2

You can create class that extends android.app.Application. In that class, you can throw runtime exception to crash the app, if app is running on emulator.

Note that, there's no bulletproof solution as anyone can decompile your app with free tools and remove those checks easily.

import android.app.Application;
import android.os.Build;

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        if (isEmulator()) throw new IllegalStateException();
    }

    private boolean isEmulator() {
        return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
                || Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.startsWith("unknown")
                || Build.HARDWARE.contains("goldfish")
                || Build.HARDWARE.contains("ranchu")
                || Build.MODEL.contains("google_sdk")
                || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion")
                || Build.PRODUCT.contains("sdk_google")
                || Build.PRODUCT.contains("google_sdk")
                || Build.PRODUCT.contains("sdk")
                || Build.PRODUCT.contains("sdk_x86")
                || Build.PRODUCT.contains("vbox86p")
                || Build.PRODUCT.contains("emulator")
                || Build.PRODUCT.contains("simulator");
    }
}

Also, do not forget to add that class to the <application> tag of your AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.natigbabayev.stackoverflow">

    <application
        ...
        android:name=".App">
        ...
    </application>

</manifest>

I hope my answer helps.

Natig Babayev
  • 3,128
  • 15
  • 23
0

Updated version for 2021 and also detect VirtualBox:

/**
 * Class to detect if the user is running on an emulator
 *
 * Created by Benjamin Aimone on 16/12/2021.
 */
object EmulatorDetector {
    private var isRunningOnEmulator: Boolean? = null

    fun isRunningOnEmulator(): Boolean? {
        isRunningOnEmulator?.let {
            return it
        }
        // Android SDK emulator
        isRunningOnEmulator = runningOnAndroidStudioEmulator()
                || 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.MODEL.contains("VirtualBox")
                //bluestacks
                || "QC_Reference_Phone" == Build.BOARD && !"Xiaomi".equals(Build.MANUFACTURER, ignoreCase = true) //bluestacks
                || Build.MANUFACTURER.contains("Genymotion")
                || Build.HOST == "Build2" //MSI App Player
                || Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
                || Build.PRODUCT == "google_sdk"
                // another Android SDK emulator check
                || System.getProperties().getProperty("ro.kernel.qemu") == "1"
        return isRunningOnEmulator
    }

    private fun runningOnAndroidStudioEmulator(): Boolean {
        return Build.FINGERPRINT.startsWith("google/sdk_gphone")
                && Build.FINGERPRINT.endsWith(":user/release-keys")
                && Build.MANUFACTURER == "Google" && Build.PRODUCT.startsWith("sdk_gphone") && Build.BRAND == "google"
                && Build.MODEL.startsWith("sdk_gphone")
    }
}
Ben-J
  • 1,084
  • 8
  • 24
-1

You can use below method:

public static boolean isEmulator() {
    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);
}

Then in your Activity / Application class, call above method in onCreate() and handle your logic, as below:

if (isEmulator()) {
   // Emulator
} else {
   // Device
}
Gokul Nath KP
  • 15,485
  • 24
  • 88
  • 126