17

I would like to ascertain at run-time inside an Android app whether it is running within the BlueStacks Android emulator. This is so I can modify the way the app runs when running inside BlueStacks.

BlueStacks does not support multi-touch so I want to implement an alternative to the standard pinch-to-zoom functionality my current app has.

E.g.

If (appIsRunningInBlueStacks){
    mySurfaceView.enableMultiTouchAlternatives();
} else{
    mySurfaceView.enableMultiTouchFeatures();
}

What is a reliable way of ascertaining the value of appIsRunningInBlueStacks?

EDIT Summary of answers to comments on question:

Ben, Taras, thanks for the suggestions. The Build.MODEL etc. values for BlueStacks are:

  • Model: "GT-I9100"

  • Manufacturer: "samsung"

  • Device: "GT-I9100"

  • Product: "GT-I9100"

This is the same model number as the Samsung Galaxy SII so it would not be ideal to use this for fear of treating all users with SIIs the same as those on BlueStacks.

CommonsWare, the app continues to run in BlueStacks even with the < uses-feature> for multitouch in the manifest. In fact (also answering iagreen's question)...

packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);

... returns true! This is to be expected I suppose as the emulator is convinced it is a Samsung Galaxy SII!

Therefore we are still without a way of reliably detecting whether an app is running on BlueStacks without also throwing all Samsung Galaxy SII users in the same bucket. Any other ideas?

Twice Circled
  • 1,410
  • 1
  • 15
  • 23
  • 1
    Have you tried peeking through `android.os.Build`? (http://developer.android.com/reference/android/os/Build.html) – Ben Siver Jan 03 '13 at 17:36
  • Yes, try checking android.os.Build MODEL, MANUFACTURER, DEVICE, PRODUCT constants at runtime and checking their values, than simply check one of the parameter that works best and is unique at runtime. – Taras Leskiv Jan 03 '13 at 17:44
  • 1
    Do you have the proper `` elements to advertise that you require multitouch? Or is BlueStacks ignoring that? – CommonsWare Jan 03 '13 at 17:47
  • @Taras: IIRC from a previous question, BlueStacks advertises itself as being a Galaxy Tab or some such, and so those `Build` values may not be as helpful as normal in this case. – CommonsWare Jan 03 '13 at 17:48
  • 1
    Does BlueStacks correctly report [FEATURE_TOUCHSCREEN_MULTITOUCH](http://developer.android.com/reference/android/content/pm/PackageManager.html#FEATURE_TOUCHSCREEN_MULTITOUCH) from the package manager? That seems the best way to go because then you gracefully degrade for all non-multitouch devices. – iagreen Jan 03 '13 at 18:38
  • Run `adb shell getprop` and look for anything that stands out. Emulators often have some unique set of system properties. – fadden Jan 23 '15 at 21:40
  • https://github.com/framgia/android-emulator-detector – jclova Nov 07 '18 at 22:03

7 Answers7

5

You can check that the Bluestacks shared folder exist /sdcard/windows/BstSharedFolder

    Boolean onBlueStacks()
        {
        File sharedFolder = new File(Environment
                .getExternalStorageDirectory().toString()
                + File.separatorChar
                + "windows"
                + File.separatorChar
                + "BstSharedFolder");

        if (sharedFolder.exists())
            {
            return true;
            }

        return false;
        }
Regis St-Gelais
  • 3,156
  • 5
  • 27
  • 40
5

All the above methods are not working on BlueStacks 5. The correct way to do is checking if the path of /mnt/windows/BstSharedFolder exists. It is working fine on both BlueStacks 4 and 5.

   fun checkFilesExist(files: Array<String>): Boolean {
        files.forEach {
            val file = File(it)
            if (file.exists()) {
                return true
            }
        }
        return false
    }
    
    fun isBlueStacks(): Boolean {
        val BLUE_STACKS_FILES = arrayOf(
            "/mnt/windows/BstSharedFolder"
        )
        return checkFilesExist(BLUE_STACKS_FILES)
    }

Weidian Huang
  • 2,787
  • 2
  • 20
  • 29
  • I've marked this as the accepted answer as it is the most recent. If you could add a working code snippet to your answer that would improve it even further. Thank you. – Twice Circled Jan 10 '22 at 12:08
3

After trying all the suggested solutions available online we found the Google's SafetyNet Attestation API is the only solution for detecting VMs like BlueStack(any version) and NoxPlayer.

Apps that care about content piracy (and other security issues) can filter their availability on the Google Play like Netflix filters devices on the PlayStore.

The new “device catalog” section of the console includes an option called “SafetyNet exclusion,” which can be used to prevent “devices that fail integrity tests or those that are uncertified by Google,” from downloading a specific app: among these would be rooted devices and those running custom ROMs.

But there is a catch user will still find the APK from cross-sharing or other distribution systems, so the client must implement SafetyNet Attestation API on the app level.

How does it work?

SafetyNet examines software and hardware information on the device where your app is installed to create a profile of that device. The service then attempts to find this same profile within a list of device models that have passed Android compatibility testing. The API also uses this software and hardware information to help you assess the basic integrity of the device, as well as the APK information of the calling app. This attestation helps you to determine whether or not the particular device has been tampered with or otherwise modified.

It's an (easy to implement) paid API from the Google which allows 10,000 free hits per day as of now :\

If anyone is interested in detecting VMs by them self, these are the good papers available suggesting heuristic approaches :

Evading Android Runtime Analysis via Sandbox Detection

Rage Against the Virtual Machine: Hindering Dynamic Analysis of Android Malware

Vaibhav Jani
  • 12,428
  • 10
  • 61
  • 73
2

My version of BlueStacks is reporting my Build.Model as GT-N7100.

Using: android.opengl.GLES20.glGetString(android.opengl.GLES20.GL_RENDERER) I get Bluestacks.

jacobk
  • 94
  • 1
  • 5
2

It maybe too late but for the sake of others who have the same problem :

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");
}
ucMedia
  • 4,105
  • 4
  • 38
  • 46
1

Based on Mr. Regis' answer, you can detect it when the shared folder is present. However in Bluestacks 4, using file.exists() will only return false. This is because the shared folder has no permissions (000 or ----------). But listing files in the directory will detect the folder.

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");
    }
}
Smee
  • 123
  • 2
  • 13
-1

This Will be unique.

There is no bluetooth device in Bluestack.

So try to get The Bluetooth Address string which is always 'null' on Bluestack or Any emulator.Make sure you are adding Bluetooth permission on your project manifest.

BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

 String m_bluetoothAdd = m_BluetoothAdapter.getAddress();
user3527444
  • 269
  • 1
  • 4
  • 7