uniqueidentifier identificador 24 - ¿Hay un ID de dispositivo Android único?




15 Answers

ACTUALIZACIÓN : a partir de las versiones recientes de Android, muchos de los problemas con ANDROID_ID se han resuelto, y creo que este enfoque ya no es necesario. Por favor, eche un vistazo a la respuesta de Anthony .

Revelación completa: mi aplicación usó el siguiente enfoque originalmente pero ya no lo utiliza, y ahora usamos el enfoque descrito en la entrada del android-developers.blogspot.com/2011/03/… que se vincula la respuesta de emmby (a saber, generar y guardar un UUID#randomUUID() ).

Hay muchas respuestas a esta pregunta, la mayoría de las cuales solo funcionarán "parte" del tiempo, y desafortunadamente eso no es suficiente.

Según mis pruebas de dispositivos (todos los teléfonos, al menos uno de los cuales no está activado):

  1. Todos los dispositivos probados devolvieron un valor para TelephonyManager.getDeviceId()
  2. Todos los dispositivos GSM (todos probados con una tarjeta SIM) devolvieron un valor para TelephonyManager.getSimSerialNumber()
  3. Todos los dispositivos CDMA devolvieron un valor nulo para getSimSerialNumber() (como se esperaba)
  4. Todos los dispositivos con una cuenta de Google agregada devolvieron un valor para ANDROID_ID
  5. Todos los dispositivos CDMA devolvieron el mismo valor (o la derivación del mismo valor) tanto para ANDROID_ID como para TelephonyManager.getDeviceId() , siempre que se haya agregado una cuenta de Google durante la configuración.
  6. Todavía no tuve la oportunidad de probar dispositivos GSM sin SIM, un dispositivo GSM sin cuenta de Google o ninguno de los dispositivos en modo avión.

Entonces, si quieres algo único para el dispositivo en sí, TM.getDeviceId() debería ser suficiente. Obviamente, algunos usuarios son más paranoicos que otros, por lo que podría ser útil marcar uno o más de estos identificadores, de modo que la cadena sea prácticamente única para el dispositivo, pero no identifique explícitamente el dispositivo real del usuario. Por ejemplo, usando String.hashCode() , combinado con un UUID:

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() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();

podría resultar en algo como: 00000000-54b3-e7c7-0000-000046bffd97

Funciona bastante bien para mí.

Como Richard menciona a continuación, no olvide que necesita permiso para leer las propiedades de TelephonyManager , así que agregue esto a su manifiesto:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

libs de importación

import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
digitos del device

¿Los dispositivos Android tienen una ID única y, en caso afirmativo, cuál es una forma sencilla de acceder a ella utilizando Java?




Como lo menciona Dave Webb, el Blog del desarrollador de Android tiene un artículo que cubre esto. Su solución preferida es rastrear las instalaciones de la aplicación en lugar de los dispositivos, y eso funcionará bien en la mayoría de los casos de uso. La publicación del blog te mostrará el código necesario para que funcione, y te recomiendo que lo consultes.

Sin embargo, la publicación del blog continúa discutiendo soluciones si necesita un identificador de dispositivo en lugar de un identificador de instalación de la aplicación. Hablé con alguien en Google para obtener una aclaración adicional sobre algunos elementos en caso de que necesite hacerlo. Esto es lo que descubrí sobre los identificadores de dispositivos que NO se mencionan en la publicación de blog mencionada anteriormente:

  • ANDROID_ID es el identificador de dispositivo preferido. ANDROID_ID es perfectamente confiable en versiones de Android <= 2.1 o> = 2.3. Solo 2.2 tiene los problemas mencionados en el post.
  • Varios dispositivos de varios fabricantes se ven afectados por el error ANDROID_ID en 2.2.
  • Por lo que he podido determinar, todos los dispositivos afectados tienen el mismo ANDROID_ID , que es 9774d56d682e549c . Que también es el mismo ID de dispositivo reportado por el emulador, por cierto.
  • Google cree que los OEM han solucionado el problema para muchos o la mayoría de sus dispositivos, pero pude verificar que a partir de abril de 2011, al menos, todavía es bastante fácil encontrar dispositivos que tengan el ANDROID_ID roto.

Basándome en las recomendaciones de Google, implementé una clase que generará un UUID único para cada dispositivo, utilizando ANDROID_ID como semilla cuando sea apropiado, recurriendo a TelephonyManager.getDeviceId () según sea necesario, y si eso falla, recurrir a un UUID único generado aleatoriamente esto se mantiene en los reinicios de la aplicación (pero no en las reinstalaciones de la aplicación).

Tenga en cuenta que para los dispositivos que tienen que retroceder en la ID del dispositivo, la ID única se mantendrá en los restablecimientos de fábrica. Esto es algo a tener en cuenta. Si necesita asegurarse de que un restablecimiento de fábrica restablecerá su ID única, puede considerar la posibilidad de recurrir directamente al UUID aleatorio en lugar de la ID del dispositivo.

Nuevamente, este código es para una ID de dispositivo, no una ID de instalación de la aplicación. Para la mayoría de las situaciones, un ID de instalación de la aplicación es probablemente lo que estás buscando. Pero si necesita una ID de dispositivo, entonces el siguiente código probablemente funcione para usted.

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

public class DeviceUuidFactory {

    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";
    protected volatile static UUID uuid;

    public DeviceUuidFactory(Context context) {
        if (uuid == null) {
            synchronized (DeviceUuidFactory.class) {
                if (uuid == null) {
                    final SharedPreferences prefs = context
                            .getSharedPreferences(PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null);
                    if (id != null) {
                        // Use the ids previously computed and stored in the
                        // prefs file
                        uuid = UUID.fromString(id);
                    } else {
                        final String androidId = Secure.getString(
                            context.getContentResolver(), Secure.ANDROID_ID);
                        // Use the Android ID unless it's broken, in which case
                        // fallback on deviceId,
                        // unless it's not available, then fallback on a random
                        // number which we store to a prefs file
                        try {
                            if (!"9774d56d682e549c".equals(androidId)) {
                                uuid = UUID.nameUUIDFromBytes(androidId
                                        .getBytes("utf8"));
                            } else {
                                final String deviceId = (
                                    (TelephonyManager) context
                                    .getSystemService(Context.TELEPHONY_SERVICE))
                                    .getDeviceId();
                                uuid = deviceId != null ? UUID
                                    .nameUUIDFromBytes(deviceId
                                            .getBytes("utf8")) : UUID
                                    .randomUUID();
                            }
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }
                        // Write the value out to the prefs file
                        prefs.edit()
                                .putString(PREFS_DEVICE_ID, uuid.toString())
                                .commit();
                    }
                }
            }
        }
    }

    /**
     * Returns a unique UUID for the current android device. As with all UUIDs,
     * this unique ID is "very highly likely" to be unique across all Android
     * devices. Much more so than ANDROID_ID is.
     * 
     * The UUID is generated by using ANDROID_ID as the base key if appropriate,
     * falling back on TelephonyManager.getDeviceID() if ANDROID_ID is known to
     * be incorrect, and finally falling back on a random UUID that's persisted
     * to SharedPreferences if getDeviceID() does not return a usable value.
     * 
     * In some rare circumstances, this ID may change. In particular, if the
     * device is factory reset a new device ID may be generated. In addition, if
     * a user upgrades their phone from certain buggy implementations of Android
     * 2.2 to a newer, non-buggy version of Android, the device ID may change.
     * Or, if a user uninstalls your app on a device that has neither a proper
     * Android ID nor a Device ID, this ID may change on reinstallation.
     * 
     * Note that if the code falls back on using TelephonyManager.getDeviceId(),
     * the resulting ID will NOT change after a factory reset. Something to be
     * aware of.
     * 
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID
     * directly.
     * 
     * @see http://code.google.com/p/android/issues/detail?id=10603
     * 
     * @return a UUID that may be used to uniquely identify your device for most
     *         purposes.
     */
    public UUID getDeviceUuid() {
        return uuid;
    }
}



También puede considerar la dirección MAC del adaptador de Wi-Fi. Recuperado así:

WifiManager wm = (WifiManager)Ctxt.getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo().getMacAddress();

Requiere permiso android.permission.ACCESS_WIFI_STATE en el manifiesto.

Se informa que está disponible incluso cuando el Wi-Fi no está conectado. Si Joe de la respuesta anterior le da a éste un intento en sus muchos dispositivos, sería bueno.

En algunos dispositivos, no está disponible cuando Wi-Fi está desactivado.

NOTA: Desde Android 6.x, devuelve una dirección mac falsa consistente: 02:00:00:00:00:00







El siguiente código devuelve el número de serie del dispositivo usando una API de Android oculta. Pero, este código no funciona en Samsung Galaxy Tab porque "ro.serialno" no está configurado en este dispositivo.

String serial = null;

try {
    Class<?> c = Class.forName("android.os.SystemProperties");
    Method get = c.getMethod("get", String.class);
    serial = (String) get.invoke(c, "ro.serialno");
}
catch (Exception ignored) {

}



Usando el código a continuación, puede obtener la ID de dispositivo única de un dispositivo con sistema operativo Android como una cadena.

deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 



Una cosa que añadiré: tengo una de esas situaciones únicas.

Utilizando:

deviceId = Secure.getString(this.getContext().getContentResolver(), Secure.ANDROID_ID);

Resulta que a pesar de que mi tableta Viewsonic G informa un DeviceID que no es nulo, cada una de las tabletas G informa el mismo número.

Lo hace interesante al jugar "Pocket Empires", que le brinda acceso instantáneo a la cuenta de alguien basada en el "único" ID de dispositivo.

Mi dispositivo no tiene una radio celular.




Agregue el siguiente código en el archivo de clase:

final TelephonyManager tm = (TelephonyManager) getBaseContext()
            .getSystemService(SplashActivity.TELEPHONY_SERVICE);
    final String tmDevice, tmSerial, androidId;
    tmDevice = "" + tm.getDeviceId();
    Log.v("DeviceIMEI", "" + tmDevice);
    tmSerial = "" + tm.getSimSerialNumber();
    Log.v("GSM devices Serial Number[simcard] ", "" + tmSerial);
    androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(),
            android.provider.Settings.Secure.ANDROID_ID);
    Log.v("androidId CDMA devices", "" + androidId);
    UUID deviceUuid = new UUID(androidId.hashCode(),
            ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
    String deviceId = deviceUuid.toString();
    Log.v("deviceIdUUID universally unique identifier", "" + deviceId);
    String deviceModelName = android.os.Build.MODEL;
    Log.v("Model Name", "" + deviceModelName);
    String deviceUSER = android.os.Build.USER;
    Log.v("Name USER", "" + deviceUSER);
    String devicePRODUCT = android.os.Build.PRODUCT;
    Log.v("PRODUCT", "" + devicePRODUCT);
    String deviceHARDWARE = android.os.Build.HARDWARE;
    Log.v("HARDWARE", "" + deviceHARDWARE);
    String deviceBRAND = android.os.Build.BRAND;
    Log.v("BRAND", "" + deviceBRAND);
    String myVersion = android.os.Build.VERSION.RELEASE;
    Log.v("VERSION.RELEASE", "" + myVersion);
    int sdkVersion = android.os.Build.VERSION.SDK_INT;
    Log.v("VERSION.SDK_INT", "" + sdkVersion);

Añadir en AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />



Hay muchos enfoques diferentes para ANDROID_IDsolucionar estos problemas (a nullveces, o los dispositivos de un modelo específico siempre devuelven la misma ID) con ventajas y desventajas:

  • Implementación de un algoritmo de generación de ID personalizado (basado en las propiedades del dispositivo que se supone que son estáticas y no cambian -> quién sabe)
  • Abusar de otras identificaciones como IMEI , número de serie, Wi-Fi / Bluetooth-MAC (no existirán en todos los dispositivos o se necesitarán permisos adicionales)

Yo mismo prefiero usar una implementación existente de OpenUDID (consulte https://github.com/ylechelle/OpenUDID ) para Android (consulte https://github.com/vieux/OpenUDID ). Es fácil de integrar y hace uso de los ANDROID_IDrecursos alternativos para los problemas mencionados anteriormente.




Mis dos centavos: NB, esto es para una ID única de dispositivo (error) , no para la instalación como se explica en el blog de desarrolladores de Android .

Es de destacar que la solution provista por @emmby recae en un ID por aplicación ya que las SharedPreferences no se sincronizan entre los procesos (consulte here y here ). Así que evité esto por completo.

En su lugar, encapsulé las diversas estrategias para obtener un ID (dispositivo) en una enumeración: cambiar el orden de las constantes enumistas afecta la prioridad de las diversas formas de obtener el ID. Se devuelve la primera ID que no es nula o se lanza una excepción (según las buenas prácticas de Java de no dar un significado nulo). Así, por ejemplo, primero tengo la TELEFONÍA, pero una buena opción predeterminada sería la beta ANDROID_ID :

import android.Manifest.permission;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;

// TODO : hash
public final class DeviceIdentifier {

    private DeviceIdentifier() {}

    /** @see http://code.google.com/p/android/issues/detail?id=10603 */
    private static final String ANDROID_ID_BUG_MSG = "The device suffers from "
        + "the Android ID bug - its ID is the emulator ID : "
        + IDs.BUGGY_ANDROID_ID;
    private static volatile String uuid; // volatile needed - see EJ item 71
    // need lazy initialization to get a context

    /**
     * Returns a unique identifier for this device. The first (in the order the
     * enums constants as defined in the IDs enum) non null identifier is
     * returned or a DeviceIDException is thrown. A DeviceIDException is also
     * thrown if ignoreBuggyAndroidID is false and the device has the Android ID
     * bug
     *
     * @param ctx
     *            an Android constant (to retrieve system services)
     * @param ignoreBuggyAndroidID
     *            if false, on a device with the android ID bug, the buggy
     *            android ID is not returned instead a DeviceIDException is
     *            thrown
     * @return a *device* ID - null is never returned, instead a
     *         DeviceIDException is thrown
     * @throws DeviceIDException
     *             if none of the enum methods manages to return a device ID
     */
    public static String getDeviceIdentifier(Context ctx,
            boolean ignoreBuggyAndroidID) throws DeviceIDException {
        String result = uuid;
        if (result == null) {
            synchronized (DeviceIdentifier.class) {
                result = uuid;
                if (result == null) {
                    for (IDs id : IDs.values()) {
                        try {
                            result = uuid = id.getId(ctx);
                        } catch (DeviceIDNotUniqueException e) {
                            if (!ignoreBuggyAndroidID)
                                throw new DeviceIDException(e);
                        }
                        if (result != null) return result;
                    }
                    throw new DeviceIDException();
                }
            }
        }
        return result;
    }

    private static enum IDs {
        TELEPHONY_ID {

            @Override
            String getId(Context ctx) {
                // TODO : add a SIM based mechanism ? tm.getSimSerialNumber();
                final TelephonyManager tm = (TelephonyManager) ctx
                        .getSystemService(Context.TELEPHONY_SERVICE);
                if (tm == null) {
                    w("Telephony Manager not available");
                    return null;
                }
                assertPermission(ctx, permission.READ_PHONE_STATE);
                return tm.getDeviceId();
            }
        },
        ANDROID_ID {

            @Override
            String getId(Context ctx) throws DeviceIDException {
                // no permission needed !
                final String andoidId = Secure.getString(
                    ctx.getContentResolver(),
                    android.provider.Settings.Secure.ANDROID_ID);
                if (BUGGY_ANDROID_ID.equals(andoidId)) {
                    e(ANDROID_ID_BUG_MSG);
                    throw new DeviceIDNotUniqueException();
                }
                return andoidId;
            }
        },
        WIFI_MAC {

            @Override
            String getId(Context ctx) {
                WifiManager wm = (WifiManager) ctx
                        .getSystemService(Context.WIFI_SERVICE);
                if (wm == null) {
                    w("Wifi Manager not available");
                    return null;
                }
                assertPermission(ctx, permission.ACCESS_WIFI_STATE); // I guess
                // getMacAddress() has no java doc !!!
                return wm.getConnectionInfo().getMacAddress();
            }
        },
        BLUETOOTH_MAC {

            @Override
            String getId(Context ctx) {
                BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
                if (ba == null) {
                    w("Bluetooth Adapter not available");
                    return null;
                }
                assertPermission(ctx, permission.BLUETOOTH);
                return ba.getAddress();
            }
        }
        // TODO PSEUDO_ID
        // http://www.pocketmagic.net/2011/02/android-unique-device-id/
        ;

        static final String BUGGY_ANDROID_ID = "9774d56d682e549c";
        private final static String TAG = IDs.class.getSimpleName();

        abstract String getId(Context ctx) throws DeviceIDException;

        private static void w(String msg) {
            Log.w(TAG, msg);
        }

        private static void e(String msg) {
            Log.e(TAG, msg);
        }
    }

    private static void assertPermission(Context ctx, String perm) {
        final int checkPermission = ctx.getPackageManager().checkPermission(
            perm, ctx.getPackageName());
        if (checkPermission != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Permission " + perm + " is required");
        }
    }

    // =========================================================================
    // Exceptions
    // =========================================================================
    public static class DeviceIDException extends Exception {

        private static final long serialVersionUID = -8083699995384519417L;
        private static final String NO_ANDROID_ID = "Could not retrieve a "
            + "device ID";

        public DeviceIDException(Throwable throwable) {
            super(NO_ANDROID_ID, throwable);
        }

        public DeviceIDException(String detailMessage) {
            super(detailMessage);
        }

        public DeviceIDException() {
            super(NO_ANDROID_ID);
        }
    }

    public static final class DeviceIDNotUniqueException extends
            DeviceIDException {

        private static final long serialVersionUID = -8940090896069484955L;

        public DeviceIDNotUniqueException() {
            super(ANDROID_ID_BUG_MSG);
        }
    }
}



Otra forma es usar /sys/class/android_usb/android0/iSerialen una aplicación sin ningún tipo de permisos.

user@creep:~$ adb shell ls -l /sys/class/android_usb/android0/iSerial
-rw-r--r-- root     root         4096 2013-01-10 21:08 iSerial
user@creep:~$ adb shell cat /sys/class/android_usb/android0/iSerial
0A3CXXXXXXXXXX5

Para hacer esto en Java uno solo usaría FileInputStream para abrir el archivo iSerial y leer los caracteres. Solo asegúrese de envolverlo en un controlador de excepciones, ya que no todos los dispositivos tienen este archivo.

Se sabe que al menos los siguientes dispositivos tienen este archivo legible en todo el mundo:

  • Galaxy Nexus
  • Nexus S
  • Motorola Xoom 3G
  • Toshiba AT300
  • HTC One V
  • Mini MK802
  • Samsung Galaxy S II

También puede ver la publicación de mi blog. Filtrar el número de serie del hardware de Android a aplicaciones sin privilegios donde discuto qué otros archivos están disponibles para obtener información.




Utilizo el siguiente código para obtener IMEIo usar Secure. ANDROID_IDcomo alternativa, cuando el dispositivo no tiene capacidades de teléfono:

String identifier = null;
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE));
if (tm != null)
      identifier = tm.getDeviceId();
if (identifier == null || identifier .length() == 0)
      identifier = Secure.getString(activity.getContentResolver(),Secure.ANDROID_ID);



ID de instancia de Google

Lanzado en I / O 2015; en Android requiere servicios de juego 7.5.

https://developers.google.com/instance-id/
https://developers.google.com/instance-id/guides/android-implementation

InstanceID iid = InstanceID.getInstance( context );   // Google docs are wrong - this requires context
String id = iid.getId();  // blocking call

Parece que Google pretende que esta identificación se use para identificar instalaciones en Android, Chrome e iOS.

Identifica una instalación en lugar de un dispositivo, pero nuevamente, ANDROID_ID (que es la respuesta aceptada) ahora ya no identifica dispositivos. Con el tiempo de ejecución ARC, se genera un nuevo ANDROID_ID para cada instalación ( detalles aquí ), al igual que este nuevo ID de instancia. Además, creo que identificar instalaciones (no dispositivos) es lo que la mayoría de nosotros estamos buscando.

Las ventajas del ID de instancia

Me parece que Google pretende que se use para este propósito (identificando sus instalaciones), es multiplataforma y se puede usar para otros fines (consulte los enlaces anteriores).

Si usa GCM, finalmente necesitará usar este ID de instancia porque lo necesita para obtener el token de GCM (que reemplaza al antiguo ID de registro de GCM).

Las desventajas / problemas

En la implementación actual (GPS 7.5), la ID de instancia se recupera de un servidor cuando la aplicación lo solicita. Esto significa que la llamada de arriba es una llamada de bloqueo: en mi prueba no científica demora entre 1 y 3 segundos si el dispositivo está en línea, y entre 0,5 y 1,0 segundos si está desconectado (probablemente este es el tiempo que espera antes de darse por vencido y generar un mensaje). Identificación aleatoria). Esto fue probado en América del Norte en Nexus 5 con Android 5.1.1 y GPS 7.5.

Si utiliza la identificación para los fines que pretenden, por ejemplo. Autenticación de la aplicación, identificación de la aplicación, GCM: creo que esto de 1 a 3 segundos podría ser una molestia (dependiendo de su aplicación, por supuesto)




Hay más de 30 respuestas aquí y algunas son iguales y otras son únicas. Esta respuesta se basa en algunas de esas respuestas. Una de ellas es la respuesta de @Lenn Dolling.

Combina 3 ID y crea una cadena hexadecimal de 32 dígitos. Me ha funcionado muy bien.

Las 3 ID son:
Pseudo-ID : se genera según las especificaciones físicas del dispositivo
ANDROID_ID - Settings.Secure.ANDROID_ID
Dirección de Bluetooth - Dirección del adaptador de Bluetooth

Devolverá algo como esto: 551F27C060712A72730B0A0F734064B1

Nota: siempre puedes agregar más ID a la longIdcadena. Por ejemplo, número de serie. Dirección del adaptador wifi. IMEI. De esta manera lo estás haciendo más único por dispositivo.

@SuppressWarnings("deprecation")
@SuppressLint("HardwareIds")
public static String generateDeviceIdentifier(Context context) {

        String pseudoId = "35" +
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.CPU_ABI.length() % 10 +
                Build.DEVICE.length() % 10 +
                Build.DISPLAY.length() % 10 +
                Build.HOST.length() % 10 +
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +
                Build.MODEL.length() % 10 +
                Build.PRODUCT.length() % 10 +
                Build.TAGS.length() % 10 +
                Build.TYPE.length() % 10 +
                Build.USER.length() % 10;

        String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        String btId = "";

        if (bluetoothAdapter != null) {
            btId = bluetoothAdapter.getAddress();
        }

        String longId = pseudoId + androidId + btId;

        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(longId.getBytes(), 0, longId.length());

            // get md5 bytes
            byte md5Bytes[] = messageDigest.digest();

            // creating a hex string
            String identifier = "";

            for (byte md5Byte : md5Bytes) {
                int b = (0xFF & md5Byte);

                // if it is a single digit, make sure it have 0 in front (proper padding)
                if (b <= 0xF) {
                    identifier += "0";
                }

                // add number to string
                identifier += Integer.toHexString(b);
            }

            // hex string to uppercase
            identifier = identifier.toUpperCase();
            return identifier;
        } catch (Exception e) {
            Log.e("TAG", e.toString());
        }
        return "";
}



TelephonyManger.getDeviceId () Devuelve el ID de dispositivo único, por ejemplo, el IMEI para GSM y el MEID o ESN para teléfonos CDMA.

final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);            
String myAndroidDeviceId = mTelephony.getDeviceId(); 

Pero recomiendo usar:

Settings.Secure.ANDROID_ID que devuelve la ID de Android como una única cadena hex de 64 bits.

    String   myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 

A veces, TelephonyManger.getDeviceId () devolverá un valor nulo, por lo que para asegurar una identificación única, usarás este método:

public String getUniqueID(){    
    String myAndroidDeviceId = "";
    TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    if (mTelephony.getDeviceId() != null){
        myAndroidDeviceId = mTelephony.getDeviceId(); 
    }else{
         myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 
    }
    return myAndroidDeviceId;
}





Related