trovo - C'è un ID univoco del dispositivo Android?




id telefono android (20)

Ultimo aggiornamento: 6/2/15

Dopo aver letto tutti i post di Stack Overflow sulla creazione di un ID univoco, il blog degli sviluppatori di Google e la documentazione di Android, mi sembra che lo "Pseudo ID" sia la migliore opzione possibile.

Problema principale: hardware vs software

Hardware

  • Gli utenti possono cambiare hardware, tablet Android o telefono, quindi ID univoci basati su hardware non sono buone idee per gli UTENTI DI TRACKING
  • Per TRACKING HARDWARE , questa è una grande idea

Software

  • Gli utenti possono cancellare / modificare la propria ROM se sono rootati
  • Puoi tenere traccia degli utenti su piattaforme diverse (iOS, Android, Windows e Web)
  • I migliori vogliono GUIDARE UN UTENTE INDIVIDUALE con il loro consenso è quello di averli semplicemente registrati (rendilo trasparente usando OAuth)

Ripartizione generale con Android

- Garantire univocità (includere dispositivi rooted) per API> = 9/10 (99,5% dei dispositivi Android)

- Nessuna autorizzazione aggiuntiva

Codice 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)

Grazie a @stansult per aver pubblicato tutte le nostre opzioni (in questa domanda Stack Overflow).

Elenco di opzioni - ragioni per le quali / perché non usarle:

  • Email dell'utente - Software

    • L'utente potrebbe cambiare email - ALTAMENTE improbabile
    • API 5+ <uses-permission android:name="android.permission.GET_ACCOUNTS" /> o
    • API 14+ <uses-permission android:name="android.permission.READ_PROFILE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> ( Come ottenere l'indirizzo e-mail principale del dispositivo Android )
  • Numero di telefono dell'utente - Software

    • Gli utenti possono cambiare i numeri di telefono - ALTAMENTE improbabile
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • IMEI - Hardware (solo telefoni, ha bisogno di android.permission.READ_PHONE_STATE )

    • La maggior parte degli utenti odia il fatto che nell'autorizzazione sia indicato "Telefonate". Alcuni utenti danno valutazioni errate, perché credono che stai semplicemente rubando le loro informazioni personali, quando tutto ciò che vuoi veramente è monitorare le installazioni dei dispositivi. È ovvio che stai raccogliendo dati.
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • ID Android - Hardware (può essere nullo, può cambiare al reset di fabbrica, può essere modificato su un dispositivo rooted)

    • Dal momento che può essere 'null', possiamo controllare 'null' e cambiarne il valore, ma questo significa che non sarà più univoco.
    • Se si dispone di un utente con un dispositivo di ripristino di fabbrica, il valore potrebbe essere stato modificato o modificato sul dispositivo rooted in modo che possano essere presenti voci duplicate se si monitorano le installazioni utente.
  • Indirizzo MAC WLAN - Hardware (richiede android.permission.ACCESS_WIFI_STATE )

    • Questa potrebbe essere la seconda opzione migliore, ma stai ancora raccogliendo e memorizzando un identificatore univoco che proviene direttamente da un utente. Questo è ovvio che stai raccogliendo dati.
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
  • Indirizzo MAC Bluetooth - Hardware (dispositivi con Bluetooth, richiede android.permission.BLUETOOTH )

    • La maggior parte delle applicazioni sul mercato non usa il Bluetooth, quindi se l'applicazione non usa il Bluetooth e questo è incluso, l'utente potrebbe diventare sospetto.
    • <uses-permission android:name="android.permission.BLUETOOTH "/>
  • Pseudo-Unique ID - Software (per tutti i dispositivi Android)

    • Molto possibile, potrebbe contenere collisioni - Vedi il mio metodo pubblicato qui sotto!
    • Ciò ti consente di avere un ID "quasi unico" dall'utente senza prendere nulla di privato. Puoi creare il tuo ID anonimo dalle informazioni del dispositivo.

So che non esiste un modo "perfetto" per ottenere un ID univoco senza utilizzare le autorizzazioni; tuttavia, a volte abbiamo solo bisogno di monitorare l'installazione del dispositivo. Quando si tratta di creare un ID univoco, è possibile creare un 'ID pseudo unico' basato esclusivamente su informazioni che l'API di Android ci offre senza utilizzare autorizzazioni aggiuntive. In questo modo, possiamo mostrare rispetto all'utente e cercare di offrire anche una buona esperienza utente.

Con un id pseudo-univoco, ti imbatti solo nel fatto che potrebbero esserci duplicati in base al fatto che esistono dispositivi simili. Puoi modificare il metodo combinato per renderlo più unico; tuttavia, alcuni sviluppatori devono monitorare le installazioni dei dispositivi e questo farà il trucco o le prestazioni in base a dispositivi simili.

API> = 9:

Se il loro dispositivo Android è API 9 o superiore, questo è garantito per essere univoco a causa del campo "Build.SERIAL".

RICORDA , tecnicamente stai perdendo solo lo 0,5% degli utenti che hanno API <9 . Quindi puoi concentrarti sul resto: questo è il 99,5% degli utenti!

API <9:

Se il dispositivo Android dell'utente è inferiore all'API 9; si spera che non abbiano fatto un reset di fabbrica e che il loro 'Secure.ANDROID_ID' sia conservato o non 'nullo'. (vedi http://developer.android.com/about/dashboards/index.html )

Se tutti gli altri falliscono:

Se tutto il resto fallisce, se l'utente ha un valore inferiore all'API 9 (inferiore a Gingerbread), ha ripristinato il proprio dispositivo o "Secure.ANDROID_ID" restituisce "null", quindi semplicemente l'ID restituito si baserà esclusivamente sulle informazioni del proprio dispositivo Android. Questo è dove possono accadere le collisioni.

I cambiamenti:

  • Rimosso "Android.SECURE_ID" a causa di ripristini di fabbrica potrebbe causare la modifica del valore
  • Modificato il codice da cambiare su API
  • Modificato lo pseudo

Si prega di dare un'occhiata al metodo qui sotto:

/**
 * 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();
}

Novità (per app con annunci AND Google Play Services):

Dalla console dello sviluppatore di Google Play:

A partire dal 1 ° agosto 2014, le Norme del programma per gli sviluppatori di Google Play richiedono che tutti i nuovi caricamenti e aggiornamenti delle app utilizzino l'ID pubblicitario al posto di altri identificativi persistenti per scopi pubblicitari. Per saperne di più

Implementazione :

Autorizzazione:

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

Codice:

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();
}

Fonte / Documenti:

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

Importante:

È inteso che l'ID pubblicità sostituisca completamente l'utilizzo esistente di altri identificatori per scopi pubblicitari (come l'utilizzo di ANDROID_ID in Settings.Secure) quando i servizi di Google Play sono disponibili. I casi in cui Google Play Services non è disponibile sono indicati da una GooglePlayServicesNotAvailableException lanciata da getAdvertisingIdInfo ().

Attenzione, gli utenti possono ripristinare:

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

Ho provato a fare riferimento a ogni link da cui ho preso informazioni. Se ti manca e devi essere incluso, per favore commenta!

ID istanza di Google Player Services

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

https://code.i-harness.com

I dispositivi Android dispongono di un ID univoco e, in tal caso, qual è un modo semplice per accedervi utilizzando Java?


L'ID dispositivo univoco di un dispositivo con sistema operativo Android come String, utilizzando TelephonyManagere ANDROID_ID, è ottenuto da:

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);
}

Tuttavia, consiglio vivamente un metodo suggerito da Google, vedere Identificazione delle installazioni di app .


Come dice Dave Webb, il Blog degli sviluppatori Android ha un articolo che copre questo. La loro soluzione preferita è quella di tenere traccia delle installazioni delle app piuttosto che dei dispositivi e che funzionerà bene per la maggior parte dei casi d'uso. Il post sul blog ti mostrerà il codice necessario per farlo funzionare e ti consiglio di verificarlo.

Tuttavia, il post del blog prosegue per discutere le soluzioni se è necessario un identificatore di dispositivo piuttosto che un identificativo di installazione dell'app. Ho parlato con qualcuno su Google per ottenere ulteriori chiarimenti su alcuni articoli nel caso in cui tu abbia bisogno di farlo. Ecco cosa ho scoperto sugli identificatori dei dispositivi che NON sono menzionati nel post di blog di cui sopra:

  • ANDROID_ID è l'identificatore di dispositivo preferito. ANDROID_ID è perfettamente affidabile sulle versioni di Android <= 2.1 o> = 2.3. Solo 2.2 ha i problemi menzionati nel post.
  • Diversi dispositivi di diversi produttori sono interessati dal bug ANDROID_ID in 2.2.
  • Per quanto sono stato in grado di determinare, tutti i dispositivi interessati hanno lo stesso ANDROID_ID , che è 9774d56d682e549c . Che è anche lo stesso id del dispositivo segnalato dall'emulatore, btw.
  • Google ritiene che gli OEM abbiano patchato il problema per molti o molti dei loro dispositivi, ma sono stato in grado di verificare che dall'inizio di aprile 2011, almeno, è ancora abbastanza facile trovare dispositivi con ANDROID_ID danneggiato.

Sulla base dei consigli di Google, ho implementato una classe che genererà un UUID univoco per ciascun dispositivo, utilizzando ANDROID_ID come seed, ove appropriato, ricadendo su TelephonyManager.getDeviceId () se necessario, e in caso contrario, ricorrendo a un UUID univoco generato casualmente persistente attraverso i riavvii dell'app (ma non le re-installazioni delle app).

Si noti che per i dispositivi che devono effettuare il fallback sull'ID del dispositivo, l'ID univoco continuerà a essere ripristinato in fabbrica. Questo è qualcosa di cui essere consapevoli. Se è necessario assicurarsi che il ripristino dei dati di fabbrica ripristini il proprio ID univoco, è consigliabile considerare di ricadere direttamente sull'UUID casuale anziché sull'ID del dispositivo.

Ancora una volta, questo codice è per un ID dispositivo, non un ID installazione app. Per la maggior parte delle situazioni, un ID di installazione dell'app è probabilmente quello che stai cercando. Ma se hai bisogno di un ID dispositivo, il seguente codice funzionerà probabilmente per te.

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;
    }
}

Ecco il codice che Reto Meier ha utilizzato nella presentazione di Google I / O quest'anno per ottenere un ID univoco per l'utente:

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;
}

Se accetti questo con una strategia di backup per inviare le preferenze al cloud (descritto anche nel talk di Reto, dovresti avere un ID che si collega a un utente e resta in attesa dopo che il dispositivo è stato cancellato o addirittura sostituito. in analytics andando avanti (in altre parole, non ho ancora fatto quel po ':).


Inoltre, potresti prendere in considerazione l'indirizzo MAC dell'adattatore Wi-Fi. Recuperato così:

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

Richiede il permesso android.permission.ACCESS_WIFI_STATE nel manifest.

Segnalato per essere disponibile anche quando il Wi-Fi non è connesso. Se Joe dalla risposta sopra dà questa prova sui suoi molti dispositivi, sarebbe carino.

Su alcuni dispositivi, non è disponibile quando il Wi-Fi è disattivato.

NOTA: da Android 6.x, restituisce l'indirizzo mac falso coerente: 02:00:00:00:00:00



AGGIORNAMENTO : A partire dalle versioni recenti di Android, molti dei problemi con ANDROID_ID sono stati risolti e credo che questo approccio non sia più necessario. Si prega di dare un'occhiata alla risposta di Anthony .

Completa divulgazione: la mia app ha utilizzato l'approccio di seguito in origine ma non utilizza più questo approccio e ora utilizziamo l'approccio delineato nella voce android-developers.blogspot.com/2011/03/… cui rimanda la risposta di emmby (ovvero, generazione e salvataggio di un UUID#randomUUID() ).

Ci sono molte risposte a questa domanda, molte delle quali funzioneranno solo "alcune" volte, e sfortunatamente non è abbastanza buona.

In base ai miei test sui dispositivi (tutti i telefoni, almeno uno dei quali non è attivato):

  1. Tutti i dispositivi testati hanno restituito un valore per TelephonyManager.getDeviceId()
  2. Tutti i dispositivi GSM (tutti testati con una SIM) hanno restituito un valore per TelephonyManager.getSimSerialNumber()
  3. Tutti i dispositivi CDMA hanno restituito null per getSimSerialNumber() (come previsto)
  4. Tutti i dispositivi con un account Google aggiunto hanno restituito un valore per ANDROID_ID
  5. Tutti i dispositivi CDMA hanno restituito lo stesso valore (o derivazione dello stesso valore) per ANDROID_ID e TelephonyManager.getDeviceId() , purché sia stato aggiunto un account Google durante l'installazione.
  6. Non avevo ancora la possibilità di provare i dispositivi GSM senza SIM, dispositivo GSM senza account Google aggiunto o nessuno dei dispositivi in ​​modalità aereo.

Quindi, se vuoi qualcosa di unico per il dispositivo stesso, TM.getDeviceId() dovrebbe essere sufficiente. Ovviamente alcuni utenti sono più paranoici di altri, quindi potrebbe essere utile usare l'hash 1 o più di questi identificatori, in modo che la stringa sia ancora virtualmente unica per il dispositivo, ma non identifichi esplicitamente il dispositivo reale dell'utente. Ad esempio, utilizzando String.hashCode() , combinato 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();

potrebbe comportare qualcosa come: 00000000-54b3-e7c7-0000-000046bffd97

Funziona abbastanza bene per me.

Come menzionato da Richard qui sotto, non dimenticare che hai bisogno dell'autorizzazione per leggere le proprietà di TelephonyManager , quindi aggiungi questo al tuo manifest:

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

librerie di importazione

import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;

ID istanza di Google

Rilasciato all'I / O 2015; su Android richiede servizi di riproduzione 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

Sembra che Google intenda utilizzare questo ID per identificare le installazioni su Android, Chrome e iOS.

Identifica un'installazione piuttosto che un dispositivo, ma di nuovo, ANDROID_ID (che è la risposta accettata) ora non identifica più nemmeno i dispositivi. Con il runtime ARC viene generato un nuovo ANDROID_ID per ogni installazione ( dettagli qui ), proprio come questo nuovo ID istanza. Inoltre, penso che identificare le installazioni (non i dispositivi) sia ciò che la maggior parte di noi sta effettivamente cercando.

I vantaggi dell'ID istanza

Mi sembra che Google intenda utilizzarlo a tale scopo (identificando le tue installazioni), che sia multipiattaforma e possa essere utilizzato per una serie di altri scopi (vedi i link sopra).

Se utilizzi GCM, alla fine dovrai utilizzare questo ID di istanza perché ne hai bisogno per ottenere il token GCM (che sostituisce il vecchio ID di registrazione GCM).

Gli svantaggi / problemi

Nell'attuale implementazione (GPS 7.5) l'ID istanza viene recuperato da un server quando la tua app lo richiede. Ciò significa che la chiamata sopra è una chiamata bloccante - nel mio test non scientifico ci vogliono 1-3 secondi se il dispositivo è online e 0,5 - 1,0 secondi se non in linea (presumibilmente questo è il tempo che attende prima di arrendersi e generare un ID casuale). Questo è stato testato in Nord America su Nexus 5 con Android 5.1.1 e GPS 7.5.

Se si utilizza l'ID per gli scopi che intendono - ad es. autenticazione app, identificazione app, GCM - Penso che questo 1-3 secondi potrebbe essere un fastidio (a seconda dell'app, ovviamente).


Aggiungi sotto il codice nel file di classe:

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);

Aggiungi in AndroidManifest.xml:

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

Ecco come sto generando l'ID univoco:

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;
}

Penso che questo sia un modo sicuro per costruire uno scheletro per un ID unico ... dai un'occhiata.

ID Pseudo-Unico, che funziona su tutti i dispositivi Android Alcuni dispositivi non hanno un telefono (ad esempio Tablet) o per qualche ragione, non si desidera includere l'autorizzazione READ_PHONE_STATE. È comunque possibile leggere i dettagli come la versione ROM, il nome del produttore, il tipo di CPU e altri dettagli hardware, che saranno adatti se si desidera utilizzare l'ID per un controllo della chiave seriale o per altri scopi generali. L'ID calcolato in questo modo non sarà univoco: è possibile trovare due dispositivi con lo stesso ID (basato sullo stesso hardware e immagine ROM) ma i cambiamenti nelle applicazioni del mondo reale sono trascurabili. A questo scopo puoi usare la classe 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 maggior parte dei membri di Build sono stringhe, quello che stiamo facendo qui è di prendere la loro lunghezza e trasformarla via modulo in una cifra. Abbiamo 13 cifre di questo tipo e ne aggiungiamo altre due nella parte anteriore (35) per avere lo stesso ID di dimensione dell'IMEI (15 cifre). Ci sono altre possibilità qui, state bene, date un'occhiata a queste stringhe. Restituisce qualcosa di simile 355715565309247. Non è richiesto alcun permesso speciale, rendendo questo approccio molto conveniente.

(Informazioni aggiuntive: la tecnica sopra riportata è stata copiata da un articolo su here .)


Per il riconoscimento hardware di uno specifico dispositivo Android è possibile controllare gli indirizzi MAC.

puoi farlo in questo modo:

in AndroidManifest.xml

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

ora nel tuo codice:

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

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

In ogni dispositivo Android la loro è almeno una "interfaccia wlan0" che è il chip WI-FI. Questo codice funziona anche quando WI-FI non è acceso.

PS Loro sono un sacco di altre interfacce che otterrete dalla lista contenente MACS, ma questo può cambiare tra i telefoni.


Utilizzando il codice riportato di seguito, è possibile ottenere l'ID dispositivo univoco di un dispositivo con sistema operativo Android come una stringa.

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

Che ne dici IMEI . Questo è unico per Android o altri dispositivi mobili.


Esistono molti approcci diversi per aggirare tali ANDROID_IDproblemi (a nullvolte possono essere i dispositivi o un modello specifico restituiscono sempre lo stesso ID) con pro e contro:

  • Implementazione di un algoritmo di generazione di ID personalizzato (basato sulle proprietà del dispositivo che dovrebbero essere statiche e non cambierà -> chi lo sa)
  • Abuso di altri ID come IMEI , numero di serie, indirizzo Wi-Fi / Bluetooth-MAC (non saranno presenti su tutti i dispositivi o saranno necessarie ulteriori autorizzazioni)

Io stesso preferisco usare un'implementazione OpenUDID esistente (vedi https://github.com/ylechelle/OpenUDID ) per Android (vedi https://github.com/vieux/OpenUDID ). È facile da integrare e utilizza i ANDROID_IDfallback per i problemi sopra menzionati.


Google ora ha un ID pubblicità .
Questo può anche essere usato, ma nota che:

L'ID pubblicità è un ID ripristinabile specifico dell'utente, unico

e

consente agli utenti di reimpostare il proprio identificatore o disattivare gli annunci basati sugli interessi nelle app Google Play.

Quindi, sebbene questo ID possa cambiare, sembra che presto potremmo non avere una scelta , dipende dallo scopo di questo id.

http://developer.android.com/google/play-services/id.html

Copia-incolla il codice qui

HTH


Il seguente codice restituisce il numero di serie del dispositivo utilizzando un'API Android nascosta. Ma questo codice non funziona su Samsung Galaxy Tab perché "ro.serialno" non è impostato su questo 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) {

}

Io uso il seguente codice per ottenere IMEIo usare Secure. ANDROID_IDin alternativa, quando il dispositivo non ha funzionalità telefoniche:

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);

Più specificamente Settings.Secure.ANDROID_ID,. Questa è una quantità a 64 bit che viene generata e memorizzata al primo avvio del dispositivo. Viene ripristinato quando il dispositivo viene cancellato.

ANDROID_IDsembra una buona scelta per un identificatore di dispositivo unico. Ci sono aspetti negativi: in primo luogo, non è affidabile al 100% sulle versioni di Android precedenti alla 2.2 (“Froyo”).Inoltre, c'è stato almeno un bug ampiamente osservato in un telefono popolare di un importante produttore, in cui ogni istanza ha lo stesso ANDROID_ID.


Un altro modo è quello di utilizzare /sys/class/android_usb/android0/iSerialin un'applicazione senza permessi di sorta.

[email protected]:~$ adb shell ls -l /sys/class/android_usb/android0/iSerial
-rw-r--r-- root     root         4096 2013-01-10 21:08 iSerial
[email protected]:~$ adb shell cat /sys/class/android_usb/android0/iSerial
0A3CXXXXXXXXXX5

Per fare ciò in Java si usa semplicemente un FileInputStream per aprire il file iSerial e leggere i caratteri. Assicurati di averlo racchiuso in un gestore di eccezioni, perché non tutti i dispositivi hanno questo file.

Almeno i seguenti dispositivi sono noti per avere questo file leggibile a livello mondiale:

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

È anche possibile vedere il mio post sul blog Perdendo il numero di serie dell'hardware di Android in app non privilegiate in cui discuto di quali altri file sono disponibili per informazioni.





uniqueidentifier