Czy istnieje unikalny identyfikator urządzenia z systemem Android?

Czy urządzenia z Androidem mają unikalny identyfikator, a jeśli tak, to jaki jest prosty sposób uzyskania do niego dostępu za pomocą Javy?

Author: alamshahbaz16497, 2010-05-07

30 answers

Settings.Secure#ANDROID_ID zwraca Android ID jako unikalne dla każdego użytkownika 64-struna sześciokątna.

import android.provider.Settings.Secure;

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

Aktualizacja: W ostatnich wersjach Androida wiele problemów z ANDROID_ID zostało rozwiązanych i uważam, że takie podejście nie jest już konieczne. Proszę spojrzeć na odpowiedź Anthony ' ego.

Pełne ujawnienie: moja aplikacja pierwotnie używała poniższego podejścia, ale nie używa już tego podejścia, a teraz używamy podejścia opisanego w Blog dewelopera Androida wpis, który odpowiedź emmby linki do (mianowicie generowanie i zapisywanie UUID#randomUUID()).


Istnieje wiele odpowiedzi na to pytanie, z których większość będzie działać tylko "niektóre" czasu, i niestety to nie wystarczy.

Na podstawie moich testów urządzeń (Wszystkie telefony, z których przynajmniej jeden nie jest aktywowany): {]}
  1. wszystkie testowane urządzenia zwracają wartość TelephonyManager.getDeviceId()
  2. wszystkie urządzenia GSM (wszystkie testowane z kartą SIM) zwróciły wartość TelephonyManager.getSimSerialNumber()
  3. wszystkie urządzenia CDMA zwróciły null dla getSimSerialNumber() (zgodnie z oczekiwaniami)
  4. wszystkie Urządzenia z dodanym kontem Google zwróciły wartość ANDROID_ID
  5. wszystkie urządzenia CDMA zwróciły tę samą wartość (lub wyprowadzenie tej samej wartości) zarówno dla ANDROID_ID, jak i TelephonyManager.getDeviceId() -- tak długo, jak konto Google zostało dodane podczas konfiguracji.
  6. nie miałem jeszcze okazji przetestować urządzeń GSM bez SIM, urządzenia GSM bez dodanego konta Google, ani żadnego z urządzeń w trybie samolotowym.

Więc jeśli chcesz coś unikalnego dla samego urządzenia, TM.getDeviceId() Powinno wystarczyć. Oczywiście niektórzy użytkownicy są bardziej paranoiczni niż inni, więc może być przydatne hash 1 lub więcej z tych identyfikatorów, tak że ciąg jest nadal praktycznie unikalny dla urządzenia, ale nie identyfikuje bezpośrednio rzeczywistego urządzenia użytkownika. Na przykład, używając String.hashCode(), w połączeniu z 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();

Może spowodować coś w rodzaju: 00000000-54b3-e7c7-0000-000046bffd97

Dla mnie działa wystarczająco dobrze.

Jak wspomina Richard poniżej, nie zapominaj, że potrzebujesz pozwolenia aby przeczytać właściwości TelephonyManager, dodaj to do manifestu:

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

Import libs

import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
 1068
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-01 14:37:26

Ostatnia Aktualizacja: 6/2/15


Po przeczytaniu każdego postu o tworzeniu unikalnego identyfikatora, blogu programisty Google i dokumentacji Androida, czuję, że 'Pseudo ID' jest najlepszą możliwą opcją.

Główny problem: Hardware vs Software

Hardware

    Użytkownicy mogą zmieniać swój sprzęt, tablet lub telefon z Androidem, więc unikalne identyfikatory oparte na sprzęcie nie są dobrymi pomysłami na śledzenie użytkowników]}
  • do śledzenia Sprzęt , to jest świetny pomysł

Oprogramowanie

    Użytkownicy mogą wyczyścić / zmienić ROM, jeśli są zakorzenione.]} Możesz śledzić użytkowników na różnych platformach (iOS, Android, Windows i www)]} Jeśli użytkownik nie jest zalogowany, może to zrobić za pomocą OAuth, co oznacza, że użytkownik nie jest zalogowany.]}

Ogólny podział z Androidem

- gwarancja wyjątkowości (obejmują urządzenia zakorzenione) dla API > = 9/10 (99,5% urządzeń z Androidem)

- Brak dodatkowych uprawnień

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

Podziękowania dla @ stansult za zamieszczenie wszystkie nasze opcje (W tym pytaniu o przepełnienie stosu).

Lista opcji-powody, dla których/ dlaczego ich nie używać:

  • E - Mail Użytkownika-Oprogramowanie

  • Numer Telefonu Użytkownika-Oprogramowanie

    • użytkownicy mogą zmieniać numery telefonów-bardzo mało prawdopodobne
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • IMEI-Hardware (tylko telefony, potrzebuje android.permission.READ_PHONE_STATE)

    • większość użytkowników nienawidzi faktu, że w pozwoleniu jest napisane "rozmowy telefoniczne". Niektórzy użytkownicy dają złe oceny, ponieważ uważają, że po prostu kradniesz ich osobiste informacje, kiedy wszystko, co naprawdę chcesz zrobić, to śledzić Instalacje urządzenia. To oczywiste, że zbierasz dane.
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • Android ID-Hardware (może być null, może zmienić się po przywróceniu ustawień fabrycznych, może być zmieniony na zrootowanym urządzeniu)

    • ponieważ może być 'null' , możemy sprawdzić 'null' I zmienić jego wartość, ale to oznacza, że nie będzie już unikalna.
    • Jeśli masz użytkownika z urządzeniem do przywracania ustawień fabrycznych, wartość może mieć zmienione lub zmienione na urządzeniu zakorzenione, więc mogą być duplikaty wpisów, jeśli śledzisz instalacje użytkownika.
  • Adres MAC WLAN-Sprzęt (potrzebuje android.permission.ACCESS_WIFI_STATE)

    • to może być druga najlepsza opcja, ale nadal zbierasz i przechowujesz unikalny identyfikator, który pochodzi bezpośrednio od użytkownika. Jest to oczywiste, że zbierasz dane.
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
  • Adres MAC Bluetooth - Sprzęt (Urządzenia z Bluetooth, potrzeby android.permission.BLUETOOTH)

    • większość aplikacji na rynku nie używa Bluetooth, więc jeśli Twoja aplikacja nie używa Bluetooth, a Ty to włączysz, użytkownik może stać się podejrzany.
    • <uses-permission android:name="android.permission.BLUETOOTH "/>
  • Pseudo-unikalne oprogramowanie ID (dla wszystkich urządzeń z Androidem)

    • Bardzo możliwe, mogą zawierać kolizje-zobacz moją metodę zamieszczoną poniżej!
    • to pozwala na "prawie unikalny" identyfikator użytkownika bez brania niczego, co jest prywatne. Możesz utworzyć własny anonimowy identyfikator z informacji o urządzeniu.

Wiem, że nie ma żadnego "doskonałego" sposobu na uzyskanie unikalnego identyfikatora bez użycia uprawnień; jednak czasami naprawdę musimy tylko śledzić instalację urządzenia. Jeśli chodzi o tworzenie unikalnego identyfikatora, możemy utworzyć "pseudo unikalny identyfikator" wyłącznie na podstawie informacji, które daje nam Android API bez użycia dodatkowych uprawnienia. W ten sposób możemy pokazać użytkownikowi szacunek i spróbować zaoferować dobre wrażenia użytkownika.

Z pseudo-unikalnym identyfikatorem, tak naprawdę napotykasz tylko fakt, że mogą istnieć duplikaty oparte na fakcie, że istnieją podobne urządzenia. Możesz dostosować połączoną metodę, aby uczynić ją bardziej wyjątkową; jednak niektórzy programiści muszą śledzić instalacje urządzeń, a to załatwi sprawę lub wydajność w oparciu o podobne urządzenia.

API > = 9:

Jeśli ich urządzenie z Androidem jest API 9 lub więcej, to jest gwarantowane być unikalne ze względu na ' Build.Pole szeregowe.

Pamiętaj, technicznie brakuje Ci tylko około 0,5% użytkowników , którzy mają API . Więc możesz skupić się na reszcie: to jest 99,5% użytkowników!

API

Jeśli urządzenie Użytkownika z Androidem jest niższe niż API 9; mam nadzieję, że nie zrobili resetu fabrycznego i ich ' bezpieczne.ANDROID_ID "zostanie zachowany lub nie "null". (patrz http://developer.android.com/about/dashboards/index.html )

Jeśli Wszystko inne zawiedzie:

Jeśli Wszystko inne zawiedzie, jeśli użytkownik ma niższy niż API 9 (niższy niż Gingerbread), zresetował swoje urządzenie lub ' Bezpieczne.ANDROID_ID "zwraca " null" , a następnie po prostu zwrócony IDENTYFIKATOR będzie oparty wyłącznie na informacjach o urządzeniu z Androidem. Tutaj mogą się zdarzyć kolizje.

Zmiany:

  • Usunięto ' Android.SECURE_ID " ze względu na resetowanie fabryczne może spowodować wartość do zmiany
  • edytowano kod do zmiany w API
  • zmieniono Pseudo

Proszę spojrzeć na poniższą metodę:

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

Nowy (dla aplikacji z reklamami i usługami Google Play):

Z konsoli programisty Google Play:

Od 1 sierpnia 2014 r., Polityka programu programisty Google Play wymaga przesłania i aktualizacji wszystkich nowych aplikacji, aby używać identyfikatora reklamy w zamiast innych uporczywych identyfikatory do wszelkich celów reklamowych. Dowiedz się więcej

Realizacja :

Pozwolenie:

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

Kod:

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

Źródło / Dokumenty:

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

Ważne:

Ma na celu, aby ID reklamy całkowicie Zastąp istniejące wykorzystanie innych identyfikatorów do celów reklamowych (takich jak użycie ANDROID_ID w Ustawieniach.Bezpieczne), gdy usługi Google Play są dostępne. Przypadki gdzie usługi Google Play są niedostępne są wskazywane przez GooglePlayServicesNotAvailableException rzucane przez getAdvertisingIdInfo().

Ostrzeżenie, użytkownicy mogą zresetować:

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

Próbowałem odwoływać się do każdego linku, który Wziąłem informacje od. Jeśli brakuje cię i musisz być uwzględniony, skomentuj!

Google Player Services InstanceID

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

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

Jak wspomina Dave Webb, Blog programisty Androida ma Artykuł , który opisuje to. Ich preferowanym rozwiązaniem jest śledzenie instalacji aplikacji, a nie urządzeń, co będzie dobrze działać w większości przypadków użycia. Post na blogu pokaże Ci kod niezbędny do tego, aby to działało i polecam go sprawdzić.

Jednak post na blogu omawia rozwiązania, jeśli potrzebujesz identyfikatora urządzenia, a nie identyfikatora instalacji aplikacji. Rozmawiałem z kimś z Google, aby uzyskać kilka dodatkowych wyjaśnień na temat kilku elementów w przypadku, gdy trzeba to zrobić. Oto, co odkryłem o identyfikatorach urządzeń, o których nie wspomniano we wspomnianym poście na blogu:

  • ANDROID_ID jest preferowanym identyfikatorem urządzenia. ANDROID_ID jest całkowicie niezawodny w wersjach Androida =2.3. Tylko 2.2 ma problemy wymienione w poście.
  • Błąd ANDROID_ID w 2.2 dotyczy kilku urządzeń różnych producentów.
  • As far as I ' ve been w stanie określić, wszystkie dotknięte urządzenia mają ten sam IDENTYFIKATOR ANDROID_ID , czyli 9774d56d682e549c. Który jest również tym samym identyfikatorem urządzenia zgłoszonym przez emulator, btw.
  • Google uważa, że producenci OEM naprawili problem dla wielu lub większości swoich urządzeń, ale byłem w stanie zweryfikować, że od początku kwietnia 2011, przynajmniej, nadal jest dość łatwo znaleźć urządzenia, które mają uszkodzony ANDROID_ID.

W oparciu o zalecenia Google wdrożyłem klasę, która wygeneruje unikalny UUID dla każdego urządzenia, używając ANDROID_ID jako zalążka, w razie potrzeby, powracając do TelephonyManager.getDeviceId() w razie potrzeby, a jeśli to się nie powiedzie, odwołuje się do losowo generowanego unikalnego identyfikatora UUID, który jest utrzymywany w trakcie ponownego uruchamiania aplikacji (ale nie ponownej instalacji aplikacji).

Należy pamiętać, że w przypadku urządzeń, które muszą wycofać się na ID urządzenia, unikalny identyfikator będzie utrzymywał się przez Resetowanie fabryczne. To jest coś, o czym należy pamiętać. Jeśli chcesz upewnić się, że fabryka reset zresetuje Twój unikalny identyfikator, możesz rozważyć powrót bezpośrednio do losowego identyfikatora UUID zamiast identyfikatora urządzenia.

Ponownie, ten kod jest dla identyfikatora urządzenia, a nie ID instalacji aplikacji. W większości sytuacji identyfikator instalacji aplikacji jest prawdopodobnie tym, czego szukasz. Ale jeśli potrzebujesz identyfikatora urządzenia, poniższy kod prawdopodobnie zadziała dla Ciebie.

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

public class DeviceUuidFactory {

    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";
    protected volatile static UUID uuid;

    public DeviceUuidFactory(Context context) {
        if (uuid == null) {
            synchronized (DeviceUuidFactory.class) {
                if (uuid == null) {
                    final SharedPreferences prefs = context
                            .getSharedPreferences(PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null);
                    if (id != null) {
                        // Use the ids previously computed and stored in the
                        // prefs file
                        uuid = UUID.fromString(id);
                    } else {
                        final String androidId = Secure.getString(
                            context.getContentResolver(), Secure.ANDROID_ID);
                        // Use the Android ID unless it's broken, in which case
                        // fallback on deviceId,
                        // unless it's not available, then fallback on a random
                        // number which we store to a prefs file
                        try {
                            if (!"9774d56d682e549c".equals(androidId)) {
                                uuid = UUID.nameUUIDFromBytes(androidId
                                        .getBytes("utf8"));
                            } else {
                                final String deviceId = (
                                    (TelephonyManager) context
                                    .getSystemService(Context.TELEPHONY_SERVICE))
                                    .getDeviceId();
                                uuid = deviceId != null ? UUID
                                    .nameUUIDFromBytes(deviceId
                                            .getBytes("utf8")) : UUID
                                    .randomUUID();
                            }
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }
                        // Write the value out to the prefs file
                        prefs.edit()
                                .putString(PREFS_DEVICE_ID, uuid.toString())
                                .commit();
                    }
                }
            }
        }
    }

    /**
     * Returns a unique UUID for the current android device. As with all UUIDs,
     * this unique ID is "very highly likely" to be unique across all Android
     * devices. Much more so than ANDROID_ID is.
     * 
     * The UUID is generated by using ANDROID_ID as the base key if appropriate,
     * falling back on TelephonyManager.getDeviceID() if ANDROID_ID is known to
     * be incorrect, and finally falling back on a random UUID that's persisted
     * to SharedPreferences if getDeviceID() does not return a usable value.
     * 
     * In some rare circumstances, this ID may change. In particular, if the
     * device is factory reset a new device ID may be generated. In addition, if
     * a user upgrades their phone from certain buggy implementations of Android
     * 2.2 to a newer, non-buggy version of Android, the device ID may change.
     * Or, if a user uninstalls your app on a device that has neither a proper
     * Android ID nor a Device ID, this ID may change on reinstallation.
     * 
     * Note that if the code falls back on using TelephonyManager.getDeviceId(),
     * the resulting ID will NOT change after a factory reset. Something to be
     * aware of.
     * 
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID
     * directly.
     * 
     * @see http://code.google.com/p/android/issues/detail?id=10603
     * 
     * @return a UUID that may be used to uniquely identify your device for most
     *         purposes.
     */
    public UUID getDeviceUuid() {
        return uuid;
    }
}
 318
Author: emmby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-10 14:22:51

Oto kod, który Reto Meier użył w prezentacji Google I / O w tym roku, aby uzyskać unikalny identyfikator dla użytkownika:

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

Jeśli połączysz to ze strategią tworzenia kopii zapasowych, aby wysłać Preferencje do chmury (opisaną również w talku Reto , powinieneś mieć identyfikator, który łączy się z użytkownikiem i pozostaje w pobliżu Po wyczyszczeniu lub nawet wymianie urządzenia. Planuję wykorzystać to w analityce w przyszłości (innymi słowy, jeszcze tego nie zrobiłem :).

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

Możesz również wziąć pod uwagę adres MAC adaptera Wi-Fi. Pobrano:

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

Wymaga pozwolenia android.permission.ACCESS_WIFI_STATE w manifeście.

Zgłoszono, że są dostępne nawet wtedy, gdy Wi-Fi nie jest połączone. Jeśli Joe z powyższej odpowiedzi da temu spróbować na swoich wielu urządzeniach, byłoby miło.

Na niektórych urządzeniach nie jest ona dostępna, gdy sieć Wi-Fi jest wyłączona.

Uwaga: z Androida 6.x, zwraca spójny fałszywy adres mac: 02:00:00:00:00:00

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

Jest raczej przydatna informacja Proszę..

Obejmuje pięć różnych typów ID:

  1. IMEI (tylko dla urządzeń z systemem Android z telefonem; potrzeby android.permission.READ_PHONE_STATE)
  2. Pseudo-unikalny identyfikator (dla wszystkich urządzeń z Androidem)
  3. Android ID (może być null, może zmienić się po przywróceniu ustawień fabrycznych, może być zmieniony na zrootowanym telefonie)
  4. adres MAC WLAN string (needs android.permission.ACCESS_WIFI_STATE)
  5. BT Mac Address string (Urządzenia z Bluetooth, needs android.permission.BLUETOOTH)
 80
Author: stansult,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-08 02:16:52

Oficjalny blog deweloperów Androida ma teraz pełny artykuł tylko na ten temat, Identyfikacja instalacji aplikacji.

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

At Google I/O Reto Meier opublikował solidną odpowiedź na to, jak podejść do tego, co powinno zaspokoić większość programistów potrzeb śledzenia użytkowników w różnych instalacjach. Anthony Nolan pokazuje kierunek w swojej odpowiedzi, ale pomyślałem, że napiszę pełne podejście, aby inni mogli łatwo zobaczyć, jak to zrobić (Zajęło mi trochę czasu, aby dowiedzieć się szczegółów).

Takie podejście daje anonimowy, bezpieczny identyfikator użytkownika, który będzie trwały dla użytkownika na różnych urządzeniach (w oparciu o podstawowe konto Google) i w różnych instalacjach. Podstawowe podejście polega na wygenerowaniu losowego identyfikatora użytkownika i zapisaniu go we wspólnych preferencjach aplikacji. Następnie agent kopii zapasowych Google przechowuje w chmurze udostępnione preferencje powiązane z kontem Google.

Przejdźmy do pełnego podejścia. Po pierwsze, musimy utworzyć kopię zapasową dla naszych SharedPreferences za pomocą usługi kopii zapasowej Android. Zacznij od rejestracji aplikacji za pośrednictwem http://developer.android.com/google/backup/signup.html. [5]}Google da ci klucz usługi kopii zapasowej, który musisz dodać do manifestu. Musisz również powiedzieć aplikacji, aby używała BackupAgent w następujący sposób:
<application android:label="MyApplication"
         android:backupAgent="MyBackupAgent">
    ...
    <meta-data android:name="com.google.android.backup.api_key"
        android:value="your_backup_service_key" />
</application>

Następnie należy utworzyć agenta kopii zapasowej i powiedzieć mu, aby używał agenta pomocniczego dla sharedpreferences:

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

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

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

Aby wykonać kopię zapasową, musisz utworzyć instancję BackupManager w głównej aktywności:

BackupManager backupManager = new BackupManager(context);
Na koniec Utwórz identyfikator użytkownika, jeśli jeszcze nie istnieje, i zapisz go w 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;
}

Ten User_ID będzie teraz trwałe w całej instalacji, nawet jeśli użytkownik przenosi urządzenie.

Aby uzyskać więcej informacji na temat tego podejścia, Zobacz referat Reto .

Oraz szczegółowe informacje na temat implementacji agenta backupu znajdują się Backup danych. Szczególnie polecam sekcję na dole na temat testowania, ponieważ kopia zapasowa nie dzieje się natychmiastowo, więc aby przetestować, musisz wymusić kopię zapasową.

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

Poniższy kod Zwraca numer seryjny urządzenia przy użyciu ukrytego interfejsu API systemu Android. Ale ten kod nie działa na Samsung Galaxy Tab, ponieważ " ro.serialno " nie jest ustawiony na tym urządzeniu.

String serial = null;

try {
    Class<?> c = Class.forName("android.os.SystemProperties");
    Method get = c.getMethod("get", String.class);
    serial = (String) get.invoke(c, "ro.serialno");
}
catch (Exception ignored) {

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

Myślę, że jest to pewny sposób na zbudowanie szkieletu dla unikalnego identyfikatora... Zobacz też

Pseudo-unikalny identyfikator, który działa na wszystkich urządzeniach z Androidem Niektóre urządzenia nie mają telefonu (np. Tabletów) lub z jakiegoś powodu nie chcesz dołączać uprawnień READ_PHONE_STATE. Możesz nadal czytać szczegóły, takie jak wersja ROM, Nazwa Producenta, Typ procesora i inne szczegóły sprzętowe, które będą odpowiednie, jeśli chcesz użyć identyfikatora do sprawdzenia klucza szeregowego lub innych ogólnych celów. ID obliczone w ten sposób nie będzie unikalne: możliwe jest znalezienie dwóch urządzeń o tym samym ID (na podstawie tego samego sprzętu i obrazu ROM), ale zmiany w rzeczywistych aplikacjach są znikome. W tym celu możesz użyć klasy 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

Większość członków budujących to ciągi znaków, co robimy tutaj, to wziąć ich długość i przekształcić ją poprzez modulo w cyfrę. Mamy 13 takich cyfr i dodajemy jeszcze dwie z przodu (35), aby mieć ten sam rozmiar ID co IMEI (15 cyfr). Są tu inne możliwości, wystarczy spojrzeć na te struny. Zwraca coś w rodzaju 355715565309247. Nie jest wymagane specjalne pozwolenie, co czyni to podejście bardzo wygodnym.


(Dodatkowe informacje: technika podana powyżej została skopiowana z artykułu o Pocket Magic.)

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

Używając poniższego kodu, możesz uzyskać unikalny identyfikator urządzenia z systemem Android jako ciąg znaków.

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

Pole Serial zostało dodane do klasy Build na poziomie API 9 (Android 2.3 - Gingerbread). Dokumentacja mówi, że reprezentuje numer seryjny sprzętu. Dlatego powinien być unikalny, jeśli istnieje na urządzeniu.

Nie wiem, czy jest to rzeczywiście Obsługiwane (=nie null) przez wszystkie urządzenia z poziomem API >= 9.

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

Dodam jeszcze jedno-mam jedną z tych wyjątkowych sytuacji.

Użycie:

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

Okazuje się, że nawet jeśli mój Tablet Viewsonic G zgłasza identyfikator urządzenia, który nie jest Null, każdy tablet G zgłasza ten sam numer.

Sprawia, że interesująca jest gra "Pocket Empires", która daje natychmiastowy dostęp do czyjegoś konta na podstawie "unikalnego" DeviceID.

Moje urządzenie nie ma radia komórkowego.
 15
Author: Tony Maro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-21 20:46:43

Szczegółowe instrukcje dotyczące uzyskiwania unikalnego identyfikatora dla każdego urządzenia z systemem Android, z którego zainstalowana jest Twoja aplikacja, znajdziesz w oficjalnym blogu deweloperów AndroidaIdentyfikacja instalacji aplikacji.

Wydaje się, że najlepszym sposobem jest wygenerowanie go po instalacji, a następnie odczytanie go po ponownym uruchomieniu aplikacji.

Osobiście uważam to za dopuszczalne, ale nie idealne. Żaden identyfikator dostarczony przez Androida nie działa we wszystkich przypadkach jak większość są zależne od Stanów radiowych telefonu (Wi-Fi on/off, komórka on/off, Bluetooth on/off). Pozostałe, jak Settings.Secure.ANDROID_ID, muszą być zaimplementowane przez producenta i nie mają gwarancji, że będą unikalne.

Poniżej przedstawiono przykład zapisu danych do pliku instalacyjnego , który byłby przechowywany wraz z innymi danymi zapisywanymi lokalnie przez aplikację.

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

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

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

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

Dodaj poniższy kod w pliku klasy:

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

Dodaj do AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
 10
Author: Android,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-18 04:17:20

Unikalny identyfikator urządzenia z systemem Android jako ciąg znaków, używając TelephonyManager i ANDROID_ID, otrzymuje się przez:

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

Ale zdecydowanie polecam metodę sugerowaną przez Google, zobacz Identyfikacja instalacji aplikacji.

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

Istnieje wiele różnych podejść do obejścia tych ANDROID_ID problemów (może być null Czasami lub urządzenia określonego modelu zawsze zwracają ten sam IDENTYFIKATOR) z plusami i minusami:

  • implementacja niestandardowego algorytmu generowania ID (opartego na właściwościach urządzenia, które mają być statyczne i nie ulegną zmianie - > kto wie)
  • nadużywanie innych identyfikatorów, takich jak IMEI, numer seryjny, Wi-Fi/Bluetooth-adres MAC (nie będą istnieć na wszystkich urządzeniach lub dodatkowe uprawnienia stają się necessary)

Ja sam wolę używać istniejącej implementacji OpenUDID (patrz https://github.com/ylechelle/OpenUDID ) dla Androida (zobacz https://github.com/vieux/OpenUDID ). jest łatwy do integracji i korzysta z ANDROID_ID z alternatywnymi rozwiązaniami dla wyżej wymienionych problemów.

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

Co powiesz na IMEI . To jest unikalne dla Androida lub innych urządzeń mobilnych.

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

Moje dwa grosze-NB To jest dla device (err) unique ID - nie dla instalacji, jak wspomniano w Android developers ' s blog.

Należy zauważyć, że rozwiązanie dostarczone przez @emmby wraca do identyfikatora aplikacji, ponieważ Sharedpreferencje nie są synchronizowane między procesami (Zobacz tutaj i tutaj). Więc uniknąłem tego całkowicie.

Zamiast tego zamknąłem różne strategie uzyskiwania identyfikatora (urządzenia) w zmieniającym się enum kolejność stałych enum wpływa na priorytet różnych sposobów uzyskania ID. Zwracany jest pierwszy inny niż null ID lub wyrzucany jest wyjątek (zgodnie z dobrymi praktykami Javy dotyczącymi Nie nadawania null znaczenia). Więc na przykład mam telefon pierwszy - ale dobrym domyślnym wyborem byłby ANDROID_ID beta:

import android.Manifest.permission;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;

// TODO : hash
public final class DeviceIdentifier {

    private DeviceIdentifier() {}

    /** @see http://code.google.com/p/android/issues/detail?id=10603 */
    private static final String ANDROID_ID_BUG_MSG = "The device suffers from "
        + "the Android ID bug - its ID is the emulator ID : "
        + IDs.BUGGY_ANDROID_ID;
    private static volatile String uuid; // volatile needed - see EJ item 71
    // need lazy initialization to get a context

    /**
     * Returns a unique identifier for this device. The first (in the order the
     * enums constants as defined in the IDs enum) non null identifier is
     * returned or a DeviceIDException is thrown. A DeviceIDException is also
     * thrown if ignoreBuggyAndroidID is false and the device has the Android ID
     * bug
     *
     * @param ctx
     *            an Android constant (to retrieve system services)
     * @param ignoreBuggyAndroidID
     *            if false, on a device with the android ID bug, the buggy
     *            android ID is not returned instead a DeviceIDException is
     *            thrown
     * @return a *device* ID - null is never returned, instead a
     *         DeviceIDException is thrown
     * @throws DeviceIDException
     *             if none of the enum methods manages to return a device ID
     */
    public static String getDeviceIdentifier(Context ctx,
            boolean ignoreBuggyAndroidID) throws DeviceIDException {
        String result = uuid;
        if (result == null) {
            synchronized (DeviceIdentifier.class) {
                result = uuid;
                if (result == null) {
                    for (IDs id : IDs.values()) {
                        try {
                            result = uuid = id.getId(ctx);
                        } catch (DeviceIDNotUniqueException e) {
                            if (!ignoreBuggyAndroidID)
                                throw new DeviceIDException(e);
                        }
                        if (result != null) return result;
                    }
                    throw new DeviceIDException();
                }
            }
        }
        return result;
    }

    private static enum IDs {
        TELEPHONY_ID {

            @Override
            String getId(Context ctx) {
                // TODO : add a SIM based mechanism ? tm.getSimSerialNumber();
                final TelephonyManager tm = (TelephonyManager) ctx
                        .getSystemService(Context.TELEPHONY_SERVICE);
                if (tm == null) {
                    w("Telephony Manager not available");
                    return null;
                }
                assertPermission(ctx, permission.READ_PHONE_STATE);
                return tm.getDeviceId();
            }
        },
        ANDROID_ID {

            @Override
            String getId(Context ctx) throws DeviceIDException {
                // no permission needed !
                final String andoidId = Secure.getString(
                    ctx.getContentResolver(),
                    android.provider.Settings.Secure.ANDROID_ID);
                if (BUGGY_ANDROID_ID.equals(andoidId)) {
                    e(ANDROID_ID_BUG_MSG);
                    throw new DeviceIDNotUniqueException();
                }
                return andoidId;
            }
        },
        WIFI_MAC {

            @Override
            String getId(Context ctx) {
                WifiManager wm = (WifiManager) ctx
                        .getSystemService(Context.WIFI_SERVICE);
                if (wm == null) {
                    w("Wifi Manager not available");
                    return null;
                }
                assertPermission(ctx, permission.ACCESS_WIFI_STATE); // I guess
                // getMacAddress() has no java doc !!!
                return wm.getConnectionInfo().getMacAddress();
            }
        },
        BLUETOOTH_MAC {

            @Override
            String getId(Context ctx) {
                BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
                if (ba == null) {
                    w("Bluetooth Adapter not available");
                    return null;
                }
                assertPermission(ctx, permission.BLUETOOTH);
                return ba.getAddress();
            }
        }
        // TODO PSEUDO_ID
        // http://www.pocketmagic.net/2011/02/android-unique-device-id/
        ;

        static final String BUGGY_ANDROID_ID = "9774d56d682e549c";
        private final static String TAG = IDs.class.getSimpleName();

        abstract String getId(Context ctx) throws DeviceIDException;

        private static void w(String msg) {
            Log.w(TAG, msg);
        }

        private static void e(String msg) {
            Log.e(TAG, msg);
        }
    }

    private static void assertPermission(Context ctx, String perm) {
        final int checkPermission = ctx.getPackageManager().checkPermission(
            perm, ctx.getPackageName());
        if (checkPermission != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Permission " + perm + " is required");
        }
    }

    // =========================================================================
    // Exceptions
    // =========================================================================
    public static class DeviceIDException extends Exception {

        private static final long serialVersionUID = -8083699995384519417L;
        private static final String NO_ANDROID_ID = "Could not retrieve a "
            + "device ID";

        public DeviceIDException(Throwable throwable) {
            super(NO_ANDROID_ID, throwable);
        }

        public DeviceIDException(String detailMessage) {
            super(detailMessage);
        }

        public DeviceIDException() {
            super(NO_ANDROID_ID);
        }
    }

    public static final class DeviceIDNotUniqueException extends
            DeviceIDException {

        private static final long serialVersionUID = -8940090896069484955L;

        public DeviceIDNotUniqueException() {
            super(ANDROID_ID_BUG_MSG);
        }
    }
}
 7
Author: Mr_and_Mrs_D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:36

Oto jak generuję unikalny identyfikator:

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

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

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

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

Innym sposobem jest użycie /sys/class/android_usb/android0/iSerial w aplikacji bez żadnych uprawnień.

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

Aby to zrobić w Javie wystarczy użyć FileInputStream, aby otworzyć plik iSerial i odczytać znaki. Upewnij się tylko, że zawijasz go w obsługę wyjątków, ponieważ nie wszystkie urządzenia mają ten plik.

Przynajmniej następujące urządzenia są znane z tego pliku do odczytu na świecie:

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

Możesz również zobaczyć mój wpis na bloguwyciekł numer seryjny sprzętu z Androidem do nieuprzywilejowanych aplikacji gdzie omówię, jakie inne pliki są dostępne dla informacji.

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

Aby rozpoznać sprzętowo konkretne urządzenie z Androidem, możesz sprawdzić adresy MAC.

Możesz to zrobić w ten sposób:

W AndroidManifest.xml

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

Teraz w kodzie:

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

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

W każdym urządzeniu z Androidem ich jest co najmniej interfejs "wlan0", czyli chip WI-FI. Ten kod działa nawet wtedy, gdy WI-FI nie jest włączone.

P. S. Są to kilka innych interfejsów, które otrzymasz z listy zawierającej komputery MAC, ale może to zmienić się między telefony.

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

Używam poniższego kodu, aby uzyskać IMEI lub użyć Secure.ANDROID_ID jako alternatywa, gdy urządzenie nie ma możliwości telefonu:

String identifier = null;
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE));
if (tm != null)
      identifier = tm.getDeviceId();
if (identifier == null || identifier .length() == 0)
      identifier = Secure.getString(activity.getContentResolver(),Secure.ANDROID_ID);
 6
Author: Asaf Pinhassi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-20 03:21:09

A dokładniej Settings.Secure.ANDROID_ID. Jest to 64-bitowa ilość, która jest generowana i przechowywana podczas pierwszego uruchomienia urządzenia. Jest resetowany po wyczyszczeniu urządzenia.

ANDROID_ID wydaje się dobrym wyborem dla unikalnego identyfikatora urządzenia. Są minusy: po pierwsze, nie jest w 100% niezawodny w wydaniach Androida przed 2.2 (“Froyo”). ponadto wystąpił co najmniej jeden powszechnie zaobserwowany błąd w popularnej słuchawce od głównego producenta, gdzie każda instancja ma ten sam ANDROID_ID.

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

Google Instance ID

[1]}wydany na I / O 2015; na Androida wymaga usług play 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

Wygląda na to, że Google zamierza użyć tego identyfikatora do identyfikacji instalacji na Androidzie, Chrome i iOS.

Identyfikuje instalację, a nie urządzenie, ale ponownie ANDROID_ID (który jest akceptowana odpowiedź) teraz również nie identyfikuje urządzeń. W trybie runtime ARC generowany jest nowy identyfikator ANDROID_ID dla każdej instalacji (szczegóły tutaj ), podobnie jak ten nowy identyfikator instancji. Myślę też, że identyfikacja instalacji (a nie urządzeń) jest tym, czego większość z nas właściwie szuka.

Zalety ID instancji

Wydaje mi się, że Google zamierza wykorzystać go do tego celu( identyfikując Twoje instalacje), jest wieloplatformowy i może być wykorzystywane do wielu innych celów (patrz linki powyżej).

Jeśli używasz GCM, to w końcu będziesz musiał użyć tego identyfikatora instancji, ponieważ potrzebujesz go, aby uzyskać token GCM (który zastępuje stary identyfikator rejestracji GCM).

Wady / problemy

W bieżącej implementacji (GPS 7.5) identyfikator instancji jest pobierany z serwera, gdy aplikacja go zażąda. Oznacza to, że powyższe wywołanie jest wywołaniem blokującym - w moich nienaukowych testach trwa 1-3 sekund, jeśli urządzenie jest online, i 0.5-1.0 sekund, jeśli off-line (Prawdopodobnie tak długo czeka, zanim zrezygnuje i wygeneruje losowe ID). Został on przetestowany w Ameryce Północnej na Nexusie 5 z Androidem 5.1.1 i GPS 7.5.

Jeśli używasz identyfikatora do celów, które zamierzają - np. uwierzytelnianie aplikacji, identyfikacja aplikacji, GCM-myślę, że to 1-3 sekundy może być uciążliwe(w zależności od aplikacji, oczywiście).

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

Android device mac id również unikalny identyfikator, nie zmieni się Załóżmy, że sformatujemy samo urządzenie, używając poniższego kodu, aby uzyskać mac id

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

Nie zapomnij również dodać odpowiednich uprawnień do swojego AndroidManifest.xml

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

Jest tu ponad 30 odpowiedzi, niektóre są takie same, a niektóre wyjątkowe. Odpowiedź ta opiera się na kilku z tych odpowiedzi. Jednym z nich jest odpowiedź @ Lenn Dolling.

Łączy 3 identyfikatory i tworzy 32-cyfrowy ciąg sześciokątny. To działa bardzo dobrze dla mnie.

3 identyfikatory to:
Pseudo-ID - generowany jest na podstawie specyfikacji urządzeń fizycznych
ANDROID_ID - Settings.Secure.ANDROID_ID
adres Bluetooth - adres adaptera Bluetooth

Zwróci coś w ten sposób: 551f27c060712a72730b0a0f734064b1

Uwaga: zawsze możesz dodać więcej identyfikatorów do ciągu longId. Na przykład numer seryjny. adres adaptera wifi. IMEI. W ten sposób uczynisz go bardziej unikalnym na urządzenie.

@SuppressWarnings("deprecation")
@SuppressLint("HardwareIds")
public static String generateDeviceIdentifier(Context context) {

        String pseudoId = "35" +
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.CPU_ABI.length() % 10 +
                Build.DEVICE.length() % 10 +
                Build.DISPLAY.length() % 10 +
                Build.HOST.length() % 10 +
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +
                Build.MODEL.length() % 10 +
                Build.PRODUCT.length() % 10 +
                Build.TAGS.length() % 10 +
                Build.TYPE.length() % 10 +
                Build.USER.length() % 10;

        String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        String btId = "";

        if (bluetoothAdapter != null) {
            btId = bluetoothAdapter.getAddress();
        }

        String longId = pseudoId + androidId + btId;

        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(longId.getBytes(), 0, longId.length());

            // get md5 bytes
            byte md5Bytes[] = messageDigest.digest();

            // creating a hex string
            String identifier = "";

            for (byte md5Byte : md5Bytes) {
                int b = (0xFF & md5Byte);

                // if it is a single digit, make sure it have 0 in front (proper padding)
                if (b <= 0xF) {
                    identifier += "0";
                }

                // add number to string
                identifier += Integer.toHexString(b);
            }

            // hex string to uppercase
            identifier = identifier.toUpperCase();
            return identifier;
        } catch (Exception e) {
            Log.e("TAG", e.toString());
        }
        return "";
}
 5
Author: ᴛʜᴇᴘᴀᴛᴇʟ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 14:01:34

Google ma teraz ID reklamy .
Można to również wykorzystać, ale należy pamiętać, że:

Identyfikator reklamowy to unikalny identyfikator, który można zresetować]}

I

Umożliwia użytkownikom Resetowanie identyfikatora lub rezygnację z reklam opartych na zainteresowaniach w aplikacjach Google Play.

Więc chociaż ten identyfikator może się zmienić, wydaje się, że wkrótce możemy nie mieć wyboru , zależy od celu tego identyfikatora.

Więcej informacji @ develper.android

Kopiuj-Wklej tutaj kod

HTH

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

Telefon.getDeviceId () zwraca unikalny identyfikator urządzenia, na przykład IMEI dla GSM i MEID lub ESN dla telefonów CDMA.

final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);            
String myAndroidDeviceId = mTelephony.getDeviceId(); 

Ale polecam używać:

Ustawienia.Zabezpieczony.ANDROID_ID , który zwraca identyfikator Androida jako unikalny 64-bitowy ciąg szesnastkowy.

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

Sometimes TelephonyManger.getDeviceId () zwróci null, więc aby zapewnić unikalny identyfikator, użyjesz tej metody:

public String getUniqueID(){    
    String myAndroidDeviceId = "";
    TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    if (mTelephony.getDeviceId() != null){
        myAndroidDeviceId = mTelephony.getDeviceId(); 
    }else{
         myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 
    }
    return myAndroidDeviceId;
}
 4
Author: Jorgesys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-06 15:00:25