Benzersiz bir Android cihaz kimliği var mı?


Yanıtlar:


2024

Settings.Secure#ANDROID_IDAndroid kimliğini her kullanıcı 64 bit onaltılık dize için benzersiz olarak döndürür .

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID); 

476
Bazen boş olduğu bilinmektedir, "fabrika ayarlarına sıfırlamadan sonra değişebilir" olarak belgelenmiştir. Kendi sorumluluğunuzdadır kullanın ve köklü bir telefonda kolayca değiştirilebilir.
Seva Alekseyev


18
Uygulama ilk çalıştırıldığında ayarlanamayabileceği, daha sonra ayarlanabileceği veya teoride değişebileceği için ANDROID_ID'yi ilk yanıtta kullanma konusunda dikkatli olmamız gerektiğini düşünüyorum, dolayısıyla benzersiz kimlik değişebilir

46
Bu çözümle ilgili büyük sınırlamalar olduğunu unutmayın: android-developers.blogspot.com/2011/03/…
emmby

35
ANDROID_ID artık bir cihazı benzersiz bir şekilde tanımlamıyor (4.2 itibariyle): stackoverflow.com/a/13465373/150016
Tom

1145

GÜNCELLEME : Android'in son sürümlerinden itibaren, sorunların ANDROID_IDçoğu çözüldü ve bu yaklaşımın artık gerekli olmadığına inanıyorum. Lütfen Anthony'nin cevabına bir göz atın .

Tam açıklama: Uygulamam başlangıçta aşağıdaki yaklaşımı kullandı ancak artık bu yaklaşımı kullanmıyor ve şimdi Android Geliştirici Blog girişinde emmby'nin yanıt bağlantılarına (yani, oluşturma ve kaydetme UUID#randomUUID()) bağlanan yaklaşımı kullanıyoruz .


Bu sorunun birçok yanıtı var, çoğu zaman sadece "biraz" işe yarayacak ve maalesef bu yeterince iyi değil.

Cihaz testlerime dayanarak (en az biri etkinleştirilmemiş tüm telefonlar):

  1. Test edilen tüm cihazlar için bir değer döndürdü TelephonyManager.getDeviceId()
  2. Tüm GSM cihazları (tümü bir SIM ile test edilmiştir), TelephonyManager.getSimSerialNumber()
  3. Tüm CDMA aygıtları boş bırakıldı getSimSerialNumber()(beklendiği gibi)
  4. Google hesabı eklenmiş tüm cihazlar için bir değer döndürdü ANDROID_ID
  5. Tüm CDMA aygıtları, her ikisi için de aynı değeri (veya aynı değerin türetilmesini) döndürdü ANDROID_IDve TelephonyManager.getDeviceId()- kurulum sırasında bir Google hesabı eklendiği sürece .
  6. Henüz SIM özelliği olmayan GSM cihazlarını, Google hesabı eklenmemiş bir GSM cihazını veya uçak modundaki cihazlardan herhangi birini test etme şansım olmadı.

Bu yüzden cihazın kendisine özgü bir şey istiyorsanız, yeterli TM.getDeviceId() olmalıdır . Açıkçası bazı kullanıcılar diğerlerinden daha paranoyaktır, bu nedenle bu tanımlayıcılardan 1 veya daha fazlasını hash etmek yararlı olabilir, böylece dize hala cihaza neredeyse benzersizdir, ancak kullanıcının gerçek cihazını açıkça tanımlamaz. Örneğin, String.hashCode()UUID ile birlikte kullanarak :

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

şöyle bir şeyle sonuçlanabilir: 00000000-54b3-e7c7-0000-000046bffd97

Benim için yeterince iyi çalışıyor.

Richard'ın aşağıda belirttiği gibi, TelephonyManagerözellikleri okumak için izne ihtiyacınız olduğunu unutmayın , bu yüzden bunu bildiriminize ekleyin:

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

ithalat kütüphaneleri

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

151
Telefon tabanlı kimlik tablet cihazlarda olmayacak, değil mi?
Seva Alekseyev

22
Bu yüzden neden çoğu zaman işe yaramayacağını söyledim :) Bu soruya tüm cihazlar, tüm cihaz türleri ve tüm donanım yapılandırmaları için güvenilir herhangi bir cevap görmedim. Bu yüzden bu soru başlamak için burada. Bunun hepsinin sonu olmayan bir çözümün olmadığı açıktır. Bireysel cihaz üreticilerinin cihaz seri numaraları olabilir, ancak bunlar bizim için kullanılmaya açık değildir ve bu bir gereklilik değildir. Böylece elimizde mevcut olanla kalıyoruz.
Joe

31
Kod örneği harika çalışıyor. <uses-permission android:name="android.permission.READ_PHONE_STATE" />Manifest dosyasına eklemeyi unutmayın . Bir veritabanında depolanıyorsa, döndürülen dize 36 karakter uzunluğundadır.
Richard

10
Bu çözümle ilgili büyük sınırlamalar olduğunu unutmayın: android-developers.blogspot.com/2011/03/…
emmby

18
@softarn: Bahsettiğiniz şeyin emmby'nin zaten bağlı olduğu ve ne söylemeye çalıştığınızı açıklayan Android Geliştirici Blogu olduğuna inanıyorum , bu yüzden belki de yorumunu basitçe iptal etmelisiniz. Her iki durumda da, emmby'nin cevabından bahsettiği gibi, blog bilgisinde bile sorunlar var. Soru benzersiz bir DEVICE tanımlayıcısı (kurulum tanımlayıcısı değil) ister, bu yüzden ifadenize katılmıyorum. Blog, istediğiniz şeyin cihazı takip etmek zorunda olmadığı varsayımına varırken, soru sadece bunu soruyor. Aksi takdirde bloga katılıyorum.
Joe

438

Son Güncelleme: 6/2/15


Benzersiz bir kimlik oluşturma, Google geliştirici blogu ve Android dokümantasyonuyla ilgili her Stack Overflow yayınını okuduktan sonra, 'Sahte Kimlik' mümkün olan en iyi seçenek gibi hissediyorum.

Ana Sayı: Donanım ve Yazılım

Donanım

  • Kullanıcılar donanımlarını, Android tabletlerini veya telefonlarını değiştirebildiğinden, donanıma dayalı benzersiz kimlikler TAKİP KULLANICILARI için iyi fikirler değildir
  • İçin İZLEME DONANIM , bu harika bir fikir

Yazılım

  • Kullanıcılar köklüyse ROM'larını silebilir / değiştirebilir
  • Platformlardaki kullanıcıları (iOS, Android, Windows ve Web) izleyebilirsiniz
  • En iyi Talep PARÇA bireysel bir kullanıcı kendi ile rızası basitçe (OAuth kullanarak bu Kesintisiz olun) onları giriş sahip olmaktır

Android ile genel arıza

- API> = 9/10 (Android cihazların% 99,5'i) için benzersizliği (köklü cihazları dahil edin) garanti edin

- Ekstra izin yok

Psuedo kodu:

if API >= 9/10: (99.5% of devices)

return unique ID containing serial id (rooted devices may be different)

else

return the unique ID of build information (may overlap data - API < 9)

Tüm seçeneklerimizi ( @ Stack Overflow sorusunda) yayınladığı için @stansult'a teşekkürler .

Seçeneklerin listesi - neden kullanılmadığı / neden kullanılmadığı:

  • Kullanıcı E-postası - Yazılım

    • Kullanıcı e-postayı değiştirebilir - ÇOK olası değil
    • API 5+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />veya
    • API 14+ <uses-permission android:name="android.permission.READ_PROFILE" /> <uses-permission android:name="android.permission.READ_CONTACTS" />( Android cihazın birincil e-posta adresi nasıl alınır )
  • Kullanıcı Telefon Numarası - Yazılım

    • Kullanıcılar telefon numaralarını değiştirebilir - ÇOK olası değil
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • IMEI - Donanım (yalnızca telefonlar, ihtiyaçlar android.permission.READ_PHONE_STATE)

    • Çoğu kullanıcı izninde "Telefon Görüşmeleri" yazmasından nefret eder. Bazı kullanıcılar kötü puanlar verir, çünkü gerçekten yapmak istediğiniz tek şey cihaz yüklemelerini izlemek olduğunda kişisel bilgilerini çaldığınıza inanırlar. Veri topladığınız açıktır.
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • Android ID - Donanım (boş olabilir, fabrika ayarlarına sıfırlandığında değiştirilebilir, köklü bir cihazda değiştirilebilir)

    • 'Null' olabileceğinden, 'null' değerini kontrol edebilir ve değerini değiştirebiliriz, ancak bu artık benzersiz olmayacağı anlamına gelir.
    • Fabrika ayarlarına sıfırlama cihazına sahip bir kullanıcınız varsa, değer köklü cihazda değişmiş veya değiştirilmiş olabilir.
  • WLAN MAC Adresi - Donanım (ihtiyaçlar android.permission.ACCESS_WIFI_STATE)

    • Bu en iyi ikinci seçenek olabilir, ancak yine de doğrudan bir kullanıcıdan gelen benzersiz bir tanımlayıcı topluyor ve saklıyorsunuz. Bu veri topladığınız açıktır.
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
  • Bluetooth MAC Adresi - Donanım (Bluetooth özellikli cihazlar, ihtiyaçlar android.permission.BLUETOOTH)

    • Piyasadaki çoğu uygulama Bluetooth kullanmaz ve bu nedenle uygulamanız Bluetooth kullanmıyorsa ve siz de dahil ediyorsanız, kullanıcı şüphelenebilir.
    • <uses-permission android:name="android.permission.BLUETOOTH "/>
  • Sahte Benzersiz Kimlik - Yazılım (tüm Android cihazlar için)

    • Çok olası, çarpışmalar içerebilir - Aşağıdaki yöntemime bakın!
    • Bu, özel bir şey almadan kullanıcıdan 'neredeyse benzersiz' bir kimliğiniz olmasını sağlar. Cihaz bilgilerinden kendi anonim kimliğinizi oluşturabilirsiniz.

İzinleri kullanmadan benzersiz bir kimlik elde etmenin 'mükemmel' bir yolu olmadığını biliyorum; ancak bazen cihaz kurulumunu gerçekten izlememiz gerekir. Benzersiz bir kimlik oluşturma söz konusu olduğunda, yalnızca Android API'nın bize ek izinler kullanmadan verdiği bilgilere dayanarak 'sahte benzersiz kimlik' oluşturabiliriz. Bu şekilde, kullanıcıya saygı gösterebilir ve iyi bir kullanıcı deneyimi sunmaya çalışabiliriz.

Sahte benzersiz bir kimlikle, gerçekten sadece benzer cihazların olduğu gerçeğine dayanarak kopyaların olabileceği gerçeğiyle karşılaşırsınız. Birleştirilen yöntemi daha benzersiz hale getirmek için düzenleyebilirsiniz; ancak, bazı geliştiricilerin cihaz yüklemelerini izlemesi gerekir ve bu da benzer cihazlara dayalı olarak hile veya performans sağlayacaktır.

API> = 9:

Android cihazları API 9 veya üstü ise, 'Build.SERIAL' alanı nedeniyle benzersiz olduğu garanti edilir.

UNUTMAYIN , teknik olarak API <9 olan kullanıcıların yaklaşık% 0,5'ini kaçırıyorsunuz . Böylece geri kalanlara odaklanabilirsiniz: Bu kullanıcıların% 99,5'i!

API <9:

Kullanıcının Android cihazı API 9'dan düşükse; umarım fabrika ayarlarına sıfırlamamışlardır ve 'Secure.ANDROID_ID' değerleri korunmuş ya da 'null' olmayacaktır. (bkz. http://developer.android.com/about/dashboards/index.html )

Eğer hepsi hataysa:

Her şey başarısız olursa, kullanıcı API 9'dan daha düşükse (Gingerbread'den daha düşük) cihazını sıfırladıysa veya 'Secure.ANDROID_ID' null değerini döndürdüyse, döndürülen kimlik yalnızca Android cihaz bilgilerini temel alır. Çarpışmalar burada gerçekleşebilir.

değişiklikler:

  • Fabrika sıfırlamaları nedeniyle 'Android.SECURE_ID' kaldırıldı, değerin değişmesine neden olabilir
  • API'da değiştirmek için kodu düzenledi
  • Yalancı Değişti

Lütfen aşağıdaki yönteme bir göz atın:

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

Yeni (reklamlı uygulamalar ve Google Play Hizmetleri için):

Google Play Geliştirici konsolundan:

1 Ağustos 2014'ten itibaren Google Play Geliştirici Program Politikası, tüm yeni uygulama yüklemelerinin ve güncellemelerinin, reklamcılık amaçlı herhangi bir kalıcı tanımlayıcı yerine reklam kimliğini kullanmasını gerektirir. Daha fazla bilgi edin

Uygulama :

İzin:

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

Kaynak / Dokümanlar:

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

Önemli:

Google Play Hizmetleri kullanılabilir olduğunda, reklam kimliğinin reklam amaçlı diğer tanımlayıcıların mevcut kullanımının (Ayarlar.Secure'da ANDROID_ID kullanımı gibi) tamamen yerini alması amaçlanmıştır. Google Play Hizmetlerinin kullanılamadığı durumlar, getAdvertisingIdInfo () tarafından atılan bir GooglePlayServicesNotAvailableException tarafından belirtilir.

Uyarı, kullanıcılar sıfırlayabilir:

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

Bilgi aldığım her bağlantıya başvurmaya çalıştım. Eksik ve dahil edilmesi gerekiyorsa, lütfen yorum yapın!

Google Player Hizmetleri Örnek Kimliği

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


Ancak BuildOS güncellemesinden sonra sınıf değişmez mi? Özellikle API güncellenmişse? Öyleyse, bunun benzersiz olduğunu nasıl garanti edersiniz? (
Yazdığınız

2
yorum göndermek için yöntemimi uygulamamda kullandım. Kötü haberlerim var. ne yazık ki PsuedoID tamamen benzersiz değil. sunucum 5 ID için 100'den fazla ve neredeyse 30 ID için 30'dan fazla kaydetti. en çok tekrarlanan kimlikler 'ffffffff-fc8f-6093-ffff-ffffd8' (159 kayıt) ve 'ffffffff-fe99-b334-ffff-ffffef' (154 kez) 'dir. Ayrıca zaman ve yorumlara dayanarak farklı insanların olduğu açıktır. şimdiye kadar toplam kayıt 10.000'dir. lütfen bunun neden olduğunu bana bildirin. tankları.
hojjat reyhane

1
Bunu 1.5+ yıl önce yazdım. Neden senin için benzersiz olmadığından emin değilim. Reklam kimliğini deneyebilirsiniz. Değilse, kendi çözümünüzü bulabilirsin.
Jared Burrows

2
Sorta..Soruyu gözden geçirir ve bu konuda düşüncelerinizi verirseniz gerçekten minnettar olurum
Durai Amuthan.H

1
@ user1587329 Teşekkürler. Bunu herkes için güncel tutmaya çalışıyorum. Bu soru, donanım ve yazılım ve çapraz platform söz konusu olduğunda zor.
Jared Burrows

340

Dave Webb'in belirttiği gibi, Android Geliştirici Blogunda bunu kapsayan bir makale var. Tercih ettikleri çözüm, cihazlardan ziyade uygulama yüklemelerini takip etmektir ve bu, çoğu kullanım durumunda iyi çalışır. Blog gönderisi, bu işi yapmak için gerekli kodu gösterecektir ve kontrol etmenizi öneririz.

Ancak, bir uygulama yükleme tanımlayıcısı yerine bir cihaz tanımlayıcısına ihtiyacınız varsa blog yayını çözümleri tartışmaya devam eder. Google'da birisiyle konuşmanız gerektiğinde birkaç öğeye ilişkin ek açıklama almak için konuştum. Yukarıda belirtilen blog yayınında bahsedilmeyen cihaz tanımlayıcıları hakkında keşfettiklerim:

  • ANDROID_ID, tercih edilen cihaz tanımlayıcısıdır. ANDROID_ID, Android <= 2.1 veya> = 2.3 sürümlerinde mükemmel derecede güvenilirdir. Görevde belirtilen sorunlar sadece 2.2.
  • Birkaç üreticinin birçok cihazı 2.2'deki ANDROID_ID hatasından etkilenir.
  • Bildiğim kadarıyla belirlemek mümkün oldum olarak, etkilenen tüm cihazlar var aynı ANDROID_ID olan 9774d56d682e549c değerine sahiptir . Aynı zamanda emülatör tarafından bildirilen aynı cihaz kimliği, btw.
  • Google, OEM'lerin sorunu cihazlarının çoğu veya çoğu için yamalarıyla ilgili olduğuna inanıyor, ancak en azından Nisan 2011'in başından itibaren, ANDROID_ID bozuk olan cihazları bulmanın hala oldukça kolay olduğunu doğrulayabildim.

Google'ın önerilerine dayanarak, her cihaz için benzersiz bir UUID oluşturacak, uygun olduğunda tohum olarak ANDROID_ID kullanan, gerektiğinde TelephonyManager.getDeviceId () yöntemine geri dönen bir sınıf uyguladım ve bu başarısız olursa rastgele oluşturulan benzersiz bir UUID'ye başvurma uygulama yeniden başlatmalarda kalıcıdır (ancak uygulama yeniden yüklemelerinde bulunmaz).

Cihaz numarası son çare olarak gereken cihazlar için, benzersiz kimlik o Not OLACAK fabrika sıfırlama arasında varlığını. Bu bilinmesi gereken bir şey. Fabrika ayarlarına sıfırlamanın benzersiz kimliğinizi sıfırlayacağından emin olmanız gerekiyorsa, cihaz kimliği yerine doğrudan rastgele UUID'ye geri dönmeyi düşünebilirsiniz.

Yine, bu kod bir uygulama yükleme kimliği için değil, bir cihaz kimliği içindir. Çoğu durumda, bir uygulama yükleme kimliği muhtemelen aradığınız şeydir. Ancak bir cihaz kimliğine ihtiyacınız varsa, aşağıdaki kod muhtemelen sizin için çalışacaktır.

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

6
Hepsi aynı boyutta olmaları için çeşitli kimliklere sahip olmamalısınız? Ayrıca, yanlışlıkla özel bilgileri ifşa etmemek için cihaz kimliğini de kullanmanız gerekir.
Steve Pomeroy

2
İyi puanlar, Steve. Her zaman bir UUID döndürmek için kodu güncelledim. Bu, a) oluşturulan kimliklerin her zaman aynı boyutta olmasını ve b) android ve cihaz kimliklerinin, yanlışlıkla kişisel bilgileri ifşa etmekten kaçınmak için iade edilmeden önce hash edilmesini sağlar. Cihaz kimliğinin fabrika ayarlarına sıfırlanacağını ve bunun bazı kullanıcılar için istenmeyebileceğini belirtmek için açıklamayı güncelledim.
emmby

1
Yanlış olduğuna inanıyorum; tercih edilen çözüm, cihaz tanımlayıcılarını değil kurulumları takip etmektir. Kodunuz blog yazısındakinden çok daha uzun ve karmaşıktır ve bana herhangi bir değer kattığı açık değildir.
Tim Bray

7
İyi bir nokta, yorumları, kullanıcıların cihaz kimlikleri yerine uygulama yükleme kimlikleri kullanmasını şiddetle önerecek şekilde güncelledim. Ancak, bu çözümün kurulum kimliği yerine bir cihaza ihtiyacı olan insanlar için hala değerli olduğunu düşünüyorum.
emmby

8
ANDROID_ID fabrika ayarlarına sıfırlandığında değişebilir, bu yüzden cihazları da tanımlayamaz
Samuel

180

Reto Meier'in bu yıl Google I / O sunumunda kullanıcı için benzersiz bir kimlik almak amacıyla kullandığı kod :

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

Bunu buluta tercihler göndermek için bir yedekleme stratejisiyle birleştirirseniz (Reto'nun konuşmasında da açıklanırsa, bir kullanıcıyla bağlanan ve cihaz silindikten veya hatta değiştirildikten sonra etrafta yapışan bir kimliğiniz olmalıdır. analitikte ilerliyoruz (başka bir deyişle, henüz bu işi yapmadım :).


@Lenn Dolling'in yöntemini şimdiki zaman için benzersiz bir kimliğe eklenmiş olarak kullanıyordum. Ama bu daha basit ve güvenilir bir yol gibi görünüyor. Reto Meier ve Antony Nolan'a teşekkürler
Gökhan Barış Aker

Harika ama rootlu cihazlar ne olacak? Buna erişebilir ve uid'i kolayca başka bir tanesiyle değiştirebilirler.
tasomaniac

3
Bir kaldırma ve yeniden yükleme işleminden sonra da devam etmek için benzersiz kimliğe ihtiyacınız yoksa harika bir seçenektir (örneğin, üç kazanma şansı elde ettiğiniz tanıtım etkinliği / oyun, süre).
Kyle Clegg

2
Meier sunusu, kullanıcının bu özelliği açmayı seçmesine bağlı olan Android Yedekleme Yöneticisi'ni kullanmaya dayanır. Uygulama kullanıcı tercihleri ​​(Meier'in kullanımı) için bu iyidir, çünkü kullanıcı bu seçeneği seçmediyse, bunları yedeklemez. Bununla birlikte, asıl soru cihaz için benzersiz bir kimlik oluşturmakla ilgilidir ve bu kimlik, cihaz başına, uygulama başına değil, kurulum başına değil, her cihaz için ayrı ayrı üretildiğinden ve kullanıcının yedekleme seçeneğini seçmesine bağlı olduğundan, kullanımının ötesinde kullanımı tercihler (örneğin, sınırlı bir deneme için) sınırlıdır.
Carl

12
Bu, verilerin kaldırılması veya silinmesinde işe yaramaz.
John Shelley

106

Ayrıca Wi-Fi adaptörünün MAC adresini de düşünebilirsiniz. Bu şekilde alındı:

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

android.permission.ACCESS_WIFI_STATEManifest'te izin gerekiyor .

Wi-Fi bağlı olmasa bile kullanılabileceği bildirildi. Yukarıdaki yanıttan Joe bunu birçok cihazında denerse, bu iyi olurdu.

Bazı cihazlarda Kablosuz kapalı olduğunda kullanılamaz.

NOT: Android 6.x sürümünden tutarlı sahte mac adresi döndürür:02:00:00:00:00:00


8
Bu gerekliandroid.permission.ACCESS_WIFI_STATE
ohhorob

5
Bence hemen hemen tüm android cihazlarda WiFi kapalı olduğunda kullanılamaz olduğunu göreceksiniz. Kablosuz bağlantıyı kapatmak aygıtı çekirdek düzeyinde kaldırır.
chrisdowney

12
@ Sanandrea - bakalım, köklü bir cihazda HER ŞEY sahte olabilir.
ocodo

5
WiFi MAC adresine erişim Android M'de engellendi: stackoverflow.com/questions/31329733/…
breez

6
Android 6.x tutarlı sahte mac adresi döndürür:02:00:00:00:00:00
Behrouz.M

87

Burada oldukça yararlı bilgiler var .

Beş farklı kimlik türünü kapsar:

  1. IMEI (yalnızca Telefon kullanan Android cihazlar için; ihtiyaçlar android.permission.READ_PHONE_STATE)
  2. Sahte Benzersiz Kimlik (tüm Android cihazlar için)
  3. Android ID (boş olabilir, fabrika ayarlarına sıfırlandığında değiştirilebilir, köklü telefonda değiştirilebilir)
  4. WLAN MAC Adres dizesi (ihtiyaçlar android.permission.ACCESS_WIFI_STATE)
  5. BT MAC Adres dizesi (Bluetooth özellikli cihazlar, gereksinimlerandroid.permission.BLUETOOTH )

2
Önemli nokta (burada ve makalede): açılmadıkça WLAN veya BT MAC alamazsınız! Aksi takdirde WLAN MAC'in mükemmel tanımlayıcı olacağını düşünüyorum. Kullanıcının hiç Wi-Fi özelliğini açacağına dair bir garantiniz yok ve bunu kendiniz açmanın 'uygun' olduğunu düşünmüyorum.
Tom

1
@Tom yanılıyorsun. Kapalı olsalar bile WLAN veya BT MAC'i okuyabilirsiniz. Bununla birlikte, cihazın WLAN veya BT modüllerinin mevcut olduğuna dair bir garanti yoktur.
Marqs

2
En önemlisi, Yerel WiFi ve Bluetooth MAC adresleri artık kullanılamamaktadır.
sarika kate

4
@sarikakate Sadece 6.0 Marshmallow ve üstü için geçerli ... Hala 6.0 Marshmallow'un altında beklendiği gibi çalışıyor.
Smeet

@Smeet Evet haklısın. 6.0'ın altında çalıştığından bahsetmeyi unuttum
sarika kate

51

Resmi Android Geliştiricileri Blogunda artık bu konuyla ilgili tam bir makale var: Uygulama Yüklemelerini Tanımlama .


4
Ve bu argümanın temel noktası, donanımdan benzersiz bir kimlik almaya çalışıyorsanız, muhtemelen bir hata yapıyorsunuzdur.
Tim Bray

3
Cihaz kilidinizin fabrika ayarlarına sıfırlanmasıyla sıfırlanmasına izin veriyorsanız, deneme sürümü modeliniz ölü kadar iyidir.
Seva Alekseyev

43

At Google I / O Reto Meier kurulumları arasında kullanıcıları izlemek için çoğu geliştirici ihtiyaçlarını karşılamak gereken bu yaklaşım nasıl sağlam bir cevap yayınladı. Anthony Nolan cevabının yönünü gösteriyor, ancak diğerlerinin nasıl yapılacağını kolayca görebilmesi için tam yaklaşımı yazacağımı düşündüm (ayrıntıları anlamak biraz zaman aldı).

Bu yaklaşım, size farklı cihazlarda (birincil Google hesabına dayalı olarak) ve yüklemelerde kullanıcı için kalıcı olacak anonim ve güvenli bir kullanıcı kimliği verecektir. Temel yaklaşım rastgele bir kullanıcı kimliği oluşturmak ve bunu uygulamaların paylaşılan tercihlerinde saklamaktır. Ardından Google hesabına bağlı paylaşılan tercihleri ​​bulutta depolamak için Google'ın yedekleme aracısını kullanırsınız.

Tam yaklaşımdan geçelim. İlk olarak, Android Yedekleme Hizmetini kullanarak SharedPreferences için bir yedek oluşturmamız gerekiyor. Uygulamanızı kayıt ettirerek başlayın http://developer.android.com/google/backup/signup.html.

Google, manifest'e eklemeniz gereken bir yedekleme hizmeti anahtarı verecektir. Ayrıca, uygulamaya BackupAgent uygulamasını aşağıdaki gibi kullanmasını söylemeniz gerekir:

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

Sonra yedekleme aracısı oluşturmanız ve yardımcı aracıyı paylaşılan tercihler için kullanmasını söylemeniz gerekir:

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

Yedeklemeyi tamamlamak için ana Etkinliğinizde bir BackupManager örneği oluşturmanız gerekir:

BackupManager backupManager = new BackupManager(context);

Son olarak, henüz yoksa bir kullanıcı kimliği oluşturun ve bunu SharedPreferences'da saklayın:

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

Bu Kullanıcı_kimliği, kullanıcı cihazı hareket ettirse bile kurulumlarda kalıcı olacaktır.

Bu yaklaşım hakkında daha fazla bilgi için Reto'nun konuşmasına bakınız .

Yedekleme aracısının nasıl uygulanacağına ilişkin tüm ayrıntılar için bkz. Veri Yedekleme . Yedeklemenin hemen gerçekleşmediği için özellikle testin altındaki bölümü öneriyorum ve bu nedenle test etmek için yedeklemeyi zorlamanız gerekiyor.


5
Bir kullanıcının birden fazla cihazı olduğunda aynı kimliğe sahip birden fazla cihaza yol açmaz mı? Örneğin bir tablet ve bir telefon.
Mart'ta Tosa

Bunun için minimum hedef 8 gereklidir.
halxinate

Uygulama içi satın alımlar sırasında doğrulama yükü oluşturmanın tercih edilen yolu bu mudur? Uygulama içi faturalandırma örnek kodu yorumundan: "İyi bir geliştirici yükü şu özelliklere sahiptir: 1. İki farklı kullanıcı bir öğe satın alırsa, yük, aralarında farklıdır, böylece bir kullanıcının satın alınması başka bir kullanıcıya tekrar oynatılamaz. 2. Yükün, uygulama satın alma akışını başlatan uygulama olmasa bile doğrulayabileceğiniz şekilde olmalıdır (böylece bir cihazda kullanıcı tarafından satın alınan öğeler, kullanıcının sahip olduğu diğer cihazlarda çalışır). "
TouchBoarder

@Tosa aynı soruya sahiptim. Ancak aynı tekniği sanal cihaz kimlikleri oluşturmak için tekrar kullanamadık ve aynı şekilde yedekleyemedik mi? Cihaz kimliği bir silme veya yeniden yükleme işleminden sonra da kalmayacaktı, ancak kalıcı bir kullanıcı kimliğimiz varsa bir cihaz kimliğinden bu kadar çok ihtiyacımız olmayabilir.
jwehrle

39

Bence bu benzersiz bir kimlik için bir iskelet inşa etmenin ateş yolu ...

Tüm Android cihazlarda çalışan Sahte Benzersiz Kimlik Bazı cihazlarda telefon (ör. Tabletler) yoktur veya bir nedenle READ_PHONE_STATE iznini eklemek istemezsiniz. Kimliği bir seri anahtar kontrolü veya diğer genel amaçlar için kullanmak istiyorsanız, ROM Sürümü, Üretici adı, CPU türü ve diğer donanım ayrıntıları gibi ayrıntıları okuyabilirsiniz. Bu şekilde hesaplanan kimlik benzersiz olmayacaktır: aynı kimliğe sahip iki aygıt bulmak mümkündür (aynı donanıma ve ROM görüntüsüne dayanarak), ancak gerçek dünya uygulamalarındaki değişiklikler göz ardı edilebilir. Bu amaçla Build sınıfını kullanabilirsiniz:

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

Build üyelerinin çoğu dizgidir, burada yaptığımız şey uzunluklarını almak ve bir rakamla modulo aracılığıyla dönüştürmektir. Bu tür 13 rakamımız var ve IMEI ile aynı boyut kimliğine sahip olmak için önde iki tane daha (35) ekliyoruz (15 basamak). Burada başka olasılıklar da var, sadece bu iplere bir göz atın. Gibi bir şey döndürür 355715565309247. Bu yaklaşımı çok uygun hale getirmek için özel bir izin gerekmez.


(Ek bilgi: Yukarıda verilen teknik, Pocket Magic'teki bir makaleden kopyalanmıştır .)


7
İlginç bir çözüm. Bu gerçekten kendi "karma" fonksiyonu ile gelmeye çalışmak yerine tüm bu verileri birleştirilmiş hashing gerekir bir durum gibi görünüyor. Her değer için farklı olan önemli veriler olsa bile, çarpışmalar alabileceğiniz birçok örnek vardır. Benim tavsiyem: bir karma fonksiyonu kullanın ve sonra ikili sonuçları ondalık sayıya dönüştürün ve gerektiği şekilde kısaltın. Doğru yapmak için, gerçekten bir UUID veya tam karma dizesi kullanmalısınız.
Steve Pomeroy

21
Kaynaklarınıza kredi vermelisiniz ... Bu, aşağıdaki makaleden kaldırılmıştır: pocketmagic.net/?p=1662
Steve Haley

8
Bu kimlik, sizin bilmediğiniz gibi çarpışmalara açıktır. Aynı taşıyıcının özdeş cihazlarında aynı olması neredeyse garanti edilir.
Seva Alekseyev

7
Bu, cihaz yükseltilirse de değişebilir.
David

8
Çok, çok kötü bir çözüm. İki Nexus 5 üzerinde test edildi ... Aynı numaraları döndür.
Sinan Dizdarević

38

Aşağıdaki kod, gizli bir Android API kullanarak cihaz seri numarasını döndürür. Ancak, bu kod Samsung Galaxy Tab üzerinde çalışmaz çünkü bu cihazda "ro.serialno" ayarlanmamıştır.

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

}

Ben sadece ro.serialnooluşturmak için kullanılan xda geliştirici okudum Settings.Secure.ANDROID_ID. Yani temel olarak aynı değerin farklı temsilleridir.
Martin

@Martin: ancak cihazı sıfırlarken seri numarası değişmez. Öyle değil mi? Bunun için sadece yeni bir değer ANDROID_IDelde edilir.
Ronnie

Aslında tüm cihazlarda aynı yerde test ettim. Ya da en azından karma değerleri aynı (gizlilik nedeniyle gerçek değerleri günlük dosyalarına yazmıyorum).
Martin

Bu değerandroid.os.Build.SERIAL
eugeneek

android.os.Build.SERIALAndroid O'da kullanımdan kaldırılacak, bkz. android-developers.googleblog.com/2017/04/…
EpicPandaForce

32

Basit bir soru, basit bir cevabı yok.

Dahası, buradaki mevcut cevapların tümü güncel değil veya güvenilir değil.

Yani sen 2020 yılında bir çözüm arama yapıyorsanız .

Aklınızda bulundurmanız gereken birkaç nokta:

Tüm donanım tabanlı tanımlayıcılar (SSAID, IMEI, MAC, vb.), Dünya çapında aktif cihazların% 50'sinden fazlası olan google harici cihazlar (Piksel ve Nexuses hariç her şey) için güvenilir değildir. Bu nedenle resmi Android tanımlayıcılarının en iyi uygulamaları açıkça belirtmektedir:

SSAID (Android ID), IMEI, MAC adresi vb. Gibi donanım tanımlayıcıları kullanmaktan kaçının .

Bu, yukarıdaki cevapların çoğunu geçersiz kılar. Ayrıca farklı android güvenlik güncellemeleri nedeniyle, bazıları daha basit ve kullanıcı tarafından reddedilebilecek daha yeni ve daha katı çalışma zamanı izinleri gerektirir.

Yukarıda CVE-2018-9489belirtilen tüm WIFI tabanlı teknikleri etkileyen örnek olarak .

Bu, bu tanımlayıcıları yalnızca güvenilir değil, aynı zamanda birçok durumda erişilemez hale getirir.

Yani daha basit kelimelerle: bu teknikleri kullanma .

Buradaki diğer birçok yanıt AdvertisingIdClient, tasarımıyla yalnızca reklam profili oluşturma için kullanılması gerektiğinden, aynı zamanda uyumsuz olanı kullanmanızı önerir . Resmi referansta da belirtilmiştir

Reklam kimliğini yalnızca kullanıcı profili oluşturma veya reklam kullanım örnekleri için kullanın

Yalnızca cihaz tanımlaması için güvenilir değildir, aynı zamanda kullanıcının herhangi bir anda sıfırlayabileceğini veya engelleyebileceğini açıkça belirten reklam izleme politikasıyla ilgili kullanıcı gizliliğine de uymanız gerekir .

Yani onu da kullanma .

İstediğiniz statik global benzersiz ve güvenilir cihaz tanımlayıcısına sahip olamayacağınız için. Android'in resmi referansı şunları önerir:

Ödeme sahtekarlığını önleme ve telefonculuk hariç, diğer tüm kullanım durumlarında mümkün olduğunda bir FirebaseInstanceId veya özel olarak saklanmış bir GUID kullanın.

Cihazdaki uygulama kurulumu için benzersizdir, bu yüzden kullanıcı uygulamayı kaldırdığında - silinir, bu yüzden% 100 güvenilir değildir, ancak bir sonraki en iyi şeydir.

Kullanmak için sınıfınızaFirebaseInstanceId en son ateş tabanı mesajlaşma bağımlılığını ekleyin

implementation 'com.google.firebase:firebase-messaging:20.2.0'

Ve arka plan iş parçacığında aşağıdaki kodu kullanın:

String reliableIdentifier = FirebaseInstanceId.getInstance().getId();

Aygıt kimliğini uzak sunucunuzda depolamanız gerekiyorsa, olduğu gibi saklamayın (düz metin), ancak tuz içeren bir karma .

Bugün sadece en iyi uygulama değil, aslında bunu GDPR - tanımlayıcıları ve benzeri düzenlemelere göre yasa ile yapmanız gerekir .


3
Şimdilik bu en iyi cevap ve ilk cümle en iyi özet: "Basit bir soru, basit bir cevap olmadan - sadece sev.
b2mob

"Ödeme sahtekarlığının önlenmesi ve telefon hariç" yorumunu, bu kullanım durumunu nasıl ele alacağınıza ilişkin hiçbir cevap verilmeden takdir etmelisiniz.
Eran Boudjnah

@EranBoudjnah Cevapta bağlantılı resmi referanstan alıntı. Bu kullanım durumunu ele almaya çalışabilirim, ancak OP sorusuna özgü olmadığından, stackoverflow politikasına göre - ayrı bir özel soruda yapılmalıdır.
Nikita Kurtin

Sadece cevabın eksik olduğunu söylüyorum. Ama bunun bir teklif olduğu için senin hatan olmadığını biliyorum.
Eran Boudjnah

1
@ M.UsmanKhan, cevap bundan hemen sonra yazılıyor: " Bugün sadece en iyi uygulama değil, aslında GDPR - tanımlayıcılar ve benzeri düzenlemelere göre yasa ile yapmanız gerekiyor. "
Nikita Kurtin

27

Aşağıdaki kodu kullanarak, bir Android OS cihazının benzersiz cihaz kimliğini dize olarak alabilirsiniz.

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

21

Sınıfa API seviye 9'daki (Android 2.3 - Gingerbread) bir Seri alan eklendi Build. Belgeler, donanım seri numarasını temsil ettiğini söylüyor. Bu nedenle, cihazda varsa benzersiz olmalıdır.

API düzeyi> = 9 olsa tüm cihazlar tarafından aslında (= boş değil) desteklenip desteklenmediğini bilmiyorum.


2
Ne yazık ki, "bilinmiyor".
m0skit0

18

Ekleyeceğim bir şey var - bu eşsiz durumlardan birine sahibim.

Kullanımı:

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

Viewsonic G Tabletimde Null olmayan bir DeviceID bildirilse bile, her bir G Tablet'in aynı numarayı bildirdiği ortaya çıkıyor.

"Benzersiz" DeviceID dayalı birinin hesabına anında erişim sağlayan "Pocket Empires" oynamak ilginç kılar.

Cihazımda hücre radyosu yok.


Kimlik nedir? perchance 9774d56d682e549cmı?
Mr_and_Mrs_D

Vay be, çok uzun zaman önceydi o tableti çoktan attım. Söyleyemedim.
Tony Maro

İşler. Ayrıca, rastgele UUID'den aldığım kimlikten çok daha kompakt.
Treewallie

1
@Treewallie çalışıyor mu? Farklı Uygulamalardan aynı cihaz kimliğini alabilir misiniz?
Arnold Brown

@ArnoldBrown Evet. Test ettiğinizden emin olun. İyi günler: D
Treewallie

16

Uygulamanızın yüklü olduğu her bir Android cihaz için benzersiz bir tanımlayıcı edinmeye ilişkin ayrıntılı talimatlar için, resmi Android Geliştiricileri Blogunun Uygulama Yüklemelerini Tanımlama yayınlamasına bakın .

En iyi yol, kurulumdan sonra kendiniz bir tane oluşturmanız ve daha sonra uygulama yeniden başlatıldığında onu okumaktır.

Şahsen bunu kabul edilebilir buluyorum ama ideal değil. Android tarafından sağlanan hiçbir tanımlayıcı, çoğu durumda telefonun radyo durumlarına (Wi-Fi açık / kapalı, hücresel açık / kapalı, Bluetooth açık / kapalı) bağlı olduğu için tüm durumlarda çalışmaz. Diğerleri, Settings.Secure.ANDROID_IDüretici tarafından uygulanmalıdır ve benzersiz oldukları garanti edilmez.

Aşağıda, uygulamanın yerel olarak kaydettiği diğer verilerle birlikte depolanacak bir yükleme dosyasına veri yazma örneği yer almaktadır .

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

Uygulama yüklemelerini izlemek istiyorsanız bu mükemmeldir. Cihazları izlemek çok daha zordur ve tamamen hava geçirmez bir çözüm gibi görünmemektedir.
Luca Spiller

Rootlu cihazlar ne olacak? Bu kurulum kimliğini kolayca değiştirebilirler, değil mi?
tasomaniac

Kesinlikle. Kök kurulum kimliğini değiştirebilir. Bu kod bloğunu kullanarak root kontrolü yapabilirsiniz: stackoverflow.com/questions/1101380/…
Kevin Parker

fabrika ayarlarına sıfırlanırsak dosya silinir mi?
Jamshid

/ Data bölümünü fabrika ayarlarına sıfırlar ve siler veya biçimlendirirseniz UUID farklıdır.
Kevin Parker

12

Sınıf dosyasına aşağıdaki kodu ekleyin:

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

AndroidManifest.xml dosyasına ekleyin:

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

10

Android OS cihazının String olarak benzersiz cihaz kimliği, TelephonyManagerve kullanılarak ANDROID_IDşu şekilde elde edilir:

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

Ancak Google tarafından önerilen bir yöntemi şiddetle öneririm, bkz . Uygulama Yüklemelerini Belirleme .


9

Bu ANDROID_IDsorunlar üzerinde çalışmak için birçok farklı yaklaşım vardır ( nullbazen veya belirli bir modelin cihazları her zaman aynı kimliği döndürür) artıları ve eksileri ile:

  • Özel kimlik oluşturma algoritması uygulama (statik olması gereken ve değişmeyecek olan cihaz özelliklerine göre -> kim bilir)
  • IMEI , seri numarası, Wi-Fi / Bluetooth-MAC adresi gibi diğer kimliklerin kötüye kullanılması (tüm cihazlarda bulunmayacak veya ek izinler gerekli olacaktır)

Kendim Android için mevcut bir OpenUDID uygulamasını kullanmayı tercih ediyorum (bkz. Https://github.com/ylechelle/OpenUDID ) (bkz. Https://github.com/vieux/OpenUDID ). Entegre edilmesi kolaydır ve ANDROID_IDyukarıda bahsedilen sorunlar için yedeklerle birlikte kullanılır .


8

Peki IMEI . Bu, Android veya diğer mobil cihazlar için benzersizdir.


9
Mobil operatöre bağlanmadıkları için IMEI'si olmayan tabletlerim için değil.
Brill Pappin

2
IMEI yerine ESN'li CDMA aygıtlarından bahsetmiyorum bile.
David

@David Verilen Android ile CDMA var mı?
Elzo Valugi

1
Sadece o yapacak olan bir telefon :) Bir Tablet olmayabilir.
Brill Pappin

3
@ElzoValugi Zaten "bugünlerde" ve hala tüm tabletlerde SIM kart yok.
Matthew Quiros

8

İşte nasıl benzersiz id üretiyorum:

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.0 sürümünde ReadPhoneState kullanıcısını çalışma zamanı izni istiyorsak
Harsha

8

İki sentim - NB bu, bir cihaz (err) benzersiz kimliği için - Android geliştiricilerinin blogunda tartışıldığı gibi kurulum değil .

SharedPreferences süreçler arasında senkronize edilmediğinden @emmby tarafından sağlanan çözümün uygulama başına kimliğine geri döndüğünü unutmayın ( buraya ve buraya bakın ). Bu yüzden bundan tamamen kaçındım.

Bunun yerine, bir numaralandırmada (cihaz) kimliği almak için çeşitli stratejileri kapsadım - numaralandırma sabitlerinin sırasını değiştirmek, kimliği almanın çeşitli yollarının önceliğini etkiler. İlk null olmayan kimlik döndürülür veya bir istisna atılır (iyi Java uygulamalarına göre null'a bir anlam vermeme). Yani örneğin ben TELEPHONY bir ilk var - ama iyi bir varsayılan seçim ANDROID_ID beta olurdu :

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

8

Burada 30'dan fazla cevap var ve bazıları aynı ve bazıları benzersiz. Bu cevap bu cevaplardan birkaçına dayanmaktadır. Bunlardan biri @Lenn Dolling'in cevabı.

3 kimliği birleştirir ve 32 basamaklı bir onaltılık dize oluşturur. Benim için çok iyi çalıştı.

3
Kimlik : Sahte Kimlik - Fiziksel aygıt belirtimlerine göre oluşturulur
ANDROID_ID - Settings.Secure.ANDROID_ID
Bluetooth Adresi - Bluetooth adaptör adresi

Bunun gibi bir şey döndürür: 551F27C060712A72730B0A0F734064B1

Not: Dizeye her zaman daha fazla kimlik ekleyebilirsiniz longId. Örneğin, Seri #. wifi adaptör adresi. IMEI. Bu şekilde cihaz başına daha benzersiz hale getirmiş olursunuz.

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

1
Ekleme UUID'sini için longId: o en benzersiz bir tanımlayıcı yapmak, ve bir dosyada saklayınString uuid = UUID.randomUUID().toString();
Mousa Alfhaily

1
Her şey başarısız olursa, kullanıcı API 9'dan düşükse (Gingerbread'den düşük) telefonunu veya 'Secure.ANDROID_ID' değerini sıfırladı. 'null' döndürürse, yalnızca döndürülen kimlik yalnızca Android cihaz bilgilerini temel alır. Çarpışmalar burada gerçekleşebilir. DISPLAY, HOST veya ID kullanmamaya çalışın - bu öğeler değişebilir. Çarpışmalar varsa, çakışan veriler olacaktır. Kaynak: gist.github.com/pedja1/fe69e8a80ed505500caa
Mousa Alfhaily

Bu kod satırında Benzersiz numara almaya çalışırsak, bu Benzersiz Kimlik olduğunu söyleyebilir ve başka bir cihazla asla çakışmayacak mı?
Ninja

1
@Ninja BLE mac adresi benzersiz olduğundan, evet oluşturulan kimlik her zaman benzersiz olacaktır. Ancak, gerçekten emin olmak istiyorsanız, bir UUID eklemenizi öneririm longId. Bir satırı şu şekilde değiştirin: String longId = pseudoId + androidId + btId + UUID.randomUUID().toString();Bu, oluşturulan kimliğin benzersiz olacağını garanti eder.
ᴛʜᴇᴘᴀᴛᴇʟ

@ ᴛʜᴇᴘᴀᴛᴇʟ Bu büyük yardım için çok teşekkür ederim. Aslında benim app çok hassas veriler bu yüzden ben sadece bu şeyleri teyit bu yüzden emin olmak gerekir.
Ninja

7

Başka bir yol, /sys/class/android_usb/android0/iSerialherhangi bir izin olmadan bir uygulamada kullanmaktır.

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

Java'da bunu yapmak için iSerial dosyasını açmak ve karakterleri okumak için bir FileInputStream kullanılır. Tüm cihazlarda bu dosya olmadığından, bir istisna işleyicisine sardığınızdan emin olun.

En azından aşağıdaki cihazların bu dosyanın dünya tarafından okunabilir olduğu bilinmektedir:

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

Blog gönderimi ayrıca , bilgi için başka hangi dosyaların mevcut olduğunu tartıştığım ayrıcalıklı olmayan uygulamalara Android donanım seri numarasını sızdırıyor da görebilirsiniz .


Sadece blog yazınızı okudum. Bunun benzersiz olmadığına inanıyorum: Build.SERIAL, herhangi bir izin olmadan da kullanılabilir ve (teoride) benzersiz bir donanım seri numarasıdır.
Tom

1
Haklısın. Bu, cihazınızın izlenebilmesinin sadece bir yolu daha var ve dediğin gibi her iki yöntem de uygulama izni gerektirmiyor.
insitusec

7

TelephonyManger.getDeviceId () Benzersiz aygıt kimliğini döndürür; örneğin, GSM için IMEI ve CDMA telefonlar için MEID veya ESN.

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

Ama ben kullanmanızı öneririz:

Android ID'yi benzersiz bir 64 bit onaltılık dize olarak döndüren Settings.Güvenli.ANDROID_ID .

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

Bazen TelephonyManger.getDeviceId () null döndürür, bu nedenle benzersiz bir kimlik sağlamak için bu yöntemi kullanırsınız:

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

Kısa bir süre önce, bir müşterinin SM-G928F / Galaxy S6 edge + cihazının Android Kimliği için 16 onaltılık rakam yerine yalnızca 15 verdiğini keşfettim.
Holger Jakobs

7

Belirli bir Android cihazın donanım tanıma için MAC Adreslerini kontrol edebilirsiniz.

bunu şu şekilde yapabilirsiniz:

AndroidManifest.xml'de

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

şimdi kodunuzda:

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

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

Her Android cihazda en az bir "wlan0" Arayüzü cadı WI-FI yongasıdır. Bu kod, WI-FI açık olmasa bile çalışır.

PS Onların MACS içeren listeden alacağınız diğer Arayüzler bir demet Ama bu telefonlar arasında değişebilir.


7

IMEIGüvenli almak veya kullanmak için aşağıdaki kodu kullanın. ANDROID_IDalternatif olarak, cihazda telefon özellikleri yoksa:

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

7

Daha spesifik olarak Settings.Secure.ANDROID_ID,. Bu, aygıt ilk kez başlatıldığında oluşturulan ve depolanan 64 bitlik bir miktardır. Cihaz silindiğinde sıfırlanır.

ANDROID_IDbenzersiz bir cihaz tanımlayıcısı için iyi bir seçim gibi görünüyor. Dezavantajları vardır: Birincisi, 2.2'den önceki Android sürümlerinde% 100 güvenilir değildir. (“Froyo”).Ayrıca, her bir örneğin aynı ANDROID_ID değerine sahip olduğu büyük bir üreticinin popüler bir telefonunda en az bir yaygın olarak gözlemlenen hata vardı.


1
bu cevap eski google blog android-developers.googleblog.com/2011/03/… 'nin bir kopya macunudur . Yani hata zaten çözüldü mü?
Sergii


6

Google Örnek Kimliği

I / O 2015'te çıktı; Android için oyun hizmetleri 7.5 gerektirir.

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

Google, bu kimliğin Android, Chrome ve iOS'taki yüklemeleri tanımlamak için kullanılmasını planlıyor gibi görünüyor.

Bir aygıttan çok bir kurulumu tanımlar, ancak daha sonra tekrar ANDROID_ID (kabul edilen cevaptır) artık cihazları da tanımlamamaktadır. ARC çalışma zamanı ile, bu yeni yönetim ortamı kimliği gibi her kurulum için ( burada ayrıntılar ) yeni bir ANDROID_ID oluşturulur . Ayrıca, kurulumların (cihazlar değil) tanımlanmasının çoğumuzun aradığı şey olduğunu düşünüyorum.

Örnek kimliğinin avantajları

Bana öyle geliyor ki, Google bu amaç için kullanılmasını planlıyor (kurulumlarınızı tanımlamak), platformlar arası ve bir dizi başka amaç için kullanılabilir (yukarıdaki bağlantılara bakın).

GCM kullanıyorsanız, GCM belirtecini (eski GCM kayıt kimliğinin yerine geçer) almak için ihtiyacınız olduğu için bu örnek kimliğini kullanmanız gerekir.

Dezavantajları / sorunları

Geçerli uygulamada (GPS 7.5), uygulamanız istediği zaman örnek kimliği bir sunucudan alınır. Bu, yukarıdaki çağrının engelleme çağrısı olduğu anlamına gelir - bilimsel olmayan testlerimde cihazın çevrimiçi olması 1-3 saniye, çevrimdışı ise 0,5 - 1,0 saniye sürer (muhtemelen bu, vazgeçip üretmeden önce ne kadar beklediğidir) rastgele ID). Bu, Android 5.1.1 ve GPS 7.5 ile Nexus 5'te Kuzey Amerika'da test edildi.

Kimliği amaçlanan amaçlarla kullanırsanız - ör. uygulama kimlik doğrulaması, uygulama kimliği, GCM - Sanırım bu 1-3 saniye bir sıkıntı olabilir (elbette uygulamanıza bağlı olarak).


1
exampleID'nin bir diğer önemli dezavantajı, kullanıcı uygulamanın verilerini temizlerse sizin için yeni bir instanceID'nin oluşturulmasıdır.
idanakav

İlginç, ancak potansiyel kullanım durumlarını gerçekten değiştirdiğini düşünmüyorum: android_id gibi örnek kimliği, bir cihazı tanımlamak için uygun değil. Böylece sunucunuz, kullanıcı tarafından silinen verileri, uygulamanızı kaldırıp yeniden yüklüyormuş gibi görecektir - bu mantıksız değildir.
Tom
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.