Haben Android-Geräte eine eindeutige ID, und wenn ja, wie kann man mit Java einfach darauf zugreifen?
Gibt es eine eindeutige Android-Geräte-ID?
Tyler
Jo
AKTUALISIEREN: Ab den letzten Versionen von Android, viele der Probleme mit ANDROID_ID
wurden gelöst, und ich glaube, dass dieser Ansatz nicht mehr notwendig ist. Bitte schau dir Anthonys Antwort an.
Vollständige Offenlegung: Meine App hat ursprünglich den folgenden Ansatz verwendet, verwendet diesen Ansatz jedoch nicht mehr, und wir verwenden jetzt den in beschriebenen Ansatz Blog für Android-Entwickler Eintrag, auf den die Antwort von emmby verweist (nämlich Generieren und Speichern einer UUID#randomUUID()
).
Auf diese Frage gibt es viele Antworten, von denen die meisten nur „manchmal“ funktionieren, und das ist leider nicht gut genug.
Basierend auf meinen Tests von Geräten (alle Telefone, von denen mindestens eines nicht aktiviert ist):
- Alle getesteten Geräte haben einen Wert für zurückgegeben
TelephonyManager.getDeviceId()
- Alle GSM-Geräte (alle getestet mit einer SIM) haben einen Wert für zurückgegeben
TelephonyManager.getSimSerialNumber()
- Alle CDMA-Geräte haben null zurückgegeben für
getSimSerialNumber()
(wie erwartet) - Alle Geräte mit einem hinzugefügten Google-Konto haben einen Wert für zurückgegeben
ANDROID_ID
- Alle CDMA-Geräte haben für beide den gleichen Wert (oder die Ableitung des gleichen Werts) zurückgegeben
ANDROID_ID
undTelephonyManager.getDeviceId()
— so lange wie Während der Einrichtung wurde ein Google-Konto hinzugefügt. - Ich hatte noch keine Gelegenheit, GSM-Geräte ohne SIM, ein GSM-Gerät ohne hinzugefügtes Google-Konto oder eines der Geräte im Flugmodus zu testen.
Wenn Sie also etwas Einzigartiges für das Gerät selbst wollen, TM.getDeviceId()
sollte ausreichen. Offensichtlich sind einige Benutzer paranoider als andere, daher kann es nützlich sein, eine oder mehrere dieser Kennungen zu hashen, sodass die Zeichenfolge immer noch praktisch eindeutig für das Gerät ist, aber das tatsächliche Gerät des Benutzers nicht explizit identifiziert. Zum Beispiel mit String.hashCode()
kombiniert mit einer 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();
könnte zu etwas führen wie: 00000000-54b3-e7c7-0000-000046bffd97
Es funktioniert gut genug für mich.
Wie Richard unten erwähnt, vergessen Sie nicht, dass Sie eine Erlaubnis zum Lesen benötigen TelephonyManager
Eigenschaften, also fügen Sie dies zu Ihrem Manifest hinzu:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Bibliotheken importieren
import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
-
Telefoniebasierte ID wird es auf Tablet-Geräten nicht geben, oder?
– Seva Alexejew
23. Juni 2010 um 14:27 Uhr
-
Daher habe ich gesagt, dass die meisten nicht immer funktionieren 🙂 Ich habe noch keine Antwort auf diese Frage gefunden, die für alle Geräte, alle Gerätetypen und alle Hardwarekonfigurationen zuverlässig ist. Deshalb ist diese Frage hier, um damit zu beginnen. Es ist ziemlich klar, dass es dafür keine End-all-be-all-Lösung gibt. Einzelne Gerätehersteller haben möglicherweise Geräteseriennummern, aber diese werden uns nicht zur Verwendung offengelegt, und dies ist keine Anforderung. So bleibt uns das, was uns zur Verfügung steht.
– Jo
29. Juni 2010 um 19:40 Uhr
-
Das Codebeispiel funktioniert super. Denken Sie daran, hinzuzufügen
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
zur Manifestdatei. Beim Speichern in einer Datenbank ist die zurückgegebene Zeichenfolge 36 Zeichen lang.– Richard
27. Februar 2011 um 22:28 Uhr
-
Beachten Sie, dass diese Lösung große Einschränkungen aufweist: android-developers.blogspot.com/2011/03/…
– Emma
7. April 2011 um 20:09 Uhr
-
@softarn: Ich glaube, Sie beziehen sich auf den Android Developer Blog, auf den emmby bereits verlinkt ist und der erklärt, was Sie sind versuchen zu sagen, also hätten Sie vielleicht stattdessen einfach seinen Kommentar positiv bewerten sollen. Wie auch immer, wie emmby in seiner Antwort erwähnt, gibt es immer noch Probleme, sogar mit den Blog-Informationen. Die Frage fragt nach einem eindeutigen GERÄT Kennung (nicht Installationskennung), daher stimme ich Ihrer Aussage nicht zu. Der Blog geht davon aus, was Sie wollen Es ist nicht nötig um das Gerät zu verfolgen, während die Frage genau danach fragt. Ansonsten stimme ich dem Blog zu.
– Jo
22. Juli 2011 um 0:45 Uhr
-
Ich habe Ihre Methode in meiner App zum Senden von Kommentaren verwendet. Ich habe schlechte Neuigkeiten. Leider ist die PsuedoID nicht vollständig eindeutig. Mein Server hat mehr als 100 für 5 IDs und mehr als 30 für fast 30 IDs aufgezeichnet. Die am häufigsten wiederholten IDs sind „ffffffff-fc8f-6093-ffff-ffffd8“ (159-Datensatz) und „ffffffff-fe99-b334-ffff-ffffef“ (154-mal). Auch basierend auf Zeit und Kommentaren ist es offensichtlich, dass es verschiedene Völker gibt. die Gesamtaufzeichnungen bis jetzt sind 10.000. Bitte lassen Sie mich wissen, warum dies passiert ist. Panzer.
– hojjat reyhane
17. März 2015 um 16:36 Uhr
-
Ich habe das vor über 1,5 Jahren geschrieben. Ich bin mir nicht sicher, warum es nicht einzigartig für Sie ist. Sie können die Werbe-ID ausprobieren. Wenn nicht, können Sie Ihre eigene Lösung finden.
– Jared Burrows
17. März 2015 um 17:35 Uhr
-
sorta .. Ich würde es wirklich schätzen, wenn Sie die Frage durchgehen und Ihre Gedanken dazu äußern
– Durai Amuthan.H
29. April 2015 um 17:41 Uhr
-
@user1587329 Danke. Ich versuche, dies für alle aktuell zu halten. Diese Frage ist knifflig, wenn es um Hardware vs. Software und plattformübergreifend geht.
– Jared Burrows
6. Mai 2015 um 14:08 Uhr
Emma
Wie Dave Webb erwähnt, die Android Developer Blog hat einen Artikel das deckt das ab. Ihre bevorzugte Lösung besteht darin, App-Installationen statt Geräte zu verfolgen, und das wird für die meisten Anwendungsfälle gut funktionieren. Der Blogbeitrag zeigt Ihnen den notwendigen Code, damit das funktioniert, und ich empfehle Ihnen, ihn sich anzusehen.
Der Blogbeitrag fährt jedoch fort, Lösungen zu diskutieren, wenn Sie eine Gerätekennung anstelle einer App-Installationskennung benötigen. Ich habe mit jemandem bei Google gesprochen, um zusätzliche Erläuterungen zu einigen Punkten zu erhalten, falls dies erforderlich sein sollte. Folgendes habe ich über Gerätekennungen herausgefunden, die im oben genannten Blogbeitrag NICHT erwähnt werden:
- ANDROID_ID ist die bevorzugte Gerätekennung. ANDROID_ID ist absolut zuverlässig auf Android-Versionen <=2.1 oder >=2.3. Nur 2.2 hat die im Beitrag erwähnten Probleme.
- Mehrere Geräte verschiedener Hersteller sind vom ANDROID_ID-Bug in 2.2 betroffen.
- Soweit ich feststellen konnte, haben alle betroffenen Geräte dieselbe ANDROID_IDwelches ist 9774d56d682e549c. Das ist auch die gleiche Geräte-ID, die vom Emulator gemeldet wird, übrigens.
- Google glaubt, dass OEMs das Problem für viele oder die meisten ihrer Geräte gepatcht haben, aber ich konnte bestätigen, dass es zumindest Anfang April 2011 immer noch recht einfach ist, Geräte mit der defekten ANDROID_ID zu finden.
Basierend auf den Empfehlungen von Google habe ich eine Klasse implementiert, die eine eindeutige UUID für jedes Gerät generiert, wobei ANDROID_ID gegebenenfalls als Startwert verwendet wird, bei Bedarf auf TelephonyManager.getDeviceId() zurückgegriffen wird und, falls dies fehlschlägt, auf eine zufällig generierte eindeutige UUID zurückgegriffen wird die über App-Neustarts hinweg beibehalten wird (jedoch nicht über App-Neuinstallationen).
Beachten Sie, dass für Geräte, die auf die Geräte-ID zurückgreifen müssen, die eindeutige ID WILLE bestehen über Werksresets hinweg. Dies ist etwas, dessen man sich bewusst sein sollte. Wenn Sie sicherstellen müssen, dass beim Zurücksetzen auf die Werkseinstellungen Ihre eindeutige ID zurückgesetzt wird, sollten Sie erwägen, direkt auf die zufällige UUID statt auf die Geräte-ID zurückzugreifen.
Auch dieser Code ist für eine Geräte-ID, nicht für eine App-Installations-ID. In den meisten Fällen ist eine App-Installations-ID wahrscheinlich das, wonach Sie suchen. Wenn Sie jedoch eine Geräte-ID benötigen, funktioniert der folgende Code wahrscheinlich für Sie.
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;
}
}
-
Sollten Sie nicht die verschiedenen IDs hashen, damit sie alle dieselbe Größe haben? Außerdem sollten Sie die Geräte-ID hashen, um nicht versehentlich private Informationen preiszugeben.
– Steve Pomeroy
11. April 2011 um 20:10 Uhr
-
Gute Punkte, Steve. Ich habe den Code aktualisiert, um immer eine UUID zurückzugeben. Dadurch wird sichergestellt, dass a) die generierten IDs immer dieselbe Größe haben und b) die Android- und Geräte-IDs gehasht werden, bevor sie zurückgegeben werden, um zu vermeiden, dass versehentlich persönliche Informationen preisgegeben werden. Ich habe auch die Beschreibung aktualisiert, um darauf hinzuweisen, dass die Geräte-ID beim Zurücksetzen auf die Werkseinstellungen bestehen bleibt und dass dies für einige Benutzer möglicherweise nicht wünschenswert ist.
– Emma
11. April 2011 um 21:53 Uhr
-
Ich glaube, Sie liegen falsch; Die bevorzugte Lösung besteht darin, Installationen zu verfolgen, nicht Gerätekennungen. Ihr Code ist wesentlich länger und komplexer als der im Blogbeitrag, und es ist für mich nicht offensichtlich, dass er einen Mehrwert bringt.
– Tim Bray
12. April 2011 um 4:58 Uhr
-
Guter Punkt, ich habe den Kommentar aktualisiert, um Benutzern dringend zu empfehlen, App-Installations-IDs anstelle von Geräte-IDs zu verwenden. Ich denke jedoch, dass diese Lösung immer noch wertvoll für Leute ist, die eher eine Geräte- als eine Installations-ID benötigen.
– Emma
12. April 2011 um 12:25 Uhr
-
ANDROID_ID kann sich beim Zurücksetzen auf die Werkseinstellungen ändern, sodass Geräte auch nicht identifiziert werden können
– Samuel
19. Mai 2011 um 8:12 Uhr
Peter Mortensen
Hier ist der Code, den Reto Meier in der verwendet hat Google I/O Präsentation in diesem Jahr, um eine eindeutige ID für den Benutzer zu erhalten:
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;
}
Wenn Sie dies mit einer Backup-Strategie koppeln, um Einstellungen an die Cloud zu senden (ebenfalls beschrieben in Reto’s sprechen, sollten Sie eine ID haben, die mit einem Benutzer verknüpft ist und nach dem Löschen oder sogar Ersetzen des Geräts erhalten bleibt. Ich plane, dies in Zukunft in der Analytik zu verwenden (mit anderen Worten, ich habe das noch nicht getan :).
-
Sollten Sie nicht die verschiedenen IDs hashen, damit sie alle dieselbe Größe haben? Außerdem sollten Sie die Geräte-ID hashen, um nicht versehentlich private Informationen preiszugeben.
– Steve Pomeroy
11. April 2011 um 20:10 Uhr
-
Gute Punkte, Steve. Ich habe den Code aktualisiert, um immer eine UUID zurückzugeben. Dadurch wird sichergestellt, dass a) die generierten IDs immer dieselbe Größe haben und b) die Android- und Geräte-IDs gehasht werden, bevor sie zurückgegeben werden, um zu vermeiden, dass versehentlich persönliche Informationen preisgegeben werden. Ich habe auch die Beschreibung aktualisiert, um darauf hinzuweisen, dass die Geräte-ID beim Zurücksetzen auf die Werkseinstellungen bestehen bleibt und dass dies für einige Benutzer möglicherweise nicht wünschenswert ist.
– Emma
11. April 2011 um 21:53 Uhr
-
Ich glaube, Sie liegen falsch; Die bevorzugte Lösung besteht darin, Installationen zu verfolgen, nicht Gerätekennungen. Ihr Code ist wesentlich länger und komplexer als der im Blogbeitrag, und es ist für mich nicht offensichtlich, dass er einen Mehrwert bringt.
– Tim Bray
12. April 2011 um 4:58 Uhr
-
Guter Punkt, ich habe den Kommentar aktualisiert, um Benutzern dringend zu empfehlen, App-Installations-IDs anstelle von Geräte-IDs zu verwenden. Ich denke jedoch, dass diese Lösung immer noch wertvoll für Leute ist, die eher eine Geräte- als eine Installations-ID benötigen.
– Emma
12. April 2011 um 12:25 Uhr
-
ANDROID_ID kann sich beim Zurücksetzen auf die Werkseinstellungen ändern, sodass Geräte auch nicht identifiziert werden können
– Samuel
19. Mai 2011 um 8:12 Uhr
Sie können auch die MAC-Adresse des Wi-Fi-Adapters berücksichtigen. So abgerufen:
WifiManager wm = (WifiManager)Ctxt.getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo().getMacAddress();
Genehmigung erforderlich android.permission.ACCESS_WIFI_STATE
im Manifest.
Berichten zufolge verfügbar, auch wenn keine Wi-Fi-Verbindung besteht. Wenn Joe aus der obigen Antwort dies auf seinen vielen Geräten ausprobieren würde, wäre das schön.
Auf einigen Geräten ist es nicht verfügbar, wenn WLAN deaktiviert ist.
HINWEIS: Ab Android 6.x gibt es eine konsistente gefälschte Mac-Adresse zurück: 02:00:00:00:00:00
-
Dies erforderlich
android.permission.ACCESS_WIFI_STATE
– ohhorob
1. November 2010 um 4:41 Uhr
-
Ich denke, Sie werden feststellen, dass es auf so ziemlich allen Android-Geräten nicht verfügbar ist, wenn WLAN ausgeschaltet ist. Das Ausschalten von WiFi entfernt das Gerät auf Kernel-Ebene.
– Chrisdowney
21. Mai 2012 um 23:38 Uhr
-
@Sanandrea – seien wir ehrlich, auf einem gerooteten Gerät kann ALLES gespooft werden.
– Okodo
4. September 2013 um 9:53 Uhr
-
Der Zugriff auf die WLAN-MAC-Adresse wurde auf Android M blockiert: stackoverflow.com/questions/31329733/…
– Brise
22. Dezember 2015 um 12:37 Uhr
-
Ab Android 6.x gibt es eine konsistente gefälschte Mac-Adresse zurück:
02:00:00:00:00:00
– Behrouz.M
10. Juli 2016 um 9:14 Uhr
Wenn Sie verwenden
ANDROID_ID
Lesen Sie unbedingt diese Antwort und dieser Fehler.– Dheeraj Vepakomma
16. Januar 2013 um 8:16 Uhr
Ihre Lösung ist hier: stackoverflow.com/a/63481350/7135685
– Mujahid Khan
19. August 2020 um 6:42 Uhr