1

I'm developing an app in which I'm gonna need the unique ID of a device.

This post: Is there a unique Android device ID? first leads me to consider using ANDROID_ID. But I need a reliable solution for both tablets and phones, with or without any google account/software on it, like in China where most of its services are blocked. I'm therefore looking for an other solution.

Important: for security reasons, this id must be safe from any change. Of course when the device is rooted or when someone really want to mess with the app, it's impossible, but at least for the average users. Also, the Mac address and the TelephonyManager.getDeviceId() are not reliable.

As I'm targeting both phones and tablets, with or without Google, is it a way to get a unique device Id unmodifiable for each device?

Community
  • 1
  • 1
Virthuss
  • 3,142
  • 1
  • 21
  • 39
  • Virtually anything you access from your app could be modified with root. – Johann Bauer Nov 06 '15 at 09:53
  • This id is not meant to be used as it is, it will be mixed and encrypted with other parameters. I know if someone really want to mess with it its possible, but for the average user I'd like to have the safest solution – Virthuss Nov 06 '15 at 10:01
  • @FabinPaul I' asking for a safe solution including non-google device as well. I saw this topic man, and it's actually the most famous one about the topic. But it doesnt help in my case. – Virthuss Nov 06 '15 at 10:10
  • Do you want a solution that won't show false-positives (different users recognized as the same) or one that won't have false-negative (same user recognized as a different user)? – Johann Bauer Nov 06 '15 at 10:14
  • Hem... I'm not good enough in english to understand that, sorry ! ( By the way, is there a way to remove this "possible duplicate" flag? ) – Virthuss Nov 06 '15 at 10:16
  • I have removed the duplicate flag. :) – Fabin Paul Nov 06 '15 at 11:32

6 Answers6

1

I am sorry that I flagged this question before fully understanding it. Like @Johann said considering rooted users into the equation will make it a lot more difficult to identify the device.

Using the assumption that your application uses webservice, user must connect to internet in some way i.e. either by data plan(users with sim card) or by wifi.

So combining id's from both the hardware and generating a unique hashcode of the resulting string, you should be able to uniquely identify the device(in theory i.e). But I haven't tested this code, so check if works for you.

final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);

final String tmDevice, tmSerial, androidId, wifi;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi = ""+ manager.getConnectionInfo().getMacAddress();

String unique_id = makeSHA1Hash(tmDevice + tmSerial + androidId + wifi);

makeSHA1Hash

 public String makeSHA1Hash(String input)
        throws NoSuchAlgorithmException, UnsupportedEncodingException
    {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        md.reset();
        byte[] buffer = input.getBytes("UTF-8");
        md.update(buffer);
        byte[] digest = md.digest();

        String hexStr = "";
        for (int i = 0; i < digest.length; i++) {
            hexStr +=  Integer.toString( ( digest[i] & 0xff ) + 0x100, 16).substring( 1 );
        }
        return hexStr;
    }

Hope it helps you...

Fabin Paul
  • 1,701
  • 1
  • 16
  • 18
  • No problem! Glad you remove the flag :) For the rest, it appears that there is no "real" solution for my question, so I'll stay on the ANDROID_ID and an encryption as you suggested. – Virthuss Nov 09 '15 at 01:45
0

You can use the wifi mac address:

  private String getWifiMacAddress() {
        WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = manager.getConnectionInfo();
        return info.getMacAddress();
  }
Héctor
  • 24,444
  • 35
  • 132
  • 243
  • Thanks for your answer but this is not safe enough. From google: It may be possible to retrieve a Mac address from a device’s WiFi or Bluetooth hardware. We do not recommend using this as a unique identifier. To start with, not all devices have WiFi. Also, if the WiFi is not turned on, the hardware may not report the Mac address. – Virthuss Nov 06 '15 at 09:55
  • Do devices without wifi exists? :O Joke... I think it is not possible what you want. When user is `root` can do anything. – Héctor Nov 06 '15 at 10:00
  • Of course it will always be a way to mess with an android app, but I'll need something reliable for at least the averages users. With or without google, for tablet or phone. – Virthuss Nov 06 '15 at 10:23
0

you can use the device imei number.

You want to call-

  android.telephony.TelephonyManager.getDeviceId().

You'll need the following permission in your AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
sud
  • 505
  • 1
  • 4
  • 12
0

I think it would be good to identify devices by using Mac address o Wi-Fi module. It's quite unique even on cheap chinese devices. Take a look at WifiInfo class: http://developer.android.com/reference/android/net/wifi/WifiInfo.html

Should works fine for device identification.

Serj.by
  • 534
  • 5
  • 17
0

After the device is rooted, the IMEI numbers and the MAC/WiFi address can be modified. Moreover, from Android Marshmallow, the user may revoke the permission for WiFi/MAC address and Bluetooth address. If you try to retrieve those values, you will be presented with a simple dummy ID, which remains common across all Marshmallow devices.
Check this link

pri
  • 1,521
  • 2
  • 13
  • 26
0

You can use the Android unique serial number it is generated when the device is booted for the first time and remains same for the lifetime.

Settings.Secure.getString(getContext().getContentResolver(), Settings.Secure.ANDROID_ID)
Deepak Vajpayee
  • 348
  • 2
  • 4
  • 15