Android cihazların benzersiz bir kimliği var mı ve eğer öyleyse, Java kullanarak ona erişmenin basit bir yolu nedir?
Android cihazların benzersiz bir kimliği var mı ve eğer öyleyse, Java kullanarak ona erişmenin basit bir yolu nedir?
Yanıtlar:
Settings.Secure#ANDROID_ID
Android 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);
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):
TelephonyManager.getDeviceId()
TelephonyManager.getSimSerialNumber()
getSimSerialNumber()
(beklendiği gibi)ANDROID_ID
ANDROID_ID
ve TelephonyManager.getDeviceId()
- kurulum sırasında bir Google hesabı eklendiği sürece .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;
<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.
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.
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 .
Kullanıcı E-postası - Yazılım
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
veya<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
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
IMEI - Donanım (yalnızca telefonlar, ihtiyaçlar android.permission.READ_PHONE_STATE
)
<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)
WLAN MAC Adresi - Donanım (ihtiyaçlar android.permission.ACCESS_WIFI_STATE
)
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
Bluetooth MAC Adresi - Donanım (Bluetooth özellikli cihazlar, ihtiyaçlar android.permission.BLUETOOTH
)
<uses-permission android:name="android.permission.BLUETOOTH "/>
Sahte Benzersiz Kimlik - Yazılım (tüm Android cihazlar için)
İ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.
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!
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 )
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:
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();
}
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
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.
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!
Build
OS güncellemesinden sonra sınıf değişmez mi? Özellikle API güncellenmişse? Öyleyse, bunun benzersiz olduğunu nasıl garanti edersiniz? (
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:
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;
}
}
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 :).
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_STATE
Manifest'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
android.permission.ACCESS_WIFI_STATE
02:00:00:00:00:00
Burada oldukça yararlı bilgiler var .
Beş farklı kimlik türünü kapsar:
android.permission.READ_PHONE_STATE
)android.permission.ACCESS_WIFI_STATE
)android.permission.BLUETOOTH
)Resmi Android Geliştiricileri Blogunda artık bu konuyla ilgili tam bir makale var: Uygulama Yüklemelerini Tanımlama .
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.
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 .)
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) {
}
ro.serialno
oluşturmak için kullanılan xda geliştirici okudum Settings.Secure.ANDROID_ID
. Yani temel olarak aynı değerin farklı temsilleridir.
ANDROID_ID
elde edilir.
android.os.Build.SERIAL
android.os.Build.SERIAL
Android O'da kullanımdan kaldırılacak, bkz. android-developers.googleblog.com/2017/04/…
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-9489
belirtilen 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 .
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);
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.
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.
9774d56d682e549c
mı?
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();
}
}
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" />
TelephonyManager
ve 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 .
Bu ANDROID_ID
sorunlar üzerinde çalışmak için birçok farklı yaklaşım vardır ( null
bazen veya belirli bir modelin cihazları her zaman aynı kimliği döndürür) artıları ve eksileri ile:
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_ID
yukarıda bahsedilen sorunlar için yedeklerle birlikte kullanılır .
Peki IMEI . Bu, Android veya diğer mobil cihazlar için benzersizdir.
İş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;
}
İ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);
}
}
}
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 "";
}
longId
: o en benzersiz bir tanımlayıcı yapmak, ve bir dosyada saklayınString uuid = UUID.randomUUID().toString();
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.
Başka bir yol, /sys/class/android_usb/android0/iSerial
herhangi 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:
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 .
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;
}
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.
IMEI
Güvenli almak veya kullanmak için aşağıdaki kodu kullanın. ANDROID_ID
alternatif 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);
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_ID
benzersiz 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ı.
Android cihazlarda mevcut Benzersiz Kimlikleri anlamak için. Bu resmi kılavuzu kullanın.
Benzersiz tanımlayıcılar için en iyi uygulamalar:
Cihazları doğrulamak için IMEI, Mac Adresleri, Örnek Kimliği, GUID'ler, SSAID, Reklam Kimliği, Güvenlik Ağı API'sı.
https://developer.android.com/training/articles/user-data-ids
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).
ANDROID_ID
mutlaka okuyun .