Soru Benzersiz bir Android cihaz kimliği var mı?


Android cihazların benzersiz bir kimliği var mı ve eğer öyleyse, Java kullanarak erişmek için basit bir yol nedir?


2312
2018-05-07 00:47


Menşei


Kullanıyorsanız ANDROID_ID okuduğunuzdan emin olun bu cevap ve bu böcek. - Dheeraj V.S.
İşte bilgilendirici bir cevap. - Eng.Fouad
Mükemmel buldum: stackoverflow.com/a/16929647/1318946 - Pratik Butani
Tüm mevcut benzersiz tanımlayıcıları tartıştığından ve her birinde tartıldığından ve en iyi sonuçları verdiğinden, bunu çok yararlı buldum. stackoverflow.com/q/27233518/5252270 - sathishkumar_kingmaker


Cevaplar:


Settings.Secure#ANDROID_ID Android kimliğini bir her kullanıcı için benzersiz 64 bitlik hex dizesi.

import android.provider.Settings.Secure;

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

1699
2018-05-07 00:49



Bazen boş olarak bilinir, "fabrika ayarlarına sıfırlamada değişebilir" şeklinde belgelenmiştir. Kendi riskinizle kullanın ve köklü bir telefonda kolayca değiştirilebilir. - Seva Alekseyev
groups.google.com/group/android-developers/browse_thread/thread/... - Erdal
Ben ilk uygulamada ANDROID_ID kullanma konusunda dikkatli olmamız gerektiğini düşünüyorum çünkü uygulama ilk çalıştırıldığında ayarlanamayabilir, daha sonra ayarlanabilir veya hatta teoride bile değişebilir, dolayısıyla benzersiz ID değişebilir
Bu çözümle ilgili büyük sınırlamalar olduğunu unutmayın: android-developers.blogspot.com/2011/03/... - emmby
ANDROID_ID artık bir cihazı benzersiz olarak tanımlamaz (4.2'den itibaren): stackoverflow.com/a/13465373/150016 - Tom


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

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


Bu soruna pek çok cevap var, bunların çoğu zamanın sadece bir kısmını "biraz" çalıştıracak ve maalesef bu yeterince iyi değil.

Cihaz testlerime dayanarak (en az bir tanesi aktif olmayan tüm telefonlar):

  1. Test edilen tüm cihazlar için bir değer döndü TelephonyManager.getDeviceId()
  2. Tüm GSM cihazları (tümü bir SIM ile test edilmiştir) için bir değer döndürdü TelephonyManager.getSimSerialNumber()
  3. Tüm CDMA cihazları null için döndürüldü getSimSerialNumber() (beklenildiği gibi)
  4. Google hesabına sahip tüm cihazlar eklendi. ANDROID_ID
  5. Tüm CDMA aygıtları, her ikisi için aynı değeri (veya aynı değerin türetmesini) döndürdü ANDROID_ID ve TelephonyManager.getDeviceId() - olduğu sürece kurulum sırasında bir Google hesabı eklendi.
  6. GSM cihazlarını hiç SIM olmaksızın test etme şansı, Google hesabı olmayan bir GSM cihazı veya uçak modunda herhangi bir cihaz kullanma şansım olmadı.

Yani, cihazın kendisine özgü bir şey istiyorsanız TM.getDeviceId()  meli yeterli ol. Açıkçası, bazı kullanıcılar diğerlerinden daha paranoyaktır, bu yüzden bu tanımlayıcıların 1 veya daha fazlasına sahip olmak yararlı olabilir, böylece dizge hala aygıt için neredeyse benzersizdir, ancak kullanıcının gerçek aygıtını açıkça tanımlamaz. Örneğin, kullanarak String.hashCode()bir UUID ile birlikte:

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

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

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

Richard'ın aşağıda bahsettiği gibi, okumak için izin almanız gerektiğini unutmayın. TelephonyManager özellikleri, bu yüzden manifestinize 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;

1056
2018-05-17 22:12



Telefon tabanlı kimlik, tablet cihazlarda olmayacak mı? - Seva Alekseyev
Bu yüzden çoğu zaman her zaman işe yaramayacağımı söyledim :) Bu soruya tüm cihazlar, tüm cihaz türleri ve tüm donanım yapılandırmaları için güvenilir bir cevap görmedim. Bu yüzden bu soru ile başlamak için burada. Sonuna kadar hiç bir çözüm bulunmadığı oldukça açıktır. Bireysel cihaz üreticileri, cihaz seri numaralarına sahip olabilirler, ancak bizim kullanımımız için maruz kalmazlar ve bu bir gereklilik değildir. Böylece bizim için uygun olanla kaldık. - Joe
Kod örneği harika çalışıyor. Eklemeyi unutmayın <uses-permission android:name="android.permission.READ_PHONE_STATE" /> manifest dosyasına. Bir veritabanında depolanıyorsa, döndürülen dize 36 karakter uzunluğundadır. - Richard
Bu çözümle ilgili büyük sınırlamalar olduğunu unutmayın: android-developers.blogspot.com/2011/03/... - emmby
@softarn: Size atıfta bulunduğunuz şeyin, emmby'nin zaten bağlı olduğu Android Geliştirici Blogu olduğuna inanıyorum. çalışıyor demek ki, belki de onun yerine yorumunu yazmış olmalısınız. Her iki durumda da, emmby'nin cevabında bahsettiği gibi, blog bilgisiyle bile hala problemler vardır. Soru benzersiz bir sorar CİHAZ tanımlayıcı (kurulum tanımlayıcısı değil), bu yüzden ifadenize katılmıyorum. Blog ne istediğine dair bir varsayım yapıyor gereksiz Cihazı izlemek için, soru ise sadece bunu soruyor. Başka bir blogla aynı fikirdeyim. - Joe


Son Güncelleme: 6/2/15


Benzersiz bir kimlik, Google geliştirici blogu ve Android dokümantasyonu oluşturma ile ilgili her Yığın Taşımı yayınını okuduktan sonra, 'Sözde Kimlik' mümkün olan en iyi seçenek gibi hissediyorum.

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

Donanım

  • Kullanıcılar donanımlarını, Android tabletlerini veya telefonlarını değiştirebilir, böylece donanıma dayalı benzersiz kimlikler, İZLEME KULLANICILARI
  • İçin İZLEME DONANIMI, bu harika bir fikir

Yazılım

  • Kullanıcılar root'larsa ROM'larını silebilir / değiştirebilir
  • Kullanıcıları platformlarda (iOS, Android, Windows ve Web) takip edebilirsiniz
  • En iyi ister BİREYSEL KULLANICI TAKİP onların ile razı olmak sadece onları giriş yapmak (OAuth kullanarak bu sorunsuz yapmak)

Android ile genel arıza

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

- 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 unique ID of build information (may overlap data - API < 9)

Göndermek için @stansult'a teşekkürler tüm seçeneklerimiz (Bu Stack Overflow sorusunda).

Seçenek listesi - neden / 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ı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 (sadece telefonlar, ihtiyaçlar android.permission.READ_PHONE_STATE)

    • Kullanıcıların çoğu, "Telefon Görüşmeleri" nin izin verdiği gerekçesiyle nefret ediyor. Bazı kullanıcılar kötü puanlar verir, çünkü gerçekten yapmak istediklerinizin sadece cihaz yüklemelerini takip etmesi gerektiğinde kişisel bilgilerini çaldığına inanırlar. Veri topladığınız açıktır.
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • Android Kimliği - Donanım (null olabilir, fabrika ayarlarına sıfırlayabilir, köklü bir cihaz üzerinde değiştirilebilir)

    • 'Boş' olabileceğinden, 'boş' olup olmadığını 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, bu yüzden kullanıcı yüklemelerini izliyorsanız tekrarlayan girişler 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ıyı 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)

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

    • Çok olası, çarpışmalar içerebilir - Aşağıda benim yöntemimi gör!
    • Bu, özel bir şey almadan kullanıcıdan 'neredeyse benzersiz' bir kimliğe sahip olmanızı sağlar. Cihaz bilgilerinden kendi anonim kimliğinizi oluşturabilirsiniz.

İzinleri kullanmadan benzersiz bir kimlik almanın 'mükemmel' bir yolu olmadığını biliyorum; Ancak, bazen sadece cihaz kurulumunu izlememiz gerekiyor. Benzersiz bir kimlik oluşturmaya gelince, Android API'nın ekstra izin kullanmadan bize verdiği bilgilerin yalnızca bir kısmına dayalı olarak 'sözde benzersiz bir kimlik' oluşturabiliriz. Bu şekilde, kullanıcıya saygı gösterebilir ve iyi bir kullanıcı deneyimi sunmaya çalışabiliriz.

Sahte benzersiz bir kimlikle, yalnızca benzer aygıtların olduğu gerçeğine dayanarak yineleme olabileceği gerçeğine rastlarsınız. Daha benzersiz hale getirmek için birleştirilmiş yöntemi değiştirebilirsin; bununla birlikte, bazı geliştiricilerin cihaz yüklemelerini takip etmesi gerekir ve bu da benzer cihazlara dayanan hileyi veya performansı gerçekleştirecektir.

API> = 9:

Android cihazlarının API 9 veya üstü olması durumunda, 'Build.SERIAL' alanı nedeniyle benzersiz olması garanti edilir.

HATIRLAMAKteknik olarak sadece kullanıcıların yaklaşık% 0,5'ini kaçırıyorsunuz API <9 olan kullanıcılar. Böylece geri kalanı üzerinde odaklanabilirsiniz: Bu kullanıcıların% 99.5'idir!

API <9:

Kullanıcının Android cihazı API 9'dan düşükse; umarız, fabrika ayarlarına sıfırlamadılar ve 'Secure.ANDROID_ID' değerleri korunur veya 'null' değil. (görmek http://developer.android.com/about/dashboards/index.html)

Eğer hepsi hataysa:

Eğer tüm bunlar başarısız olursa, kullanıcı API 9'dan (Gingerbread'dan daha düşük) düşükse, cihazını sıfırladı veya 'Secure.ANDROID_ID', 'null' değerini döndürdü, daha sonra sadece geri dönen ID, Android cihazlarının bilgilerine dayanacaktı. Çarpışmaların gerçekleştiği yer burası.

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şiklik yapmak için kodu düzenledim
  • Sözde 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 (reklamlar ve Google Play Hizmetleri olan uygulamalar için):

Google Play Geliştirici konsolundan:

1 Ağustos 2014'ten itibaren Google Play Geliştirici Programı Politikası   Reklam kimliğini kullanmak için tüm yeni uygulama yüklemelerini ve güncellemeleri gerektirir.   Herhangi bir reklam amaçlı diğer kalıcı tanımlayıcıların yerine.   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:

Reklam kimliğinin tamamen mevcut olması amaçlanmıştır   reklamlar için diğer tanımlayıcıların kullanımı (ANDROID_ID kullanımı gibi)   Google Play Hizmetleri mevcut olduğunda, Settings.Secure'da. Kılıflar   Google Play Hizmetleri'nin kullanılamadığı yerler,   GooglePlayServicesNotAvailableException tarafından atılıyor   getAdvertisingIdInfo ().

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. Eğer eksik ve dahil olmanız gerekiyorsa lütfen yorum yapın!

Google Oyuncu Hizmetleri InstanceID

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


365
2017-07-12 23:58



Ama olmaz Build işletim sistemi güncellemesi üzerine sınıf değişikliği mi? Özellikle API güncellendi mi? Eğer öyleyse, bunun benzersiz olduğunu nasıl garanti edersiniz? (Yazdığın yöntem hakkında konuşma) - LuckyMe
Yorum göndermek için uygulamasında uygulamanızı kullandım. Kötü haberlerim var. ne yazık ki PsuedoID tamamen benzersiz değildir. sunucum 5 ID için 100'den fazla ve neredeyse 30 ID için 30'dan fazla kaydedildi. En çok tekrarlanan ID'ler 'ffffffff-fc8f-6093-ffff-ffffd8' (159 kayıt) ve 'ffffffff-fe99-b334-ffff-ffffef' (154 kez) 'dir. ayrıca zamana ve yorumlara dayanan, farklı insanlar var. şimdiye kadar toplam kayıtlar 10.000. Lütfen bunun neden olduğunu bana bildirin. tankları. - hojjat reyhane
Bunu 1,5+ yıl önce yazdım. Senin için neden eşsiz olmadığından emin değilim. Reklam kimliğini deneyebilirsiniz. Eğer değilse, kendi çözümünüzle gelebilirsiniz. - Jared Burrows
sorta..Sorudan geçip düşüncelerinizi iletirseniz gerçekten minnettarım. - Durai Amuthan.H
@ user1587329 Teşekkürler. Bunu herkes için güncel tutmaya çalışıyorum. Bu soru donanım vs yazılım ve çapraz platform söz konusu olduğunda zor. - Jared Burrows


Dave Webb'in bahsettiği gibi, Android Geliştirici Blog’un bir makalesi var bunu kapsar. Tercih ettikleri çözüm, cihazlardan ziyade uygulama yüklemelerini izlemektir ve çoğu kullanım durumu için iyi çalışır. Blog yazısı, bu işi yapmak için gerekli kodu size gösterecek ve kontrol etmenizi öneriyorum.

Ancak, blog uygulaması, uygulama yükleme tanımlayıcısı yerine cihaz tanımlayıcısına ihtiyacınız varsa çözümleri tartışmaya devam eder. Google'da birisiyle yapmanız gerektiğinde birkaç öğeyle ilgili bazı ek açıklamalar almak için konuştum. Daha önce bahsettiğim blog gönderisinde belirtilmeyen 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. Sadece 2.2 mesajda belirtilen sorunlara sahiptir.
  • Birkaç üreticinin birkaç cihazı, 2.2'de ANDROID_ID hatasını etkilemektedir.
  • Algıladığım kadarıyla, etkilenen tüm cihazlar aynı ANDROID_ID, hangisi 9774d56d682e549c. Aynı zamanda emülatör tarafından bildirilen aynı cihaz kimliği, btw.
  • Google, OEM'lerin, cihazlarının çoğuna veya birçoğuna ilişkin sorunu çözdüğüne inanıyor, ancak Nisan 2011'in başlangıcından itibaren, en azından, ANDROID_ID'nin bozuk olduğu cihazları bulmak hâlâ oldukça kolaydı.

Google'ın önerilerine dayanarak, her cihaz için benzersiz bir UUID oluşturacak, gerektiğinde tohum olarak ANDROID_ID öğesini kullanarak, gerektiğinde TelephonyManager.getDeviceId () öğesine geri dönecek ve bu başarısız olursa rastgele oluşturulmuş benzersiz bir UUID'ye başvuracak bir sınıf uyguladık. Bu, uygulama yeniden başlatıldığında kalıcıdır (ancak uygulama yeniden yüklemeleri değil).

Cihaz kimliğinde geriye düşmesi gereken cihazlar için benzersiz kimlik olduğunu unutmayın. İRADE fabrika ayarlarına devam et. Bu farkında olmak için bir şey. Fabrika ayarlarının benzersiz kimliğinizi sıfırladığından emin olmanız gerekiyorsa, cihaz kimliği yerine doğrudan rastgele UUID'ye geri dönmeyi düşünebilirsiniz.

Yine, bu kod bir uygulama kimliği için değil, bir cihaz kimliği içindir. Çoğu durumda, bir uygulama yükleme kimliği muhtemelen sizin 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;
    }
}

314
2018-04-11 19:06



Çeşitli kimliklere sahip olmanız gerekmeyecek mi, hepsi aynı boyda mı? Ayrıca, gizli bilgileri yanlışlıkla açığa çıkarmamak için cihaz kimliğini eklemelisiniz. - Steve Pomeroy
İ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ı sağlar ve b) Android ve cihaz kimlikleri, kişisel bilgilerin yanlışlıkla açığa çıkarılmasını önlemek için geri gönderilmeden önce karıştırılır. Ayrıca, cihazın kimliğinin fabrika ayarlarına göre devam edeceğini ve bunun bazı kullanıcılar için istenmeyebileceğini belirtmek için açıklamayı güncelledim. - emmby
Yanlış olduğuna inanıyorum; tercih edilen çözüm, cihaz tanımlayıcılarını değil, kurulumları izlemektir. Kodunuz, blog yayınınınkinden daha uzun ve daha karmaşıktır ve bana herhangi bir değer kattığının açık olmadığı kesin değildir. - Tim Bray
İyi bir nokta, kullanıcıların cihaz kimlikleri yerine uygulama yükleme kimliklerini kullanmasını şiddetle tavsiye etmek için yorumu güncelledim. Ancak, bu çözümün kurulum kimliği yerine bir cihaza ihtiyaç duyan kişiler için hala değerli olduğunu düşünüyorum. - emmby
ANDROID_ID, fabrika ayarlarına sıfırlanabilir. Bu nedenle, cihazları da tanımlayamaz. - Samuel


İşte Reto Meier’in Google I / O Bu sene, kullanıcı için benzersiz bir kimlik elde etmek için sunum:

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, bulutta tercihler göndermek için bir yedekleme stratejisiyle birleştirirseniz (ayrıca konuşma, bir kullanıcı ile bağlanan ve cihaz silindikten sonra veya hatta değiştirildikten sonra etrafa yapışan bir kimliğiniz olmalıdır. Bunu ileriye dönük analitikte kullanmayı planlıyorum (başka bir deyişle, henüz bitirmedim :).


165
2017-10-28 13:19



@Lenn Dolling'in yöntemini benzersiz kimlik için eklenen geçerli saati kullanarak kullanıyordum. Ancak bu daha basit ve güvenilir bir yol gibi görünüyor. Teşekkürler Reto Meier ve Antony Nolan - Gökhan Barış Aker
Bu harika ama ne köklü cihazlar hakkında? Buna erişebilir ve uid'i kolayca farklı bir değere dönüştürebilirler. - tasomaniac
Bir kaldırma ve yeniden yüklemeden sonra devam etmek için benzersiz kimliğe ihtiyacınız yoksa (ör., Kazanmak için üç fırsat kazanabileceğiniz promosyon etkinliği / oyun) mükemmel seçenek. - Kyle Clegg
Meier sunumu, Android Yedekleme Yöneticisi'ni kullanmaya dayanır ve bu da kullanıcının bu özelliği açmayı seçmesine bağlıdır. Bu, kullanıcı kullanıcı tercihleri ​​için iyidir (Meier'in kullanımı), çünkü kullanıcı bu seçeneği belirlemediyse, o sadece onları yedeklemez. Ancak, asıl soru, cihazve bu kimlik, uygulama başına üretilir, hatta her cihaz için tek başına izin verilmez, ve kullanıcı yedekleme seçeneğinin seçilmesine bağlı olduğu için, kullanıcı tercihlerinin ötesinde kullanımları (ör., sınırlı bir deneme için) sınırlıdır. - Carl
Bu, verilerin kaldırılması veya temizlenmesi konusunda çalışmaz. - John Shelley


Ayrıca Wi-Fi bağdaştırıcısının MAC adresini de düşünebilirsiniz. Bu nedenle alındı:

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

İzin gerektirir android.permission.ACCESS_WIFI_STATE tezahürde.

Wi-Fi bağlı olmadığında bile kullanılabilir olduğu bildirildi. Eğer yukarıdaki cevaptan Joe bunu bir çok cihazda denerse, bu hoş olur.

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

NOT: Android 6.x'ten, tutarlı bir sahte mac adresi döndürüyor: 02:00:00:00:00:00


98
2018-06-23 14:27



Bu gerekli android.permission.ACCESS_WIFI_STATE - ohhorob
Onlar var mı? Telefonsuz bir cihaz (AKA tablet) tasarlamayı tercih ederim ... - Seva Alekseyev
Bu sorunun eski olduğunu biliyorum - ama bu harika bir fikir. Uygulamamda BT mac kimliğini kullandım, ancak BT'nin çalışmasını gerektirdiği için. Bunun için geliştirmeye değer bir Android cihazı göster bana WiFi yok. - Jack
WiFi kapalıyken, hemen hemen tüm android cihazlarda kullanılamayacağını anladığınızı düşünüyorum. WiFi'yi kapatmak, aygıtı çekirdek seviyesinde kaldırır. - chrisdowney
@Sanandrea - Köklü bir cihaz üzerinde yüzleşelim, HERŞEY her türlü sahtedir. - ocodo


Oldukça yararlı bilgiler var İşte.

Beş farklı kimlik tipini kapsar:

  1. IMEI (Sadece Telefon kullanımı olan Android cihazlar için; ihtiyaçlar android.permission.READ_PHONE_STATE)
  2. Sözde Benzersiz Kimlik (tüm Android cihazlar için)
  3. Android Kimliği (null olabilir, fabrika ayarlarına sıfırlayabilir, köklü telefon üzerinde değiştirilebilir)
  4. WLAN MAC Adresi dize (ihtiyaçlar) android.permission.ACCESS_WIFI_STATE)
  5. BT MAC Adresi string (Bluetooth özellikli cihazlar, ihtiyaçlar) android.permission.BLUETOOTH)

78
2018-02-08 02:16



Dikkat edilmesi gereken önemli bir nokta (burada ve makalede): Açık olmadıkça WLAN veya BT MAC alamıyorsunuz! Aksi halde WLAN MAC'ın mükemmel bir tanımlayıcı olacağını düşünüyorum. Kullanıcının Wi-Fi'lerini açacağına dair bir garantiniz yok ve bunu kendinize çevirmenin 'uygun' olduğunu düşünmüyorum. - Tom
@Tom yanılıyorsun. WLAN veya BT MAC'ı, kapatıldıklarında bile okuyabilirsiniz. Bununla birlikte, cihazın WLAN veya BT modüllerinin mevcut olduğuna dair bir garanti yoktur. - Marqs
En önemlisi, Yerel WiFi ve Bluetooth MAC adresleri artık kullanılamıyor. AWifiInfo nesnesinin getMacAddress () yöntemi ve BluetoothAdapter.getDefaultAdapter (). GetAddress () yöntemi, her ikisinden de dönüş yapacak: 00: 00: 00: 00: 00 - sarika kate
@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ışacağından bahsetmeyi unuttum. - sarika kate