4

We are trying to reward with some kind of a coupon which can be redeemed at a physical store, whenever a new installation is done on a device. We did some trials on this and verify that it is a new device based on IMEI & IMSI. But we found people do it on some emulators where these IDs can be manipulated and mimicking a new device. How can this be avoided?

We are currently using like this

    TelephonyManager m_telephonyManager = (TelephonyManager) context.getSystemService(serviceName);
    String IMEI, IMSI;
    IMEI = m_telephonyManager.getDeviceId();
    IMSI = m_telephonyManager.getSubscriberId();
    return IMEI + ":" + IMSI;

I am sure there is a way since the ad networks which drive installs correctly attribute it only once per device.

user1076371
  • 161
  • 6
  • 2
    `IDs can be manipulated` - even your code using IMEI can be manipulated, hackers can change it to load ID from external file. – marcinj Jan 17 '14 at 19:14
  • Ad networks also have the IP of the connection and other factors they can track. And even they will have some false positives. – zapl Jan 17 '14 at 19:18
  • 1
    See various answers on [How can I detect when an Android application is running in the emulator?](http://stackoverflow.com/questions/2799097/how-can-i-detect-when-an-android-application-is-running-in-the-emulator?answertab=votes#tab-top) and [How to find out from code if my Android app runs on emulator or real device?](http://stackoverflow.com/questions/6864251/how-to-find-out-from-code-if-my-android-app-runs-on-emulator-or-real-device). Let us know if none of these solutions work and in case you are looking for something different :) – Shobhit Puri Jan 17 '14 at 19:20

3 Answers3

2

You can check if your application is running in emulator using any of these methods. But these are not 100 % reliable but a combination of these approaches might help you better.

Approach 1

if (android.os.Build.MODEL.equals(“sdk”)) {
   // emulator
} else {
   //not emulator
}

Approach 2

Try to set your manifest to have a dependency on some hardware which is not normally supported in the emulator. For example:

<uses-feature android:name="android.hardware.sensor.accelerometer" 
              android:required="true" />

Approach 3

Try using

Build.FINGERPRINT.contains("generic")

These are some ways to find if the application is running in emulator. Hope this helps.

Prem
  • 4,823
  • 4
  • 31
  • 63
0

Make them show the app + generated code on a device in store. That seems the only way your current scheme can be waterproof. Or just don't go with device ID as identification, but figure out some other promotion scheme ;)

Nanne
  • 64,065
  • 16
  • 119
  • 163
0

This isn't an answer to your question, but a suggestion as to how you could get a unique ID. Use the users mobile number as the unique ID. The problem is that getting the phone number is not trivial as can be seen here:

MSISDN : Is it a SIM Card Data? Why all The Provided Function (from Blackberry and Android) to fetch MSISDN not reliable?

Therefore what you could do is implement a basic handshake process, by which the user inputs their phone number, which is sent to your server. Your server then sends a text message to the given number, which your application can listen to. Once the confirmation text is received, a success message is sent back to the server and you know that the phone number is valid and unique.

Hope this makes sense, all the best with your project.

Community
  • 1
  • 1
TheIT
  • 11,919
  • 4
  • 64
  • 56