Wie finde ich die Seriennummer des Android-Geräts?


115

Ich muss eine eindeutige ID für eine Android-App verwenden und dachte, die Seriennummer für das Gerät wäre ein guter Kandidat. Wie rufe ich die Seriennummer eines Android-Geräts in meiner App ab?


2
Vergiss nicht, android: name = "android.permission.READ_PHONE_STATE" zu deinem Manifest
hinzuzufügen


Wenn Sie eine eindeutige ID ohne Berechtigungen erhalten möchten, können Sie diese Bibliothek verwenden , um entweder eine eindeutige ID pro Gerät mit Identity.getDeviceId (Kontext) oder eine Kennung für Ihre App-Installation über Identity.getInstallationId (Kontext) zu generieren .
Caw

Antworten:


105
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

getSystemService ist eine Methode aus der Activity-Klasse. getDeviceID () gibt die MDN oder MEID des Geräts zurück, je nachdem, welches Funkgerät das Telefon verwendet (GSM oder CDMA).

Jedes Gerät MUSS hier einen eindeutigen Wert zurückgeben (vorausgesetzt, es handelt sich um ein Telefon). Dies sollte für jedes Android-Gerät mit einem Sim-Steckplatz oder CDMA-Radio funktionieren. Mit dieser Android-Mikrowelle bist du allein ;-)


@ Hasemam Dies funktioniert nicht für mich, gibt "Force Close"
-Fehler

23
@Hasemam läuft jetzt einwandfrei, nachdem in der Datei androidManifest.xml die Berechtigung <using -ilege android: name = "android.permission.READ_PHONE_STATE"> </ users-permission> hinzugefügt wurde.
Paresh Mayani

23
Es gibt einige Ratschläge im offiziellen Blog des Android-Entwicklers zur Verwendung dieser Kennung: android-developers.blogspot.com/2011/03/…
David Snabel-Caunt

8
Was ist mit einem Android-Tablet, abgesehen von der Android-Mikrowelle? :)
Ajacian81

21
Diese Methode sollte vermieden werden. Dies funktioniert auf Telefonen, jedoch nicht auf Geräten ohne Telefonchip (Tablets sind ein Beispiel). Ab 2.3 können Sie android.os.Build.SERIAL verwenden, aber lesen Sie das Entwicklerblog, das @DavidCaunt vorgeschlagen hat.
John Mitchell

71

Wie Dave Webb erwähnt, enthält der Android Developer Blog einen Artikel , der dies behandelt.

Ich habe mit jemandem bei Google gesprochen, um zusätzliche Informationen zu einigen Punkten zu erhalten. Folgendes habe ich entdeckt, das im oben genannten Blog-Beitrag NICHT erwähnt wird:

  • ANDROID_ID ist die bevorzugte Lösung. ANDROID_ID ist auf Versionen von Android <= 2.1 oder> = 2.3 absolut zuverlässig. 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 dieselbe ANDROID_ID , nämlich 9774d56d682e549c . Dies ist übrigens auch die gleiche Geräte-ID, die vom Emulator gemeldet wurde.
  • Google glaubt, dass OEMs das Problem für viele oder die meisten ihrer Geräte behoben haben, aber ich konnte überprüfen, dass es zumindest ab 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 für jedes Gerät eine eindeutige UUID generiert. Dabei wird ANDROID_ID als Startwert verwendet, wobei bei Bedarf auf TelephonyManager.getDeviceId () zurückgegriffen wird. Wenn dies fehlschlägt, wird auf eine zufällig generierte eindeutige UUID zurückgegriffen Dies bleibt auch bei App-Neustarts erhalten (jedoch nicht bei App-Neuinstallationen).

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

1
Welche Berechtigungen sind erforderlich, damit eine App dies verwenden kann?
Dave L.

1
<Verwendet-Erlaubnis Android: Name = "android.permission.READ_PHONE_STATE"> </ Verwendet-Erlaubnis>
Gabrielle

1
@ ef2011 es ist das doppelt überprüfte
Sperrmuster

3
Danke fürs Schreiben. Aber was hindert jemanden mit einem gerooteten Telefon daran, die Datei device_id.xml einfach zu bearbeiten, um eine neue UUID seiner Wahl einzugeben? (dh um eine 'kostenlose Testversion' zu umgehen) Wäre es nicht besser, wenn die Klasse den Wert nur in einer Voreinstellungsdatei speichern würde, wenn sie auf die Zufalls-ID-Methode zurückgreifen muss? Andernfalls muss es nicht zwischen den Anwendungsläufen beibehalten werden. Es ist sicherer, neu zu generieren.
Carlos P

1
"ANDROID_ID" ist die bevorzugte Lösung. "Beachten Sie, dass ANDROID_ID ein Gerät nicht mehr eindeutig identifiziert: stackoverflow.com/a/13465373/150016
Tom

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

Dieser Code gibt die Seriennummer des Geräts mithilfe einer versteckten Android-API zurück.


7
Dies gibt mir nur den gleichen Wert wie der, den ich mit android.os.Build.SERIAL
Josephus

Irre ich mich oder ist diese Seriennummer auf allen Geräten mit einem bestimmten benutzerdefinierten ROM gleich? Die Seriennummer meines Geräts (im Eclipse Device Launcher) zeigt 01234567890ABC für ein Telefon mit einem benutzerdefinierten ROM an.
Peterdk

@Peterdk auf meinem Gerät mit Cyanogen-9 beide Methoden (vor andy-9 wie in der Antwort und die einfachere ab andy-9) melden korrektes s / n (das gleiche wie auf dem Herstelleraufkleber). Dies kann jedoch von einer bestimmten benutzerdefinierten ROM-Version abhängen. Welche Rom / Version benutzt du?
Morgwai

16
String deviceId = Settings.System.getString(getContentResolver(),
                                Settings.System.ANDROID_ID);

Es kann jedoch nicht garantiert werden, dass die Android-ID eine eindeutige Kennung ist.


@Paresh Mayani, es ist schwer zu sagen, was das Problem sein könnte, ohne auf den Code zu schauen. Meine einzige Annahme ist, dass getContentResolverdas zurückkehrt null. Es kann sich jedoch lohnen, eine Frage zu öffnen und Ihren Code zu veröffentlichen.
Anthony Forloney

4
Diese ID stammt aus dem Google-Konto, das dem Telefon zugeordnet ist. Der Simulator hat normalerweise keinen. Ein echtes Telefon hat möglicherweise auch kein Telefon. Außerdem ist dokumentiert, dass es sich beim Zurücksetzen auf die Werkseinstellungen ändern kann, und es kann jederzeit auf einem gerooteten Telefon beliebig geändert werden. Benutzung auf eigene Gefahr. Es gibt keine gute Alternative - andere vorläufige Geräte-IDs sind entweder nicht universell verfügbar oder nicht eindeutig oder beides. Weitere Antworten finden Sie für den Rest dieser traurigen Geschichte.
Seva Alekseyev

14

Es gibt einen ausgezeichneten Beitrag im Blog des Android-Entwicklers, in dem dies diskutiert wird .

Es wird davon abgeraten, es zu verwenden, TelephonyManager.getDeviceId()da es auf Android-Geräten, die keine Telefone wie Tablets sind, nicht funktioniertREAD_PHONE_STATE nicht funktioniert. Erlaubnis und funktioniert nicht auf allen Telefonen zuverlässig.

Stattdessen können Sie eine der folgenden Optionen verwenden:

  • MAC-Adresse
  • Ordnungsnummer
  • ANDROID_ID

In diesem Beitrag werden die Vor- und Nachteile der einzelnen Elemente erläutert. Es lohnt sich, sie zu lesen, damit Sie herausfinden können, welches für Sie am besten geeignet ist.


+1, hi dave, danke für die Klarstellung, weil ich gerade eine Anwendung für das Tablet entwickle, bei der ich eine eindeutige ID des Android-Geräts haben muss. Was soll ich also verwenden, um ein eindeutiges Android-Tablet-Gerät zu erhalten?
Paresh Mayani

12

Verwenden Sie Settings.Secure.ANDROID_ID für eine einfache Nummer, die für das Gerät eindeutig und für die gesamte Lebensdauer konstant ist (außer beim Zurücksetzen auf die Werkseinstellungen oder beim Hacken) .

String id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);

So verwenden Sie die Seriennummer des Geräts (die unter "Systemeinstellungen / Info / Status" angegebene), falls verfügbar, und greifen auf die Android-ID zurück:

String serialNumber = Build.SERIAL != Build.UNKNOWN ? Build.SERIAL : Secure.getString(getContentResolver(), Secure.ANDROID_ID);

unkomplizierte Antwort !!
Faris Faris

Build.SERİAL in Java veraltet
Eyyüp Alkış

7

Die IMEI ist gut, funktioniert aber nur auf Android-Geräten mit Telefon. Sie sollten auch die Unterstützung für Tablets oder andere Android-Geräte in Betracht ziehen, die kein Telefon haben.

Sie haben einige Alternativen wie: Erstellen Sie Klassenmitglieder, BT MAC, WLAN MAC oder noch besser - eine Kombination aus all diesen.

Ich habe diese Details in einem Artikel in meinem Blog erklärt, siehe: http://www.pocketmagic.net/?p=1662


6

Da hier keine Antwort erwähnt wird, wird eine perfekte, ausfallsichere ID erwähnt, die sowohl durch Systemaktualisierungen BESTÄNDIG ist als auch auf ALLEN Geräten vorhanden ist (hauptsächlich aufgrund der Tatsache, dass es keine individuelle Lösung von Google gibt), habe ich beschlossen, eine Methode zu veröffentlichen Das nächstbeste ist, wenn Sie zwei der verfügbaren Bezeichner kombinieren und zur Laufzeit eine Auswahl treffen.

Vor dem Code 3 Fakten:

  1. TelephonyManager.getDeviceId()(akaIMEI) funktioniert nicht gut oder überhaupt nicht für Geräte ohne GSM, 3G, LTE usw., gibt jedoch immer eine eindeutige ID zurück, wenn verwandte Hardware vorhanden ist , selbst wenn keine SIM-Karte eingelegt ist oder wenn kein SIM-Steckplatz vorhanden ist ( Einige OEMs haben dies getan.

  2. Da Gingerbread (Android 2.3) android.os.Build.SERIAL auf jedem Gerät vorhanden sein muss, das keine IMEI bereitstellt , dh die oben genannte Hardware gemäß der Android-Richtlinie nicht vorhanden ist.

  3. Aufgrund der Tatsache (2.) ist IMMER mindestens eine dieser beiden eindeutigen Kennungen vorhanden , und SERIAL kann gleichzeitig mit IMEI vorhanden sein.

Hinweis: Fakt (1.) und (2.) basieren auf Google-Aussagen

LÖSUNG

Mit den obigen Fakten kann man immer eine eindeutige Kennung haben, indem man prüft, ob IMEI-gebundene Hardware vorhanden ist, und auf SERIAL zurückgreifen, wenn dies nicht der Fall ist, da man nicht prüfen kann, ob die vorhandene SERIAL gültig ist. Die folgende statische Klasse enthält zwei Methoden zum Überprüfen des Vorhandenseins und Verwenden von IMEI oder SERIAL:

import java.lang.reflect.Method;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;

public class IDManagement {

    public static String getCleartextID_SIMCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

        if(isSIMAvailable(mContext,telMgr)){
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId());
            return telMgr.getDeviceId();

        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static String getCleartextID_HARDCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if(telMgr != null && hasTelephony(mContext)){           
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId() + "");

            return telMgr.getDeviceId();    
        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static boolean isSIMAvailable(Context mContext, 
            TelephonyManager telMgr){

        int simState = telMgr.getSimState();

        switch (simState) {
        case TelephonyManager.SIM_STATE_ABSENT:
            return false;
        case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
            return false;
        case TelephonyManager.SIM_STATE_PIN_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_PUK_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_READY:
            return true;
        case TelephonyManager.SIM_STATE_UNKNOWN:
            return false;
        default:
            return false;
        }
    }

    static public boolean hasTelephony(Context mContext)
    {
        TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm == null)
            return false;

        //devices below are phones only
        if (Build.VERSION.SDK_INT < 5)
            return true;

        PackageManager pm = mContext.getPackageManager();

        if (pm == null)
            return false;

        boolean retval = false;
        try
        {
            Class<?> [] parameters = new Class[1];
            parameters[0] = String.class;
            Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
            Object [] parm = new Object[1];
            parm[0] = "android.hardware.telephony";
            Object retValue = method.invoke(pm, parm);
            if (retValue instanceof Boolean)
                retval = ((Boolean) retValue).booleanValue();
            else
                retval = false;
        }
        catch (Exception e)
        {
            retval = false;
        }

        return retval;
    }


}

Ich würde raten zur Verwendung getCleartextID_HARDCHECK. Wenn die Reflexion nicht in Ihrer Umgebung haftet, verwenden Sie getCleartextID_SIMCHECKstattdessen die Methode. Berücksichtigen Sie jedoch, dass sie an Ihre spezifischen Anforderungen an die SIM-Präsenz angepasst werden sollte.

PS : Bitte beachten Sie, dass es OEMs gelungen ist, SERIAL gegen die Google-Richtlinien (mehrere Geräte mit derselben SERIAL) auszutauschen. Wie bereits erwähnt, gibt es bei einem großen OEM mindestens einen bekannten Fall (nicht bekannt gegeben und ich weiß nicht, welche Marke) es ist entweder, ich vermute Samsung).

Haftungsausschluss : Dies beantwortet die ursprüngliche Frage nach einer eindeutigen Geräte-ID. Das OP führte jedoch Unklarheiten ein, indem es angab, dass er eine eindeutige ID für eine APP benötigt. Selbst wenn für solche Szenarien Android_ID besser wäre, wird es beispielsweise nach einer Titan-Sicherung einer App durch zwei verschiedene ROM-Installationen NICHT funktionieren (kann sogar dasselbe ROM sein). Meine Lösung behält die Persistenz bei, die unabhängig von einem Flash oder einem Zurücksetzen auf die Werkseinstellungen ist, und schlägt nur fehl, wenn IMEI- oder SERIAL-Manipulationen durch Hacks / Hardware-Mods auftreten.


5

Es gibt Probleme mit allen oben genannten Ansätzen. Bei Google i / o veröffentlichte Reto Meier eine solide Antwort darauf, wie dies angegangen werden sollte, um die Anforderungen der meisten Entwickler zu erfüllen und Benutzer über Installationen hinweg zu verfolgen.

Mit diesem Ansatz erhalten Sie eine anonyme, sichere Benutzer-ID, die für den Benutzer auf verschiedenen Geräten (einschließlich Tablets, basierend auf dem primären Google-Konto) und bei Installationen auf demselben Gerät dauerhaft bleibt. Der grundlegende Ansatz besteht darin, eine zufällige Benutzer-ID zu generieren und diese in den gemeinsamen Einstellungen der Apps zu speichern. Anschließend verwenden Sie den Backup-Agenten von Google, um die mit dem Google-Konto verknüpften freigegebenen Einstellungen in der Cloud zu speichern.

Gehen wir den vollständigen Ansatz durch. Zuerst müssen wir mit dem Android Backup Service ein Backup für unsere SharedPreferences erstellen. Registrieren Sie zunächst Ihre App über diesen Link: http://developer.android.com/google/backup/signup.html

Google gibt Ihnen einen Sicherungsdienstschlüssel, den Sie dem Manifest hinzufügen müssen. Sie müssen der Anwendung außerdem mitteilen, dass sie den BackupAgent wie folgt verwenden soll:

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

Anschließend müssen Sie den Sicherungsagenten erstellen und ihn anweisen, den Hilfsagenten für freigegebene Einstellungen zu verwenden:

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

Um die Sicherung abzuschließen, müssen Sie in Ihrer Hauptaktivität eine Instanz von BackupManager erstellen:

BackupManager backupManager = new BackupManager(context);

Erstellen Sie abschließend eine Benutzer-ID, falls diese noch nicht vorhanden ist, und speichern Sie sie in den 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;
}

Diese Benutzer-ID bleibt jetzt installationsübergreifend erhalten, auch wenn der Benutzer zwischen Geräten wechselt.

Weitere Informationen zu diesem Ansatz finden Sie in Retos Vortrag hier http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html

Ausführliche Informationen zur Implementierung des Sicherungsagenten finden Sie auf der Entwicklerseite hier: http://developer.android.com/guide/topics/data/backup.html. Ich empfehle insbesondere den Abschnitt unten zum Testen, wie dies bei der Sicherung der Fall ist nicht sofort passieren und um zu testen, müssen Sie die Sicherung erzwingen.


2

Eine andere Möglichkeit besteht darin, / sys / class / android_usb / android0 / iSerial in einer App ohne jegliche Berechtigungen zu verwenden.

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

Um dies in Java zu tun, würde man einfach einen FileInputStream verwenden, um die iSerial-Datei zu öffnen und die Zeichen vorzulesen. Stellen Sie nur sicher, dass Sie es in einen Ausnahmebehandler einbinden, da nicht alle Geräte über diese Datei verfügen.

Es ist bekannt, dass mindestens die folgenden Geräte diese Datei weltweit lesbar haben:

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

Sie können meinen Blog-Beitrag auch hier sehen: http://insitusec.blogspot.com/2013/01/leaking-android-hardware-serial-number.html, wo ich diskutiere, welche anderen Dateien für Informationen verfügbar sind.


Vielen Dank für Ihre Antwort! Bitte lesen Sie die FAQ zur Eigenwerbung sorgfältig durch. Beachten Sie auch , dass Sie jedes Mal, wenn Sie auf Ihre eigene Website / Ihr eigenes Produkt verlinken, einen Haftungsausschluss veröffentlichen müssen.
Andrew Barber

1

Wie @haserman sagt:

TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

Es ist jedoch erforderlich, die Berechtigung in die Manifestdatei aufzunehmen:

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

1

Eindeutige Geräte-ID des Android-Betriebssystemgeräts als Zeichenfolge.

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

Ich empfehle diese von Google :: vorgeschlagene Methode jedoch dringend.

App-Installationen identifizieren


1

Build.SERIALDies ist der einfachste Weg, obwohl er nicht ganz zuverlässig ist, da er leer sein oder manchmal einen anderen Wert ( Proof 1 , Proof 2 ) zurückgeben kann als in den Einstellungen Ihres Geräts angegeben.

Abhängig vom Hersteller des Geräts und der Android-Version gibt es verschiedene Möglichkeiten, diese Nummer zu ermitteln . Daher habe ich beschlossen, alle möglichen Lösungen, die ich finden konnte, in einem einzigen Inhalt zusammenzustellen . Hier ist eine vereinfachte Version davon:

public static String getSerialNumber() {
    String serialNumber;

    try {
        Class<?> c = Class.forName("android.os.SystemProperties");
        Method get = c.getMethod("get", String.class);

        serialNumber = (String) get.invoke(c, "gsm.sn1");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ril.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ro.serialno");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "sys.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = Build.SERIAL;

        // If none of the methods above worked
        if (serialNumber.equals(""))
            serialNumber = null;
    } catch (Exception e) {
        e.printStackTrace();
        serialNumber = null;
    }

    return serialNumber;
}

0

Ich weiß, dass diese Frage alt ist, aber sie kann in einer Codezeile gestellt werden

String deviceID = Build.SERIAL;


AFAIK, dies ändert sich nach dem Betriebssystem-Update des Geräts, z. B. von 4.4.2 auf 4.4.4 oder was auch immer.
Den Drobiazko

-1

Ich fand die Beispielklasse, die oben von @emmby gepostet wurde, ein guter Ausgangspunkt. Aber es hat ein paar Mängel, wie von anderen Plakaten erwähnt. Das wichtigste ist, dass die UUID unnötig in einer XML-Datei gespeichert bleibt und danach immer aus dieser Datei abgerufen wird. Dies eröffnet der Klasse einen einfachen Hack: Jeder mit einem verwurzelten Telefon kann die XML-Datei bearbeiten, um sich eine neue UUID zu geben.

Ich habe den Code so aktualisiert, dass er nur dann in XML verbleibt, wenn dies unbedingt erforderlich ist (dh wenn eine zufällig generierte UUID verwendet wird), und die Logik gemäß der Antwort von @Brill Pappin neu berücksichtigt:

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 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) || (androidId == null) ) {
                                final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();

                                if (deviceId != null)
                                {
                                    uuid = UUID.nameUUIDFromBytes(deviceId.getBytes("utf8"));
                                }
                                else
                                {
                                    uuid = UUID.randomUUID();

                                    // Write the value out to the prefs file so it persists
                                    prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();
                                }
                            }
                            else
                            {
                                uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
                            } 
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }



                    }

                }
            }
        }

    }


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

Das Einfügen der ID in gemeinsame Einstellungen gefährdet das ursprüngliche Ziel, eine wirklich eindeutige ID zu erhalten. Wenn Sie beispielsweise diese ID als Schlüssel für einige Einschränkungen verwenden möchten, werden Sie geschraubt, wenn erfahrene Benutzer ein Gerät rooten und Zugriff auf Ihre freigegebene Einstellungsdatei erhalten. Sein Inhalt darf kopiert werden, was bedeutet ...
Eugene Wechsler

Es gibt auch einen weiteren Fehler in der Antwort von MB und Ihrer. Wenn Sie randomUUID als Geräte-ID und AppID verwenden, funktioniert dies für alle Geräte auf der ganzen Welt, unabhängig davon, ob es sich um Telefone handelt oder nicht oder ob es sich um Google Exp-Geräte handelt oder nicht.
Fred Grott

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.