Gibt es eine eindeutige Android-Geräte-ID?


14 Answers

UPDATE : Seit den letzten Versionen von Android wurden viele Probleme mit ANDROID_ID behoben, und ich glaube, dass dieser Ansatz nicht mehr notwendig ist. Bitte werfen Sie einen Blick auf Anthonys Antwort .

Vollständige Offenlegung: Meine App verwendete ursprünglich den folgenden Ansatz, verwendet diesen Ansatz jedoch nicht mehr. Wir verwenden nun den im android-developers.blogspot.com/2011/03/… des android-developers.blogspot.com/2011/03/… Ansatz, auf den die Antwort von emmby verweist (nämlich das Generieren und Speichern einer UUID#randomUUID() ).

Es gibt viele Antworten auf diese Frage, von denen die meisten nur "einige" der Zeit funktionieren, und leider ist das nicht gut genug.

Basierend auf meinen Tests von Geräten (alle Telefone, von denen mindestens eines nicht aktiviert ist):

  1. Alle getesteten Geräte haben einen Wert für TelephonyManager.getDeviceId()
  2. Alle GSM-Geräte (alle mit einer SIM getestet) haben einen Wert für TelephonyManager.getSimSerialNumber()
  3. Alle CDMA-Geräte haben (wie erwartet) null für getSimSerialNumber() ) zurückgegeben
  4. Alle Geräte mit einem hinzugefügten Google-Konto haben einen Wert für ANDROID_ID
  5. Alle CDMA-Geräte haben für ANDROID_ID und TelephonyManager.getDeviceId() den gleichen Wert (oder die Ableitung desselben Werts) zurückgegeben, ANDROID_ID während der Einrichtung ein Google-Konto hinzugefügt wurde.
  6. Ich hatte noch keine Gelegenheit, GSM-Geräte ohne SIM, ein GSM-Gerät ohne Google-Konto oder eines der Geräte im Flugzeugmodus zu testen.

Wenn Sie also etwas Einzigartiges für das Gerät selbst haben wollen, sollte TM.getDeviceId() ausreichen. Offensichtlich sind manche Benutzer paranoider als andere, daher könnte es nützlich sein, einen oder mehrere dieser Identifikatoren zu hashen, so dass der String für das Gerät immer noch praktisch einzigartig ist, aber das tatsächliche Gerät des Benutzers nicht explizit identifiziert. Verwenden Sie beispielsweise String.hashCode() in Kombination 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 etwas wie folgendes ergeben: 00000000-54b3-e7c7-0000-000046bffd97

Es funktioniert gut genug für mich.

Wie Richard unten erwähnt, vergessen Sie nicht, dass Sie die Berechtigung zum Lesen der TelephonyManager Eigenschaften benötigen. Fügen Sie dies Ihrem Manifest hinzu:

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

libs importieren

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

Verfügen Android-Geräte über eine eindeutige ID, und wenn ja, wie kann man mit Java einfach darauf zugreifen?




How about the IMEI . That is unique for Android or other mobile devices.




Here is how I am generating the unique id:

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






More specifically, Settings.Secure.ANDROID_ID . This is a 64-bit quantity that is generated and stored when the device first boots. It is reset when the device is wiped.

ANDROID_ID seems a good choice for a unique device identifier. There are downsides: First, it is not 100% reliable on releases of Android prior to 2.2 (“Froyo”). Also, there has been at least one widely-observed bug in a popular handset from a major manufacturer, where every instance has the same ANDROID_ID.




Sie können auch die MAC-Adresse des WLAN-Adapters berücksichtigen. So gefunden:

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

Erfordert die Berechtigung android.permission.ACCESS_WIFI_STATE im Manifest.

Berichtet, um verfügbar zu sein, auch wenn WLAN nicht verbunden ist. Wenn Joe aus der obigen Antwort diesen auf seinen vielen Geräten ausprobieren würde, wäre das nett.

Auf einigen Geräten ist es nicht verfügbar, wenn WLAN ausgeschaltet ist.

HINWEIS: Ab Android 6.x wird eine konsistente gefälschte Mac-Adresse zurückgegeben: 02:00:00:00:00:00




Add Below code in class file:

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

Add in AndroidManifest.xml:

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



There are 30+ answers here and some are same and some are unique. This answer is based on few of those answers. One of them being @Lenn Dolling's answer.

It combines 3 IDs and creates a 32-digit hex string. It has worked very well for me.

3 IDs are:
Pseudo-ID - It is generated based on physical device specifications
ANDROID_ID - Settings.Secure.ANDROID_ID
Bluetooth Address - Bluetooth adapter address

It will return something like this: 551F27C060712A72730B0A0F734064B1

Note: You can always add more IDs to the longId string. For example, Serial #. wifi adapter address. IMEI. This way you are making it more unique per device.

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



For hardware recognition of a specific Android device you could check the MAC Addresses.

you can do it that way:

in AndroidManifest.xml

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

now in your code:

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

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

In every Android device their is at least a "wlan0" Interface witch is the WI-FI chip. This code works even when WI-FI is not turned on.

PS Their are a bunch of other Interfaces you will get from the list containing MACS But this can change between phones.







Using the code below, you can get the unique device ID of an Android OS device as a string.

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



Wie Dave Webb erwähnt, hat der Android Developer Blog einen Artikel , der dies abdeckt. 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 Blogpost zeigt Ihnen den notwendigen Code, um diese Arbeit zu erledigen, und ich empfehle Ihnen, es auszuprobieren.

Der Blogpost diskutiert jedoch Lösungen, wenn Sie eine Geräte-ID und keine App-Installations-ID benötigen. Ich habe mit jemandem bei Google gesprochen, um einige zusätzliche Details zu klären, falls Sie dies tun sollten. Folgendes habe ich über Geräte-IDs herausgefunden, die im oben genannten Blogpost nicht erwähnt wurden:

  • ANDROID_ID ist die bevorzugte Gerätekennung. ANDROID_ID ist absolut zuverlässig auf Versionen von Android <= 2.1 oder> = 2.3. Nur 2.2 hat die in der Post genannten Probleme.
  • Mehrere Geräte mehrerer Hersteller sind vom ANDROID_ID-Fehler in 2.2 betroffen.
  • Soweit ich feststellen konnte, haben alle betroffenen Geräte die gleiche ANDROID_ID , nämlich 9774d56d682e549c . Welches ist auch die gleiche Geräte-ID, die vom Emulator gemeldet wird, BTW.
  • 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 fehlerhaften ANDROID_ID zu finden.

Basierend auf den Empfehlungen von Google habe ich eine Klasse implementiert, die für jedes Gerät eine eindeutige UUID generiert, die gegebenenfalls ANDROID_ID als Seed verwendet, bei Bedarf auf TelephonyManager.getDeviceId () zurückgreift und, falls dies fehlschlägt, auf eine zufällig generierte eindeutige UUID zurückgreift Dies wird bei App-Neustarts beibehalten (aber nicht bei App-Neuinstallationen).

Beachten Sie, dass für Geräte, die auf die Geräte-ID zurückgreifen müssen, die eindeutige ID während der Werkseinstellungen beibehalten wird. Das ist etwas, dessen man sich bewusst sein muss. Wenn Sie sicherstellen müssen, dass ein Zurücksetzen auf die Werkseinstellungen Ihre eindeutige ID zurücksetzt, sollten Sie in Erwägung ziehen, direkt auf die zufällige UUID anstatt auf die Geräte-ID zurückzugreifen.

Dieser Code gilt wiederum für eine Geräte-ID und keine 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;
    }
}



One thing I'll add - I have one of those unique situations.

Verwenden:

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

Turns out that even though my Viewsonic G Tablet reports a DeviceID that is not Null, every single G Tablet reports the same number.

Makes it interesting playing "Pocket Empires" which gives you instant access to someone's account based on the "unique" DeviceID.

My device does not have a cell radio.




Google Instance ID

Released at I/O 2015; on Android requires play services 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

It seems that Google intends for this ID to be used to identify installations across Android, Chrome, and iOS.

It identifies an installation rather then a device, but then again, ANDROID_ID (which is the accepted answer) now no longer identifies devices either. With the ARC runtime a new ANDROID_ID is generated for every installation ( details here ), just like this new instance ID. Also, I think that identifying installations (not devices) is what most of us are actually looking for.

The advantages of instance ID

It appears to me that Google intends for it to be used for this purpose (identifying your installations), it is cross-platform, and can be used for a number of other purposes (see the links above).

If you use GCM, then you will eventually need to use this instance ID because you need it in order to get the GCM token (which replaces the old GCM registration ID).

The disadvantages/issues

In the current implementation (GPS 7.5) the instance ID is retrieved from a server when your app requests it. This means that the call above is a blocking call - in my unscientific testing it takes 1-3 seconds if the device is online, and 0.5 - 1.0 seconds if off-line (presumably this is how long it waits before giving up and generating a random ID). This was tested in North America on Nexus 5 with Android 5.1.1 and GPS 7.5.

If you use the ID for the purposes they intend - eg. app authentication, app identification, GCM - I think this 1-3 seconds could be a nuisance (depending on your app, of course).




The following code returns the device serial number using a hidden Android API. But, this code don't works on Samsung Galaxy Tab because "ro.serialno" isn't set on this device.

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

}



Related