¿Hay un ID de dispositivo Android único?


Los dispositivos Android tienen un ID único, y si es así, ¿cuál es una forma sencilla de acceder a él usando Java?

Author: alamshahbaz16497, 2010-05-07

30 answers

Settings.Secure#ANDROID_ID devuelve el ID de Android como un único para cada usuario 64-un poco de cuerda hexagonal.

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID); 
 1741
Author: Anthony Forloney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-24 13:27:27

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, echa un vistazo a La respuesta de Anthony .

Divulgación completa: mi aplicación utilizó el enfoque a continuación originalmente, pero ya no utiliza este enfoque, y ahora utilizamos el enfoque descrito en el Android Developer Blog entrada que respuesta de emmby's enlaces a (a saber, generar y guardar UUID#randomUUID()).


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

Basado en 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 SIM) devolvieron un valor para TelephonyManager.getSimSerialNumber()
  3. Todos los dispositivos CDMA devolvieron null 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 derivación del mismo valor) tanto para ANDROID_ID como para TelephonyManager.getDeviceId() -- siempre y cuando 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 agregada, o cualquiera de los dispositivos en modo avión.

Así que 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 hash 1 o más de estos identificadores, de modo que la cadena sigue siendo virtualmente única para el dispositivo, pero no identifica 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 olvides que necesitas permiso para leer las propiedades TelephonyManager, agrega esto a tu 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;
 1068
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-01 14:37:26

Última actualización: 6/2/15


Después de leer cada publicación de Stack Overflow sobre la creación de un ID único, el blog de desarrolladores de Google y la documentación de Android, siento que el 'Pseudo ID' es la mejor opción posible.

Problema principal: Hardware vs Software

Hardware

  • Los usuarios pueden cambiar su hardware, tableta o teléfono Android, por lo que los ID únicos basados en el hardware no son buenas ideas para RASTREAR USUARIOS
  • Para SEGUIMIENTO HARDWARE , esta es una gran idea

Software

  • Los usuarios pueden borrar / cambiar su ROM si están rooteados
  • Puede realizar un seguimiento de los usuarios en todas las plataformas (iOS, Android, Windows y Web)
  • Lo mejor para RASTREAR A UN USUARIO INDIVIDUAL con su consentimiento {[26] } es simplemente tener que iniciar sesión (hacer esto sin problemas usando OAuth)

Desglose general con Android

- Garantizar la unicidad (incluir dispositivos arraigados) para API > = 9/10 (99.5% de los dispositivos Android)

- Sin permisos adicionales

Código Psuedo:

if API >= 9/10: (99.5% of devices)

return unique ID containing serial id (rooted devices may be different)

else

return unique ID of build information (may overlap data - API < 9)

Gracias a @stansult por publicar todas nuestras opciones (en esta pregunta de desbordamiento de pila).

Lista de opciones-razones por las que / por qué no usarlas:

  • Correo electrónico del usuario - Software

  • Número de teléfono del Usuario-Software

    • Los usuarios podrían cambiar los números de teléfono-MUY improbable
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • IMEI-Hardware (solo teléfonos, necesidades android.permission.READ_PHONE_STATE)

    • La mayoría de los usuarios odian el hecho de que dice "Llamadas telefónicas" en el permiso. Algunos usuarios dan malas calificaciones, porque creen que simplemente estás robando su personal información, cuando todo lo que realmente quieres hacer es rastrear las instalaciones del dispositivo. Es obvio que estás recopilando datos.
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • Android ID - Hardware (puede ser nulo, puede cambiar al restablecer los valores de fábrica, puede alterarse en un dispositivo rooteado)

    • Dado que puede ser 'null', podemos comprobar si es 'null' y cambiar su valor, pero esto significa que ya no será único.
    • Si tiene un usuario con un dispositivo de restablecimiento de fábrica, el valor puede tener cambiado o alterado en el dispositivo rooteado por lo que puede haber entradas duplicadas si está rastreando las instalaciones de los usuarios.
  • WLAN Dirección MAC-Hardware (necesidades android.permission.ACCESS_WIFI_STATE)

    • Esta podría ser la segunda mejor opción, pero todavía está recopilando y almacenando un identificador único que proviene directamente de un usuario. Es obvio que estás recopilando datos.
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
  • Dirección MAC Bluetooth - Hardware (dispositivos con Bluetooth, necesidades android.permission.BLUETOOTH)

    • La mayoría de las aplicaciones en el mercado no usan Bluetooth, por lo que si su aplicación no usa Bluetooth y está incluyendo esto, el usuario podría sospechar.
    • <uses-permission android:name="android.permission.BLUETOOTH "/>
  • Pseudo-Único ID-Software (para todos los dispositivos Android)

    • Muy posible, puede contener colisiones-Ver mi método publicado a continuación!
    • Esto le permite tener un ID 'casi único' del usuario sin tomar nada que sea privado. Puede crear su propio ID anónimo a partir de la información del dispositivo.

Sé que no hay ninguna forma 'perfecta' de obtener un ID único sin usar permisos; sin embargo, a veces solo necesitamos rastrear la instalación del dispositivo. Cuando se trata de crear un ID único, podemos crear un 'pseudo id único' basado únicamente en la información que la API de Android nos da sin usar extra permiso. De esta manera, podemos mostrar el respeto del usuario y tratar de ofrecer una buena experiencia de usuario también.

Con un identificador pseudo-único, realmente solo se encuentra con el hecho de que puede haber duplicados basados en el hecho de que hay dispositivos similares. Puede modificar el método combinado para hacerlo más único; sin embargo, algunos desarrolladores necesitan rastrear las instalaciones de los dispositivos y esto hará el truco o el rendimiento basado en dispositivos similares.

API > = 9:

Si su dispositivo Android es API 9 o más, esto está garantizado para ser único debido a la ' Build.Campo de SERIE.

RECUERDE , técnicamente solo se está perdiendo alrededor del 0.5% de los usuarios que tienen API . Así que usted puede centrarse en el resto: Este es el 99,5% de los usuarios!

API

Si el dispositivo Android del usuario es inferior a la API 9; con suerte, no han hecho un restablecimiento de fábrica y su 'Seguro.ANDROID_ID 'se conservará o no 'null'. (ver http://developer.android.com/about/dashboards/index.html )

Si todo lo demás falla:

Si todo lo demás falla, si el usuario tiene una API inferior a 9 (inferior a Gingerbread), ha restablecido su dispositivo o 'Seguro.ANDROID_ID 'devuelve ' null', luego simplemente el ID devuelto se basará únicamente en la información de su dispositivo Android. Aquí es donde pueden ocurrir las colisiones.

Cambios:

  • Eliminado ' Android.SECURE_ID ' debido a que los reinicios de fábrica podrían causar el valor a cambiar
  • Editó el código para cambiar en API
  • Cambió el Pseudo

Por favor, echa un vistazo al siguiente método:

/**
 * Return pseudo unique ID
 * @return ID
 */
public static String getUniquePsuedoID() {
    // If all else fails, if the user does have lower than API 9 (lower
    // than Gingerbread), has reset their device or 'Secure.ANDROID_ID'
    // returns 'null', then simply the ID returned will be solely based
    // off their Android device information. This is where the collisions
    // can happen.
    // Thanks http://www.pocketmagic.net/?p=1662!
    // Try not to use DISPLAY, HOST or ID - these items could change.
    // If there are collisions, there will be overlapping data
    String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);

    // Thanks to @Roman SL!
    // https://stackoverflow.com/a/4789483/950427
    // Only devices with API >= 9 have android.os.Build.SERIAL
    // http://developer.android.com/reference/android/os/Build.html#SERIAL
    // If a user upgrades software or roots their device, there will be a duplicate entry
    String serial = null;
    try {
        serial = android.os.Build.class.getField("SERIAL").get(null).toString();

        // Go ahead and return the serial for api => 9
        return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
    } catch (Exception exception) {
        // String needs to be initialized
        serial = "serial"; // some value
    }

    // Thanks @Joe!
    // https://stackoverflow.com/a/2853253/950427
    // Finally, combine the values we have found by using the UUID class to create a unique identifier
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}

Nuevo (para aplicaciones con anuncios Y Servicios de Google Play):

Desde la consola del desarrollador de Google Play:

A partir del 1 de agosto de 2014, la Política del Programa para Desarrolladores de Google Play requiere que todas las cargas y actualizaciones de aplicaciones nuevas utilicen el ID de publicidad en lugar de cualquier otro persistente identificadores para cualquier propósito publicitario. Más información

Aplicación :

Permiso:

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

Código:

import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import java.io.IOException;
...

// Do not call this function from the main thread. Otherwise, 
// an IllegalStateException will be thrown.
public void getIdThread() {

  Info adInfo = null;
  try {
    adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);

  } catch (IOException exception) {
    // Unrecoverable error connecting to Google Play services (e.g.,
    // the old version of the service doesn't support getting AdvertisingId).

  } catch (GooglePlayServicesAvailabilityException exception) {
    // Encountered a recoverable error connecting to Google Play services. 

  } catch (GooglePlayServicesNotAvailableException exception) {
    // Google Play services is not available entirely.
  }
  final String id = adInfo.getId();
  final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
}

Fuente / Documentos:

Http://developer.android.com/google/play-services/id.html http://developer.android.com/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html

Importante:

Se pretende que el ID de publicidad completamente reemplazar existente uso de otros identificadores con fines publicitarios (como el uso de ANDROID_ID en Ajustes.Seguro) cuando los servicios de Google Play están disponibles. Caso cuando los servicios de Google Play no están disponibles se indican mediante un GooglePlayServicesNotAvailableException siendo lanzado por getAdvertisingIdInfo().

Advertencia, los usuarios pueden restablecer:

Http://en.kioskea.net/faq/34732-android-reset-your-advertising-id

He tratado de hacer referencia a cada enlace que Tomé información de. Si falta y necesita ser incluido, por favor comente!

Google Player Services InstanceID

Https://developers.google.com/instance-id /

 374
Author: Jared Burrows,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-15 08:37:26

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

Sin embargo, la entrada del blog pasa a discutir las 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 algunas aclaraciones adicionales sobre algunos elementos en el caso de que sea necesario hacerlo. Esto es lo que descubrí sobre los identificadores de dispositivos que NO se mencionan en la publicación del blog antes mencionada:

  • ANDROID_ID es el identificador de dispositivo preferido. ANDROID_ID es perfectamente confiable en versiones de Android = 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 estado capaz de 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 fabricantes de equipos originales han parcheado el problema para muchos o la mayoría de sus dispositivos, pero pude verificar que a partir de principios de abril de 2011, al menos, todavía es bastante fácil encontrar dispositivos que tienen el ANDROID_ID roto.

Basado 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 al Telefonymanager.getDeviceId() según sea necesario, y si eso falla, recurrir a un UUID único generado aleatoriamente que se mantiene a través de los reinicios de la aplicación (pero no las reinstalaciones de la aplicación).

Tenga en cuenta que para los dispositivos que tienen que recurrir al ID de dispositivo, el ID único persistirá entre los reinicios de fábrica. Esto es algo que hay que tener en cuenta. Si necesita asegurarse de que una fábrica restablecer restablecerá su ID único, es posible que desee considerar volver directamente al UUID aleatorio en lugar del ID del dispositivo.

Nuevamente, este código es para un ID de dispositivo, no para un ID de instalación de 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 un ID de dispositivo, 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;
    }
}
 318
Author: emmby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-10 14:22:51

Aquí está el código que Reto Meier usó en la presentación de Google I/O este año para obtener un id único para el usuario:

private static String uniqueID = null;
private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";

public synchronized static String id(Context context) {
    if (uniqueID == null) {
        SharedPreferences sharedPrefs = context.getSharedPreferences(
                PREF_UNIQUE_ID, Context.MODE_PRIVATE);
        uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
        if (uniqueID == null) {
            uniqueID = UUID.randomUUID().toString();
            Editor editor = sharedPrefs.edit();
            editor.putString(PREF_UNIQUE_ID, uniqueID);
            editor.commit();
        }
    }
    return uniqueID;
}

Si combina esto con una estrategia de copia de seguridad para enviar preferencias a la nube (también descrita en la charla de Reto , debe tener un id que se vincule a un usuario y se quede después de que el dispositivo haya sido borrado o incluso reemplazado. Planeo usar esto en analytics en el futuro (en otras palabras, aún no he hecho ese poco :).

 166
Author: Anthony Nolan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 14:18:21

También puede considerar la dirección MAC del adaptador Wi-Fi. Recuperada 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 Wi-Fi no está conectado. Si Joe de la respuesta anterior le da a éste una oportunidad en sus muchos dispositivos, eso estaría bien.

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

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

 98
Author: Seva Alekseyev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-13 08:52:50

Hay información bastante útilaquí.

Cubre cinco tipos de ID diferentes:

  1. IMEI (solo para dispositivos Android con uso de teléfono; necesita android.permission.READ_PHONE_STATE)
  2. Pseudo-Único ID (para todos los dispositivos Android)
  3. ID de Android (puede ser nulo, puede cambiar al restablecer los valores de fábrica, puede alterarse en el teléfono rooteado)
  4. Dirección MAC WLAN cadena (necesita android.permission.ACCESS_WIFI_STATE)
  5. BT Dirección MAC cadena (dispositivos con Bluetooth, necesita android.permission.BLUETOOTH)
 80
Author: stansult,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-08 02:16:52

El Blog oficial de Desarrolladores de Android ahora tiene un artículo completo sobre este mismo tema, Identificación de Instalaciones de Aplicaciones.

 45
Author: BoD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 14:00:25

En Google I/O Reto Meier lanzó una respuesta sólida a cómo abordar esto que debería satisfacer las necesidades de la mayoría de los desarrolladores para rastrear a los usuarios en todas las instalaciones. Anthony Nolan muestra la dirección en su respuesta, pero pensé en escribir el enfoque completo para que otros puedan ver fácilmente cómo hacerlo (me llevó un tiempo averiguar los detalles).

Este enfoque le dará un ID de usuario anónimo y seguro que será persistente para el usuario en diferentes dispositivos (basado en cuenta principal de Google) y en todas las instalaciones. El enfoque básico es generar un ID de usuario aleatorio y almacenarlo en las preferencias compartidas de las aplicaciones. A continuación, utiliza el agente de copia de seguridad de Google para almacenar las preferencias compartidas vinculadas a la cuenta de Google en la nube.

Repasemos el enfoque completo. Primero, necesitamos crear una copia de seguridad para nuestras preferencias de Shared usando el Servicio de Copia de seguridad de Android. Comience por registrar su aplicación a través de http://developer.android.com/google/backup/signup.html.

Google le dará una clave de servicio de copia de seguridad que necesita agregar al manifiesto. También necesita decirle a la aplicación que use el BackupAgent de la siguiente manera:

<application android:label="MyApplication"
         android:backupAgent="MyBackupAgent">
    ...
    <meta-data android:name="com.google.android.backup.api_key"
        android:value="your_backup_service_key" />
</application>

Luego necesita crear el agente de copia de seguridad y decirle que use el agente auxiliar para sharedpreferences:

public class MyBackupAgent extends BackupAgentHelper {
    // The name of the SharedPreferences file
    static final String PREFS = "user_preferences";

    // A key to uniquely identify the set of backup data
    static final String PREFS_BACKUP_KEY = "prefs";

    // Allocate a helper and add it to the backup agent
    @Override
    public void onCreate() {
        SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this,          PREFS);
        addHelper(PREFS_BACKUP_KEY, helper);
    }
}

Para completar la copia de seguridad necesita crear una instancia de BackupManager en su actividad principal:

BackupManager backupManager = new BackupManager(context);

Finalmente crea un ID de usuario, si aún no existe, y guárdalo en SharedPreferences:

  public static String getUserID(Context context) {
            private static String uniqueID = null;
        private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
    if (uniqueID == null) {
        SharedPreferences sharedPrefs = context.getSharedPreferences(
                MyBackupAgent.PREFS, Context.MODE_PRIVATE);
        uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
        if (uniqueID == null) {
            uniqueID = UUID.randomUUID().toString();
            Editor editor = sharedPrefs.edit();
            editor.putString(PREF_UNIQUE_ID, uniqueID);
            editor.commit();

            //backup the changes
            BackupManager mBackupManager = new BackupManager(context);
            mBackupManager.dataChanged();
        }
    }

    return uniqueID;
}

Este User_ID ahora será persistente en todas las instalaciones, incluso si el usuario mueve el dispositivo.

Para más información sobre este enfoque ver La charla de Reto.

Y para obtener detalles completos de cómo implementar el agente de copia de seguridad, consulte Copia de Seguridad de Datos. Recomiendo particularmente la sección en la parte inferior sobre pruebas, ya que la copia de seguridad no ocurre instantáneamente y, por lo tanto, para probar, debe forzar la copia de seguridad.

 36
Author: TechnoTony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 14:31:17

El siguiente código devuelve el número de serie del dispositivo mediante 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) {

}
 33
Author: Roman SL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 20:08:31

Creo que esta es una forma segura de construir un esqueleto para una identificación única... compruébelo.

Pseudo-Único ID, que funciona en todos los dispositivos Android Algunos dispositivos no tienen un teléfono (por ejemplo. Tablets) o por alguna razón, no desea incluir el permiso READ_PHONE_STATE. Todavía puede leer detalles como la versión de la ROM, el nombre del fabricante, el tipo de CPU y otros detalles de hardware, que serán muy adecuados si desea usar el ID para una verificación de clave en serie u otros fines generales. id calculado de esta manera no será único: es posible encontrar dos dispositivos con el mismo ID (basado en el mismo hardware y la imagen ROM), pero los cambios en las aplicaciones del mundo real son insignificantes. Para este propósito puede usar la clase Build:

String m_szDevIDShort = "35" + //we make this look like a valid IMEI
            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 ; //13 digits

La mayoría de los miembros de Build son cadenas, lo que estamos haciendo aquí es tomar su longitud y transformarla vía módulo en un dígito. Tenemos 13 de estos dígitos y estamos agregando dos más en frente (35) para tener el mismo tamaño de ID que el IMEI (15 dígitos). Hay otras posibilidades aquí están bien, solo echar un vistazo a estas cadenas. Devuelve algo como 355715565309247. No se requiere ningún permiso especial, por lo que este enfoque es muy conveniente.


(Información adicional: La técnica dada anteriormente fue copiada de un artículo sobre Pocket Magic.)

 32
Author: Lenn Dolling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-22 17:30:31

Usando el siguiente código, puede obtener el ID de dispositivo único de un dispositivo con sistema operativo Android como una cadena.

deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 
 21
Author: Mohit Kanada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 14:10:42

Se agregó un campo Serial a la clase Build en el nivel de API 9 (Android 2.3 - Gingerbread). La documentación dice que representa el número de serie del hardware. Por lo tanto debe ser único, si existe en el dispositivo.

No se si es realmente soportado (=not null) por todos los dispositivos con nivel de API >= 9.

 18
Author: rony l,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 20:09:54

Una cosa voy a añadir - Tengo una de esas situaciones únicas.

Usando:

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

Resulta que a pesar de que mi tableta Viewsonic G reporta un ID de dispositivo que no es Nulo, cada tableta G reporta el mismo número.

Hace que sea interesante jugar "Pocket Empires", que te da acceso instantáneo a la cuenta de alguien basado en el ID de dispositivo "único".

Mi dispositivo no tiene un radio celular.

 15
Author: Tony Maro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-21 20:46:43

Para obtener instrucciones detalladas sobre cómo obtener un identificador único para cada dispositivo Android desde el que se instala la aplicación, consulte la publicación oficial del Blog de Desarrolladores de Android Identificación de Instalaciones de Aplicaciones.

Parece que la mejor manera es que usted mismo genere uno al momento de la instalación y posteriormente lo lea cuando se vuelva a lanzar la aplicación.

Personalmente encuentro esto aceptable pero no ideal. Ningún identificador proporcionado por Android funciona en todas las instancias como la mayoría dependen de los estados de radio del teléfono (Wi-Fi on / off, celular on / off, Bluetooth on / off). Los demás, como Settings.Secure.ANDROID_ID, deben ser implementados por el fabricante y no se garantiza que sean únicos.

El siguiente es un ejemplo de escritura de datos en un archivo de instalación que se almacenaría junto con cualquier otro dato que la aplicación guarde localmente.

public class Installation {
    private static String sID = null;
    private static final String INSTALLATION = "INSTALLATION";

    public synchronized static String id(Context context) {
        if (sID == null) {
            File installation = new File(context.getFilesDir(), INSTALLATION);
            try {
                if (!installation.exists())
                    writeInstallationFile(installation);
                sID = readInstallationFile(installation);
            } 
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return sID;
    }

    private static String readInstallationFile(File installation) throws IOException {
        RandomAccessFile f = new RandomAccessFile(installation, "r");
        byte[] bytes = new byte[(int) f.length()];
        f.readFully(bytes);
        f.close();
        return new String(bytes);
    }

    private static void writeInstallationFile(File installation) throws IOException {
        FileOutputStream out = new FileOutputStream(installation);
        String id = UUID.randomUUID().toString();
        out.write(id.getBytes());
        out.close();
    }
}
 14
Author: Kevin Parker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 14:15:45

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" />
 10
Author: Android,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-18 04:17:20

El ID de dispositivo único de un dispositivo con sistema operativo Android como cadena, utilizando TelephonyManager y ANDROID_ID, se obtiene mediante:

String deviceId;
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
    deviceId = mTelephony.getDeviceId();
}
else {
    deviceId = Secure.getString(
                   getApplicationContext().getContentResolver(),
                   Secure.ANDROID_ID);
}

Pero recomiendo encarecidamente un método sugerido por Google, ver Identificación de Instalaciones de Aplicaciones.

 9
Author: Jorgesys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-26 04:51:45

Hay muchos enfoques diferentes para solucionar esos ANDROID_ID problemas (pueden ser null a veces o los dispositivos de un modelo específico siempre devuelven el mismo ID) con pros y contras:

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

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

 8
Author: Andreas Klöber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 14:26:06

Qué tal el IMEI. Eso es único para Android u otros dispositivos móviles.

 7
Author: Elzo Valugi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-14 20:01:22

My two cents - NB esto es para un device (err) unique ID - no el de instalación como se discute en el Android developers's blog.

Cabe destacar que la solución proporcionada por @emmby cae en un ID por aplicación ya que las preferencias de Shared no están sincronizadas entre procesos (ver aquí y aquí). Así que evité esto por completo.

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

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);
        }
    }
}
 7
Author: Mr_and_Mrs_D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36

Así es como estoy generando el id único:

public static String getDeviceId(Context ctx)
{
    TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);

    String tmDevice = tm.getDeviceId();
    String androidId = Secure.getString(ctx.getContentResolver(), Secure.ANDROID_ID);
    String serial = null;
    if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) serial = Build.SERIAL;

    if(tmDevice != null) return "01" + tmDevice;
    if(androidId != null) return "02" + androidId;
    if(serial != null) return "03" + serial;
    // other alternatives (i.e. Wi-Fi MAC, Bluetooth MAC, etc.)

    return null;
}
 6
Author: Eng.Fouad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-27 18:34:47

Otra forma es usar /sys/class/android_usb/android0/iSerial en una aplicación sin ningún tipo de permiso.

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 un FileInputStream para abrir el archivo iSerial y leer los caracteres. Solo asegúrese de envolverlo en un controlador de excepciones, porque 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 Uno V
  • Mini MK802
  • Samsung Galaxy S II

También puedes ver mi entrada de blogFiltrar el número de serie del hardware de Android a aplicaciones sin privilegios donde discuto qué otros archivos están disponibles para información.

 6
Author: insitusec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-09 14:41:44

Para el reconocimiento de hardware de un dispositivo Android específico, puede verificar las direcciones MAC.

Puedes hacerlo de esa manera:

En AndroidManifest.xml

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

Ahora en su código:

List<NetworkInterface> interfacesList = Collections.list(NetworkInterface.getNetworkInterfaces());

for (NetworkInterface interface : interfacesList) {
   // This will give you the interface MAC ADDRESS
   interface.getHardwareAddress();
}

En cada dispositivo Android su es al menos un "wlan0" Bruja interfaz es el chip WI-FI. Este código funciona incluso cuando WI-FI no está activado.

P.d. Son un montón de otras interfaces que obtendrá de la lista que contiene MAC, pero esto puede cambiar entre Teléfono.

 6
Author: Ilan.b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-09 05:19:39

Utilizo el siguiente código para obtener el IMEI o usar Secure.ANDROID_ID como 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);
 6
Author: Asaf Pinhassi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-20 03:21:09

Más específicamente, Settings.Secure.ANDROID_ID. Esta es una cantidad de 64 bits que se genera y almacena cuando el dispositivo arranca por primera vez. Se restablece cuando se borra el dispositivo.

ANDROID_ID parece una buena opción para un identificador de dispositivo único. Hay desventajas: Primero, no es 100% confiable en versiones de Android anteriores a 2.2 (“Froyo”). También, ha habido al menos un error ampliamente observado en un teléfono popular de un fabricante importante, donde cada instancia tiene el mismo ANDROID_ID.

 6
Author: mumu123,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-20 03:21:40

ID de instancia de Google

Lanzado en E/S 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 tiene la intención de que este ID se utilice para identificar las instalaciones a través de Android, Chrome, y iOS.

Identifica una instalación en lugar de un dispositivo, pero de nuevo, ANDROID_ID (que es el respuesta aceptada) ya no identifica los dispositivos tampoco. Con el tiempo de ejecución de 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 de instance ID

Me parece que Google tiene la intención de que se utilice para este propósito( identificar sus instalaciones), es multiplataforma, y puede ser se utiliza para una serie de otros fines (ver los enlaces anteriores).

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

Desventajas / problemas

En la implementación actual (GPS 7.5), el ID de instancia se recupera de un servidor cuando la aplicación lo solicita. Esto significa que la llamada anterior es una llamada de bloqueo - en mis pruebas no científicas se tarda 1-3 segundos si el dispositivo está en línea, y 0.5-1.0 segundos si está fuera de línea (presumiblemente este es el tiempo que espera antes de darse por vencido y generar un ID aleatorio). Esto fue probado en América del Norte en Nexus 5 con Android 5.1.1 y GPS 7.5.

Si utiliza el ID para los fines que pretenden-por ejemplo. autenticación de aplicaciones, identificación de aplicaciones, GCM-Creo que este 1-3 segundos podría ser una molestia (dependiendo de su aplicación, por supuesto).

 5
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:37

Id de mac de dispositivo Android también es un id único, no cambiará supongamos que si formateamos el dispositivo en sí, utilizando el siguiente código para obtener id de mac

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = manager.getConnectionInfo();
String address = info.getMacAddress();

También no se olvide de agregar los permisos apropiados en su AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
 5
Author: Baskaran Veerabathiran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-03 11:02:10

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

Combina 3 ID y crea una cadena hexadecimal de 32 dígitos. Ha funcionado muy bien para mí.

3 IDs son:
Pseudo-ID - Se genera en función de las especificaciones del dispositivo físico
ANDROID_ID - Settings.Secure.ANDROID_ID
Dirección Bluetooth - Dirección del adaptador Bluetooth

Devolverá algo así: 551F27C060712A72730B0A0F734064B1

Nota: Siempre puede agregar más ID a la cadena longId. Por ejemplo, Serial #. 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 "";
}
 5
Author: ᴛʜᴇᴘᴀᴛᴇʟ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-08 14:01:34

Google ahora tiene un ID de publicidad .
Esto también se puede utilizar, pero tenga en cuenta que :

El ID de publicidad es un ID específico del usuario, único y reiniciable

Y

Permite a los usuarios restablecer su identificador u optar por no recibir anuncios basados en intereses dentro de las aplicaciones de Google Play.

Así que aunque este id puede cambiar, parece que pronto puede que no tengamos una opción, depende del propósito de este id.

Más información @ develper.android

Copiar y pegar código aquí

HTH

 4
Author: Hertzel Guinness,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-02 13:23:34

Telefonímico.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:

Ajustes.Seguro.ANDROID_ID que devuelve el ID de Android como una cadena hexadecimal única de 64 bits.

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

A veces Telefonímero.getDeviceId () devolverá null, por lo que para asegurar un id único utilizará 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;
}
 4
Author: Jorgesys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-06 15:00:25