Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>UPDATE</strong>: As of recent versions of Android, many of the issues with <code>ANDROID_ID</code> have been resolved, and I believe this approach is no longer necessary. Please take a look at <a href="https://stackoverflow.com/a/2785493/231078">Anthony's answer</a>.</p> <p>Full disclosure: my app used the below approach originally but no longer uses this approach, and we now use the approach outlined in the <a href="http://android-developers.blogspot.com/2011/03/identifying-app-installations.html" rel="noreferrer">Android Developer Blog</a> entry that <a href="https://stackoverflow.com/a/5626208/231078">emmby's answer</a> links to (namely, generating and saving a <a href="http://developer.android.com/reference/java/util/UUID.html#randomUUID()" rel="noreferrer"><code>UUID#randomUUID()</code></a>).</p> <hr> <p>There are many answers to this question, most of which will only work "some" of the time, and unfortunately that's not good enough.</p> <p>Based on my tests of devices (all phones, at least one of which is not activated):</p> <ol> <li>All devices tested returned a value for <code>TelephonyManager.getDeviceId()</code></li> <li>All GSM devices (all tested with a SIM) returned a value for <code>TelephonyManager.getSimSerialNumber()</code></li> <li>All CDMA devices returned null for <code>getSimSerialNumber()</code> (as expected)</li> <li>All devices with a Google account added returned a value for <code>ANDROID_ID</code></li> <li>All CDMA devices returned the same value (or derivation of the same value) for both <code>ANDROID_ID</code> and <code>TelephonyManager.getDeviceId()</code> -- <em>as long as</em> a Google account has been added during setup.</li> <li>I did not yet have a chance to test GSM devices with no SIM, a GSM device with no Google account added, or any of the devices in airplane mode.</li> </ol> <p>So if you want something unique to the device itself, <code>TM.getDeviceId()</code> <em>should</em> be sufficient. Obviously some users are more paranoid than others, so it might be useful to hash 1 or more of these identifiers, so that the string is still virtually unique to the device, but does not explicitly identify the user's actual device. For example, using <code>String.hashCode()</code>, combined with a UUID:</p> <pre><code>final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE); final String tmDevice, tmSerial, androidId; tmDevice = "" + tm.getDeviceId(); tmSerial = "" + tm.getSimSerialNumber(); androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() &lt;&lt; 32) | tmSerial.hashCode()); String deviceId = deviceUuid.toString(); </code></pre> <p>might result in something like: <code>00000000-54b3-e7c7-0000-000046bffd97</code></p> <p>It works well enough for me.</p> <p>As Richard mentions below, don't forget that you need permission to read the <code>TelephonyManager</code> properties, so add this to your manifest:</p> <pre><code>&lt;uses-permission android:name="android.permission.READ_PHONE_STATE" /&gt; </code></pre> <p>import libs</p> <pre><code>import android.content.Context; import android.telephony.TelephonyManager; import android.view.View; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload