Noyob Android qurilma identifikatori bormi?

Android qurilmalarida noyob identifikator bormi va agar shunday bo'lsa, Java yordamida unga kirishning oddiy usuli qanday?


person Tyler    schedule 07.05.2010    source manba
comment
Agar siz ANDROID_ID dan foydalanayotgan bo‘lsangiz, ushbu javobni va .   -  person Dheeraj Vepakomma    schedule 16.01.2013
comment
Sizning yechimingiz bu yerda: stackoverflow.com/a/63481350/7135685   -  person Mujahid Khan    schedule 19.08.2020


Javoblar (50)


Settings.Secure#ANDROID_ID Android identifikatorini < sifatida qaytaradi. a href="https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID" rel="noreferrer">har bir foydalanuvchi uchun noyob 64-bit hex ip.

import android.provider.Settings.Secure;

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

Shuningdek, Noyob identifikatorlar uchun eng yaxshi amaliyotlarni oʻqing: https://developer.android.com/training/articles/user-data-ids

person Anthony Forloney    schedule 07.05.2010
comment
Ba'zida u null bo'lishi ma'lum, u zavod sozlamalariga qaytarilganda o'zgarishi mumkinligi sababli hujjatlashtirilgan. O'zingizning xavf-xataringiz ostida foydalaning va uni ildiz otgan telefonda osongina o'zgartirish mumkin. - person Seva Alekseyev; 23.06.2010
comment
comment
Birinchi javobda xeshda ANDROID_ID dan foydalanishda ehtiyot bo‘lishimiz kerak deb o‘ylayman, chunki u ilova birinchi marta ishga tushirilganda sozlanmasligi, keyinroq o‘rnatilishi yoki hatto nazariy jihatdan o‘zgarishi mumkin, shuning uchun noyob ID o‘zgarishi mumkin. - person ; 05.02.2011
comment
E'tibor bering, ushbu yechimda katta cheklovlar mavjud: android-developers. blogspot.com/2011/03/ - person emmby; 08.04.2011
comment
bu ANDROID_ID faqat Android Tab uchun moʻljallangan, agar siz telefonda ishlasangiz, null boʻladi, agar Tabda ishlasangiz, Noyob ID olishingiz mumkin.-Girish - person Girish Patel; 30.09.2011
comment
ANDROID_ID endi qurilmani noyob tarzda aniqlamaydi (4.2 dan boshlab): stackoverflow.com/a/13465373/150016 - person Tom; 15.12.2012
comment
Agar foydalanuvchi Play Services keshlangan maʼlumotlarini tozalasa, bu ham oʻzgarishi mumkin. androidpolice.com/2013/11/20/ Bunday qilish Google biladigan asosiy identifikatorni o'zgartiradi. qurilmangiz. Serverlarga kelsak, qurilma asosan zavod sozlamalariga qaytarilgan.bu menimcha, ANDROID_ID - testda buni takrorlay olmayman - har qanday holatda ham xabardor bo'lishga arziydi... - person Dori; 06.03.2014
comment
Assalomu alaykum. @Joe javobiga qarang http://stackoverflow.com/a/2853253/1676736 - person Sayed Abolfazl Fatemi; 09.07.2014
comment
Qurilma identifikatorlarini olish uchun getString dan foydalanish tavsiya etilmaydi. NEGA? - person Iman Marashi; 06.04.2017
comment
Android O buni o'zgartiradi android-developers.googleblog.com/2017/04/ - person EpicPandaForce; 12.04.2017
comment
Men ilovamda Android ID dan foydalanuvchilarni aniq aniqlash uchun foydalanmoqdaman, chunki men buni elektron pochta identifikatori bilan muntazam ro'yxatdan o'tishdan ko'ra osonroq deb hisobladim va hozircha bu yechim bilan bog'liq hech qanday muammo topmadim, bizning obunachilarimizdan hech biri shikoyat qilmadi. va biz bilamizki, agar bu yana takrorlansa, qayta tiklash opsiyasi unchalik halokatli bo'lmaydi, barchasi o'ziga xos ilovaga bog'liq, agar ilova qattiq xavfsizlikni talab qilmasa, menimcha, ANDROID ID tashvishga solmasligi mumkin. - person Naga; 22.02.2019
comment
Android Lint qurilma identifikatorlarini olish uchun getString dan foydalanish tavsiya etilmaydi. Tekshiruv haqida ma'lumot: Ushbu qurilma identifikatorlaridan foydalanish yuqori qiymatli firibgarlikning oldini olish va ilg'or telefoniya holatlaridan tashqari tavsiya etilmaydi. Reklamadan foydalanish holatlari uchun AdvertisingIdClient$Info#getId va tahlillar uchun InstanceId#getId dan foydalaning. - person Malwinder Singh; 24.07.2019
comment
@AaronUllal uzr biroz kechikdim, yo'q men shunday deb o'ylamayman, sozlamalar ostida Telefon haqida men tekshirgan android telefonlardan birida android versiyasi, imei va hokazolar bor, ehtimol bu Ilovalarga qaraganda foydalanuvchilar uchun unchalik ahamiyatli emas. - person Naga; 03.09.2019
comment
Bu savolga javobning 2020 versiyasi qanday? Albatta, narsalar o'zgargan. - person André; 24.07.2020
comment
Ushbu identifikator kalit do'koni faylining o'zgarishi bilan o'zgaradi. Men o'ziga xosroq narsani qidirdim. Bitta qurilma uchun doimiy qoladigan id. - person Syed Arsalan Kazmi; 20.11.2020
comment
@SyedArsalanKazmi men fcm tokenini tanladim - person famfamfam; 05.03.2021

YANGILASH: Androidning soʻnggi versiyalarida ANDROID_ID bilan bogʻliq koʻplab muammolar hal qilindi va men bu yondashuvni endi kerak emas deb hisoblayman. Entoni javobiga qarang.

To'liq ma'lumot: mening ilovam dastlab quyidagi yondashuvdan foydalangan, ammo endi bu yondashuvdan foydalanmaydi va endi biz Android Developer Blog yozuvi emmby javobi havolasi (ya'ni , UUID#randomUUID() yaratish va saqlash).


Bu savolga ko'plab javoblar mavjud, ularning aksariyati faqat bir muncha vaqt ishlaydi va afsuski, bu etarli emas.

Mening sinovlarim asosida (barcha telefonlar, kamida bittasi yoqilmagan):

  1. Sinov qilingan barcha qurilmalar TelephonyManager.getDeviceId() qiymatini qaytardi
  2. Barcha GSM qurilmalari (hammasi SIM karta bilan tekshirilgan) TelephonyManager.getSimSerialNumber() qiymatini qaytardi
  3. Barcha CDMA qurilmalari getSimSerialNumber() uchun null qiymatini qaytardi (kutilganidek)
  4. Google hisobi qoʻshilgan barcha qurilmalar ANDROID_ID qiymatini qaytardi
  5. Barcha CDMA qurilmalari ANDROID_ID va TelephonyManager.getDeviceId() uchun bir xil qiymatni (yoki bir xil qiymatdan olingan) qaytardi -- agarki sozlash vaqtida Google hisobi qo'shilgan bo'lsa.
  6. SIM kartasiz GSM qurilmalarini, Google hisobi qo‘shilmagan GSM qurilmasini yoki samolyot rejimidagi qurilmalarni hali sinab ko‘rish imkonim yo‘q edi.

Shunday qilib, agar siz qurilmaning o'ziga xos bo'lishini istasangiz, TM.getDeviceId() bu etarli bo'lishi kerak. Shubhasiz, ba'zi foydalanuvchilar boshqalarga qaraganda ko'proq paranoyakdir, shuning uchun 1 yoki undan ko'p identifikatorni xeshlash foydali bo'lishi mumkin, shunda satr hali ham qurilma uchun deyarli yagona bo'lib qoladi, lekin foydalanuvchining haqiqiy qurilmasini aniq belgilamaydi. Masalan, UUID bilan birlashtirilgan String.hashCode() dan foydalanish:

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

Quyidagi kabi narsaga olib kelishi mumkin: 00000000-54b3-e7c7-0000-000046bffd97

Bu men uchun etarlicha yaxshi ishlaydi.

Richard quyida aytib o'tganidek, TelephonyManager xususiyatlarini o'qish uchun ruxsat kerakligini unutmang, shuning uchun buni manifestingizga qo'shing:

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

kutubxonalarni import qilish

import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
person Joe    schedule 17.05.2010
comment
Telefonga asoslangan identifikator planshet qurilmalarida bo'lmaydi, shunday emasmi? - person Seva Alekseyev; 23.06.2010
comment
Shuning uchun men ko'pchilik har doim ham ishlamaydi dedim :) Men bu savolga barcha qurilmalar, barcha turdagi qurilmalar va barcha apparat konfiguratsiyalari uchun ishonchli javobni hali ko'rmadim. Shuning uchun bu savolni boshlash uchun. Buning hech qanday yakuniy yechim yo'qligi aniq. Alohida qurilma ishlab chiqaruvchilari qurilmaning seriya raqamlariga ega bo'lishi mumkin, ammo ulardan foydalanish biz uchun ochiq emas va bu shart emas. Shunday qilib, bizda mavjud bo'lgan narsa qoladi. - person Joe; 29.06.2010
comment
Ko'proq testdan so'ng javobingizni yangilaysizmi? Bu juda qiziq bo'lardi. - person liori; 31.01.2011
comment
Kod namunasi ajoyib ishlaydi. Manifest fayliga <uses-permission android:name="android.permission.READ_PHONE_STATE" /> qo'shishni unutmang. Agar ma'lumotlar bazasida saqlansa, qaytarilgan satr 36 belgidan iborat. - person Richard; 28.02.2011
comment
E'tibor bering, ushbu yechimda katta cheklovlar mavjud: android-developers. blogspot.com/2011/03/ - person emmby; 08.04.2011
comment
Ma'lumot uchun, TelephonyManager.getDeviceId() mening Xoom-da haqiqiy noyob identifikatorni qaytaradi, shuning uchun bu planshetlar uchun ham ishlaydi. - person MusiGenesis; 21.04.2011
comment
Bu javob eskirgan va ishlatilmasligi kerak. Qurilmalarni kuzatmang, o'rnatishlarni kuzating! - person softarn; 17.07.2011
comment
@softarn: Ishonamanki, siz aytmoqchi bo'lgan narsa emmby allaqachon bog'langan Android Developer blogi bo'lib, siz nima demoqchi ekanligingizni tushuntirib beradi, shuning uchun uning o'rniga uning sharhiga shunchaki yuqori ovoz berishingiz kerak edi. Qanday bo'lmasin, Emmby o'z javobida ta'kidlaganidek, hatto blog ma'lumotlari bilan ham muammolar mavjud. Savol noyob DEVICE identifikatorini (o'rnatish identifikatori emas) so'raydi, shuning uchun men sizning bayonotingizga qo'shilmayman. Blog siz xohlagan narsa qurilmani kuzatish uchun shart emas deb taxmin qilmoqda, holbuki savol aynan shuni so'raydi. Aks holda blogga qo'shilaman. - person Joe; 22.07.2011
comment
Menimcha, bu usulda bitta jiddiy kamchilik bor. Bu SIM karta ma'lumotlariga bog'liq, foydalanuvchilar ba'zan Parvoz rejimiga o'tishadi = SIM ulanmagan. Ushbu stsenariyda, ehtimol, Android identifikatorini olish uchun sizda qayta tiklash mexanizmi bo'lishi kerak. - person Daniel Novak; 04.08.2011
comment
@Daniel Novak: adolatli nuqta. Mening ishim uchun bu muhim emas edi, chunki identifikator API aloqasida ishlatiladi, shuning uchun Parvoz rejimi = ilova yo'q :) Biz buni shunday ishlab chiqdik, masalan, agar foydalanuvchi SIM kartalarini almashtirsa, biz qasddan qurilma identifikatorini xohlaymiz. boshqacha bo'lish. Shubhasiz, bu hamma uchun bo'lmaydi, shuning uchun buni ko'rsatganingiz uchun tashakkur. - person Joe; 22.08.2011
comment
Men buni hali hech kim keltirmaganiga hayronman, lekin kod misoli ba'zi hollarda juda achinarli bo'lishi mumkin - bu telefon, masalan, parvoz rejimida yoki yo'qligiga qarab, boshqa identifikatorni qaytaradi, chunki Agar qurilma GSM tarmog'i o'chirilgan bo'lsa, simSerialNumber null bo'ladi. Agar sizda noyob identifikatorga tayanadigan, lekin tarmoqqa emas, balki faqat internetga muhtoj bo'lgan ilovangiz bo'lsa, telefonning joriy tarmoq holatidan qat'i nazar, kod har doim bir xil identifikatorni qaytarishini ta'minlash yaxshiroqdir. - person Mathias; 20.12.2011
comment
Men ushbu kodni 6 oy davomida ishlatganman. U noyob identifikatorni yaratmaydi. Men barchangizga ushbu koddan foydalanishni tavsiya etmayman. Hozir men ushbu postdagi koddan foydalanmoqdaman: stackoverflow.com/a/17625641/365229 - person Behrouz.M; 18.06.2015
comment
Ushbu kodni ishlatmaslikni qat'iy tavsiya qilaman. Unda bir nechta muhim xatolar mavjud: Birinchidan, telefoniya ham, Android identifikatori ham mavjudligi kafolatlanmaydi va ikkalasi ham mavjud bo'lmasa, sizning qurilmalaringiz faqat ularning modeliga ko'ra xaritalanadi. Ikkinchidan va bundan ham muhimi, Android ID hesh-kodidan foydalanganda siz raqamning 64 bitli qatorli ko'rinishini 32 bitli raqamga aylantirasiz va shu bilan siz juda ko'p noyoblikni yo'qotasiz. - person lavuy; 30.07.2015
comment
IMEI identifikatori endi Android 10 va undan yuqori versiyalarda ishlamaydi - person abss; 13.07.2021

#Oxirgi yangilangan: 6/2/15


Noyob identifikator, Google ishlab chiquvchi blogi va Android hujjatlarini yaratish haqidagi har bir Stack Overflow postini o‘qib chiqqanimdan so‘ng, “Pseudo ID” eng yaxshi variant deb o‘ylayman.

Asosiy muammo: Uskuna va dasturiy ta'minot

Uskuna

  • Foydalanuvchilar apparat, Android plansheti yoki telefonini oʻzgartirishi mumkin, shuning uchun uskunaga asoslangan noyob identifikatorlar FOYDALANUVCHILARNI KUZATISH uchun yaxshi gʻoya emas.
  • TRACKING HARDWARE uchun bu ajoyib g'oya

Dasturiy ta'minot

  • Foydalanuvchilar, agar ular ildiz otgan bo'lsa, ROMni o'chirishi/o'zgartirishi mumkin
  • Siz foydalanuvchilarni turli platformalarda kuzatishingiz mumkin (iOS, Android, Windows va Web)
  • INDIVIDUAL FOYDALANUVCHIni uning roziligi bilan kuzatmoqchi bo'lgan eng yaxshi narsa shunchaki tizimga kirish (OAuth yordamida muammosiz qilish)dir.

#Android bilan umumiy parchalanish

###- API ›= 9/10 (Android qurilmalarining 99,5%) uchun o‘ziga xoslik kafolati (ildizli qurilmalar ham kiradi) ###- Qo‘shimcha ruxsatlar yo‘q

Psuedo kodi:

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)

barcha variantlarimizni joylaganingiz uchun @stansultga rahmat (ushbu Stack Overflow savolida).

##Variantlar ro'yxati - ularni nima uchun / nima uchun ishlatmaslik sabablari:

  • Foydalanuvchi elektron pochtasi - Dasturiy ta'minot

  • Foydalanuvchi elektron pochta manzilini o'zgartirishi mumkin - YUQORI dargumon

  • API 5+ <uses-permission android:name="android.permission.GET_ACCOUNTS" /> yoki

  • API 14+ <uses-permission android:name="android.permission.READ_PROFILE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> (Android qurilmasini qanday olish mumkin asosiy elektron pochta manzili)

  • Foydalanuvchi telefon raqami - Dasturiy ta'minot

  • Foydalanuvchilar telefon raqamlarini o'zgartirishi mumkin - YUQORI dargumon

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

  • IMEI - Uskuna (faqat telefonlar uchun android.permission.READ_PHONE_STATE kerak)

  • Ko'pchilik foydalanuvchilar ruxsatnomada Telefon qo'ng'iroqlari yozilganidan nafratlanadi. Ba'zi foydalanuvchilar noto'g'ri baho berishadi, chunki ular sizning shaxsiy ma'lumotlaringizni o'g'irlayotganingizga ishonishadi, chunki siz faqat qurilma o'rnatilishini kuzatishni xohlaysiz. Siz ma'lumot to'playotganingiz aniq.

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

  • Android ID - Uskuna (nol bo'lishi mumkin, zavod sozlamalariga qaytarilganda o'zgarishi mumkin, ildiz otgan qurilmada o'zgartirilishi mumkin)

  • U "null" bo'lishi mumkinligi sababli, biz "null" ni tekshirishimiz va uning qiymatini o'zgartirishimiz mumkin, ammo bu endi u noyob bo'lmaydi.

  • Agar sizda zavod sozlamalarini tiklash qurilmasi bo'lgan foydalanuvchi bo'lsa, qiymat ildiz otgan qurilmada o'zgargan yoki o'zgartirilgan bo'lishi mumkin, shuning uchun foydalanuvchi o'rnatishlarini kuzatayotgan bo'lsangiz, takroriy yozuvlar bo'lishi mumkin.

  • WLAN MAC manzili - Uskuna (kerak android.permission.ACCESS_WIFI_STATE)

  • Bu ikkinchi eng yaxshi variant bo'lishi mumkin, lekin siz hali ham to'g'ridan-to'g'ri foydalanuvchidan keladigan noyob identifikatorni yig'ib va ​​saqlayapsiz. Bu siz ma'lumot to'playotganingiz aniq.

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

  • Bluetooth MAC manzili - Uskuna (Bluetooth bilan jihozlangan qurilmalar uchun android.permission.BLUETOOTH kerak)

  • Bozordagi aksariyat ilovalar Bluetooth-dan foydalanmaydi, shuning uchun ilovangiz Bluetooth-dan foydalanmasa va siz buni qo'shsangiz, foydalanuvchi shubhalanishi mumkin.

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

  • Pseudo-unique ID - dasturiy ta'minot (barcha Android qurilmalar uchun)

  • Juda mumkin, to'qnashuvlar bo'lishi mumkin - Quyida e'lon qilingan usulimni ko'ring!

  • Bu sizga shaxsiy hech narsa olmasdan foydalanuvchidan "deyarli noyob" identifikatorga ega bo'lish imkonini beradi. Qurilma ma'lumotlaridan o'zingizning anonim identifikatoringizni yaratishingiz mumkin.


Ruxsatlardan foydalanmasdan noyob identifikatorni olishning "mukammal" usuli yo'qligini bilaman; ammo, ba'zan biz faqat, albatta, qurilma o'rnatish kuzatish kerak. Noyob identifikatorni yaratish haqida gap ketganda, biz qo'shimcha ruxsatlardan foydalanmasdan faqat Android API bizga beradigan ma'lumotlar asosida "soxta noyob identifikator" yaratishimiz mumkin. Shunday qilib, biz foydalanuvchiga hurmat ko'rsatishimiz va yaxshi foydalanuvchi tajribasini taklif qilishga harakat qilishimiz mumkin.

Pseudo-noyob identifikator bilan siz haqiqatan ham shunga o'xshash qurilmalar mavjudligiga asoslanib, dublikatlar bo'lishi mumkinligiga duch kelasiz. Uni yanada noyob qilish uchun birlashtirilgan usulni sozlashingiz mumkin; biroq, ba'zi ishlab chiquvchilar qurilma o'rnatilishini kuzatishlari kerak va bu o'xshash qurilmalarga asoslangan hiyla yoki ishlashni amalga oshiradi.

##API ›= 9:

Agar ularning Android qurilmasi API 9 yoki undan yuqori boʻlsa, “Build.SERIAL” maydoni tufayli bu noyob boʻlishi kafolatlanadi.

ESDA OLING, siz texnik jihatdan faqat taxminan 0,5% foydalanuvchilardan API ‹ 9ga ega. Shunday qilib, siz qolgan narsalarga e'tibor qaratishingiz mumkin: Bu foydalanuvchilarning 99,5% ni tashkil qiladi!

##API ‹ 9:

Agar foydalanuvchining Android qurilmasi API 9 dan past bo'lsa; umid qilamanki, ular zavod sozlamalarini tiklamagan va ularning "Secure.ANDROID_ID" saqlanadi yoki "null" bo'lmaydi. (qarang: http://developer.android.com/about/dashboards/index.html)

##Agar hammasi bajarilmasa:

Agar barchasi bajarilmasa, agar foydalanuvchi API 9 dan pastroq bo‘lsa (Gingerbread’dan pastroq), qurilmasini asl holatiga qaytargan bo‘lsa yoki “Secure.ANDROID_ID” “null” qiymatini qaytarsa, qaytarilgan identifikator faqat Android qurilmasi ma’lumotlariga asoslanadi. . Bu erda to'qnashuvlar sodir bo'lishi mumkin.

O'zgarishlar:

  • “Android.SECURE_ID” olib tashlandi, chunki zavod sozlamalari qiymat o‘zgarishiga olib kelishi mumkin
  • APIda o'zgartirish uchun kod tahrirlangan
  • Pseudo-ni o'zgartirdi

Iltimos, quyidagi usulni ko'rib chiqing:

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

#Yangi (reklamali ilovalar va Google Play xizmatlari uchun):

Google Play Developer konsolidan:

2014-yil 1-avgustdan boshlab Google Play Developer dasturi siyosati har qanday reklama maqsadlarida boshqa doimiy identifikatorlar o‘rniga reklama identifikatoridan foydalanish uchun butunlay yangi ilovalarni yuklash va yangilashni talab qiladi. Ko'proq ma'lumot olish

Amalga olish:

Ruxsat:

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

Manba/Hujjatlar:

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

##Muhim:

Google Play xizmatlari mavjud boʻlganda, reklama identifikatori reklama maqsadlarida (masalan, Settings.Secureʼda ANDROID_IDʼdan foydalanish) boshqa identifikatorlardan foydalanishni toʻliq almashtirishi moʻljallangan. Google Play xizmatlaridan foydalanish mumkin bo'lmagan holatlar getAdvertisingIdInfo() tomonidan yuborilgan GooglePlayServicesNotAvailableException bilan ko'rsatilgan.

##Ogohlantirish, foydalanuvchilar quyidagi sozlamalarni tiklashlari mumkin:

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

Men ma'lumot olgan har bir havolaga havola qilishga harakat qildim. Agar siz etishmayotgan bo'lsangiz va qo'shishingiz kerak bo'lsa, izoh qoldiring!

Google Player xizmatlari InstanceID

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

person Jared Burrows    schedule 12.07.2013
comment
sharhlarni yuborish uchun ilovamda sizning usulingizdan foydalandim. yomon xabarim bor. afsuski, PsuedoID butunlay noyob emas. mening serverim 5 ID uchun 100 dan ortiq va deyarli 30 ID uchun 30 dan ortiq qayd etdi. eng ko'p takrorlanadigan identifikatorlar "ffffffff-fc8f-6093-ffff-ffffd8" (159 ta yozuv) va "ffffffff-fe99-b334-ffff-ffffef" (154 marta). Shuningdek, vaqt va sharhlarga asoslanib, turli xalqlar borligi aniq. jami rekordlar hozirgacha 10 000 tani tashkil etadi. iltimos, nima uchun bu sodir bo'lganini menga xabar bering. tanklar. - person hojjat reyhane; 17.03.2015
comment
Men buni 1,5 yil oldin yozganman. Nima uchun bu siz uchun yagona emasligiga ishonchim komil emas. Siz reklama identifikatorini sinab ko'rishingiz mumkin. Agar yo'q bo'lsa, siz o'zingizning yechimingizni topishingiz mumkin. - person Jared Burrows; 17.03.2015
comment
sorta..Agar siz savolni ko'rib chiqsangiz va bu haqda o'z fikringizni bildirsangiz juda minnatdorman - person Durai Amuthan.H; 29.04.2015
comment
@ user1587329 Rahmat. Men buni hamma uchun yangilab turishga harakat qilaman. Bu savol apparat va dasturiy ta'minot va o'zaro faoliyat platforma haqida gap ketganda qiyin. - person Jared Burrows; 06.05.2015

Deyv Uebb ta'kidlaganidek, Android Developers blogida maqola bor buni qamrab oladi. Ularning afzal ko'rgan yechimi qurilmalardan ko'ra ilovalarni o'rnatishni kuzatishdir va bu ko'pchilik foydalanish holatlarida yaxshi ishlaydi. Blog posti sizga buni amalga oshirish uchun kerakli kodni ko'rsatadi va men uni tekshirishni tavsiya qilaman.

Biroq, blog postida sizga ilovani o'rnatish identifikatori emas, balki qurilma identifikatori kerak bo'lsa, echimlarni muhokama qilish davom etadi. Agar kerak bo'lsa, ba'zi narsalar bo'yicha qo'shimcha tushuntirish olish uchun Google'dagi kimdir bilan gaplashdim. Men yuqorida aytib o'tilgan blog postida EMAS qurilma identifikatorlari haqida bilib oldim:

  • ANDROID_ID afzal qilingan qurilma identifikatoridir. ANDROID_ID Android ‹=2.1 yoki >=2.3 versiyalarida juda ishonchli. Faqat 2.2-da postda aytib o'tilgan muammolar mavjud.
  • Bir nechta ishlab chiqaruvchilarning bir nechta qurilmalari 2.2.1-dagi ANDROID_ID xatosidan ta'sirlangan.
  • Aniqlashimcha, barcha zararlangan qurilmalar bir xil ANDROID_IDga ega, ya'ni 9774d56d682e549c. Bu emulyator tomonidan bildirilgan bir xil qurilma identifikatoridir, btw.
  • Google OEM’lar ko‘p yoki ko‘pchilik qurilmalari uchun muammoni tuzatgan deb hisoblaydi, biroq men 2011-yil aprel oyi boshidan boshlab, hech bo‘lmaganda ANDROID_ID buzilgan qurilmalarni topish hali ham oson ekanligini tasdiqladim.

Google tavsiyalariga asoslanib, men har bir qurilma uchun noyob UUID ni yaratadigan sinfni joriy qildim, agar kerak bo'lsa, ANDROID_ID ni urug' sifatida ishlatib, kerak bo'lganda TelephonyManager.getDeviceId() ga qaytadi va agar bu muvaffaqiyatsiz bo'lsa, tasodifiy yaratilgan noyob UUID ga murojaat qildim. bu ilovalarni qayta ishga tushirishda (ilovani qayta o'rnatishda emas) saqlanib qoladi.

Esda tutingki, qurilma identifikatorida qayta tiklanishi kerak bo'lgan qurilmalar uchun noyob ID BO'LADI zavod sozlamalariga qaytarilganda ham saqlanib qoladi. Bu xabardor bo'lishi kerak bo'lgan narsa. Zavod sozlamalarini tiklash sizning noyob identifikatoringizni qayta tiklashiga ishonch hosil qilishingiz kerak bo'lsa, qurilma identifikatori o'rniga to'g'ridan-to'g'ri tasodifiy UUID ga qaytish haqida o'ylashingiz mumkin.

Shunga qaramay, ushbu kod ilovani o'rnatish identifikatori emas, balki qurilma identifikatori uchundir. Ko'pgina hollarda, ilovani o'rnatish identifikatori siz qidirayotgan narsadir. Ammo agar sizga qurilma identifikatori kerak bo'lsa, unda quyidagi kod sizga mos kelishi mumkin.

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;
    }
}
person emmby    schedule 11.04.2011
comment
Har xil identifikatorlarni bir xil o'lchamda bo'lishi uchun xeshlash kerak emasmi? Bundan tashqari, shaxsiy ma'lumotlarni tasodifan oshkor qilmaslik uchun qurilma identifikatorini xeshlash kerak. - person Steve Pomeroy; 12.04.2011
comment
Shuningdek, konfiguratsiyasi qurilma identifikatoridan foydalanishga olib keladigan qurilma identifikatorni foydalanuvchiga emas, balki qurilmaga bog'laydi. Bu identifikator zavod sozlamalarini tiklashdan omon qoladi, bu potentsial yomon bo'lishi mumkin. Ehtimol, qurilma identifikatori oxirgi zavod sozlamalarini tiklash vaqti haqida xabar beruvchi biror narsa bilan xeshlangan bo'lishi mumkinmi? - person Steve Pomeroy; 12.04.2011
comment
Yaxshi fikrlar, Stiv. Men har doim UUIDni qaytarish uchun kodni yangiladim. Bu a) yaratilgan identifikatorlar har doim bir xil o'lchamda bo'lishini va b) android va qurilma identifikatorlari shaxsiy ma'lumotlarning tasodifan oshkor etilishini oldini olish uchun qaytarilgunga qadar xeshlanganligini ta'minlaydi. Shuningdek, qurilma identifikatori zavod sozlamalarini tiklashda saqlanib qolishi va bu baʼzi foydalanuvchilar uchun istalmagan boʻlishi mumkinligini taʼkidlash uchun tavsifni yangiladim. - person emmby; 12.04.2011
comment
Men siz noto'g'ri ekanligingizga ishonaman; afzal qilingan yechim qurilma identifikatorlarini emas, balki o'rnatishlarni kuzatishdir. Sizning kodingiz blog postidagiga qaraganda ancha uzunroq va murakkabroq va bu menga hech qanday qiymat qo'shishi aniq emas. - person Tim Bray; 12.04.2011
comment
Yaxshi fikr, men foydalanuvchilarga qurilma identifikatorlari o'rniga ilovalarni o'rnatish identifikatorlaridan foydalanishni tavsiya qilish uchun sharhni yangiladim. Biroq, menimcha, bu yechim o'rnatish identifikatoriga emas, balki qurilmaga muhtoj bo'lgan odamlar uchun hali ham qimmatlidir. - person emmby; 12.04.2011
comment
ANDROID_ID zavod sozlamalariga qaytarilganda oʻzgarishi mumkin, shuning uchun u qurilmalarni ham aniqlay olmaydi - person Samuel; 19.05.2011
comment
Xuddi shu javobingizda ta'kidlaganimdek, bu yerda bor Jarayonlar bo'ylab bir xil yaratilgan UUIDni olishingizga kafolat yo'q - SharedPrefs nusxasi mahalliy ! - person Mr_and_Mrs_D; 18.09.2013

Bu yil Reto Meyer Google I/O taqdimotida noyob identifikatorni olish uchun ishlatgan kod. foydalanuvchi:

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

Agar siz buni bulutga afzalliklarni yuborish uchun zaxira strategiyasi bilan birlashtirsangiz (shuningdek, Reto suhbat uchun sizda foydalanuvchi bilan bog'langan va qurilma o'chirilgandan yoki hatto almashtirilgandan keyin ham yopishib oladigan identifikatoringiz bo'lishi kerak. Men bundan tahlilda foydalanishni rejalashtirmoqdaman. oldinga (boshqacha aytganda, men hali buni qilmaganman :).

person Anthony Nolan    schedule 28.10.2011
comment
Oʻchirish va qayta oʻrnatishdan keyin ham davom etish uchun noyob identifikator kerak boʻlmasa, ajoyib variant (masalan, gʻalaba qozonish uchun uchta imkoniyatga ega boʻlgan reklama tadbiri/oʻyin, davr). - person Kyle Clegg; 16.05.2012
comment
Meier taqdimoti Android Backup Manager-dan foydalanishga tayanadi, bu esa o'z navbatida foydalanuvchi ushbu xususiyatni yoqishni tanlashiga bog'liq. Bu ilova foydalanuvchisi afzalliklari uchun juda mos keladi (Meierdan foydalanish), chunki agar foydalanuvchi ushbu variantni tanlamagan bo'lsa, u shunchaki zaxira nusxasini olmaydi. Biroq, asl savol qurilma uchun noyob identifikatorni yaratish haqida bo'lib, bu identifikator har bir qurilma u yoqda tursin, har bir o'rnatish uchun emas, balki har bir ilova uchun ishlab chiqariladi va bu foydalanuvchi tanlagan qurilmaga tayanadi. zaxira opsiyasi, uning foydalanuvchi imtiyozlaridan tashqari foydalanishlari (masalan, cheklangan sinov muddati uchun) cheklangan. - person Carl; 22.12.2012
comment
Bu oʻchirish yoki maʼlumotlarni tozalashda ishlamaydi. - person John Shelley; 02.09.2014
comment
juda yomon yechim - person famfamfam; 23.02.2021
comment
Menimcha, bu yaxshi yechim, agar siz o'chirib tashlasangiz, qurilmada va serverda noyob identifikator mavjud. Siz uni mijozning elektron pochtasi bilan saqlab qo'yganingizga ishonch hosil qilishingiz mumkin, shunda u yopishadi;-p - person vin shaba; 25.04.2021

Shuningdek, siz Wi-Fi adapterining MAC manzilini ko'rib chiqishingiz mumkin. Quyidagi tarzda olindi:

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

Manifestda android.permission.ACCESS_WIFI_STATE ruxsat talab qiladi.

Wi-Fi ulanmagan bo'lsa ham foydalanish mumkinligi xabar qilingan. Agar yuqoridagi javobdan Jou buni o'zining ko'plab qurilmalarida sinab ko'rsa, bu yaxshi bo'lardi.

Ba'zi qurilmalarda Wi-Fi o'chirilgan bo'lsa, u ishlamaydi.

QAYD: Android 6.x-dan u doimiy soxta mac manzilini qaytaradi: 02:00:00:00:00:00

person Seva Alekseyev    schedule 23.06.2010
comment

Muammo shundaki, sizning XML standart nom maydonidan foydalanmoqda, ammo XSD maqsadli nom maydonini belgilaydi. Agar siz XML-da <BadManifest xmlns="http://www.engagesoftware.com/Schemas/EngageManifest"> ni belgilasangiz, tekshiruvchi xatolar haqida kutilganidek xabar berishini bilib olishingiz kerak. Aks holda, u XML nom maydonini tanimaganligi sababli, uni e'tiborsiz qoldiradi.

- person ohhorob; 01.11.2010
comment
Wi-Fi-siz qurilmalar haqida nima deyish mumkin? - person Axarydax; 22.12.2010
comment
Bilaman, bu savol eski - lekin bu ajoyib g'oya. Men ilovamda BT mac identifikatoridan foydalandim, lekin u BT ishlashini talab qilgani uchungina. Menga Wi-Fi YO'Q Android qurilmasini ko'rsating. - person Jack; 30.08.2011
comment
O'ylaymanki, deyarli barcha Android qurilmalarida Wi-Fi o'chirilgan bo'lsa, u mavjud emasligini bilib olasiz. Wi-Fi-ni o'chirish qurilmani yadro darajasida olib tashlaydi. - person chrisdowney; 22.05.2012
comment
@Sanandrea - tan olaylik, ildiz otgan qurilmada HAMMA NARSANI soxtalashtirish mumkin. - person ocodo; 04.09.2013
comment
Google blogida aytilganidek, MAC yaxshi variant emas. Qurilmaning WiFi yoki Bluetooth uskunasidan Mac manzilini olish mumkin bo'lishi mumkin. Biz buni noyob identifikator sifatida ishlatishni tavsiya etmaymiz. Boshlash uchun barcha qurilmalarda Wi-Fi mavjud emas. Bundan tashqari, agar WiFi yoqilmagan bo'lsa, apparat Mac manzili haqida xabar bermasligi mumkin. android-developers.blogspot.com.es/2011/ 03/ - person jiahao; 01.06.2014
comment
Android M da WiFi MAC manziliga kirish bloklangan: stackoverflow.com/questions/31329733/ - person breez; 22.12.2015
comment
Eng muhimi, Mahalliy WiFi va Bluetooth MAC manzillari endi mavjud emas. aWifiInfo ob'ektining getMacAddress() usuli va BluetoothAdapter.getDefaultAdapter().getAddress() usuli endi 02:00:00:00:00:00 ga qaytadi. - person sarika kate; 30.03.2016
comment
ba'zi qurilmalarda Wi-Fi bo'lmasligi mumkin (shaxsan tajribali) - person Alberto M; 31.05.2016
comment
Android 6.x dan doimiy soxta Mac manzilini qaytaradi: 02:00:00:00:00:00 - person Behrouz.M; 10.07.2016
comment
android 10+ mac manzilini randomize, shuning uchun men bu yechimni tavsiya qilmayman - person Hari Shankar S; 09.11.2020

Juda foydali ma'lumot bu yerda.

U besh xil ID turini qamrab oladi:

  1. IMEI (faqat Telefon ishlatadigan Android qurilmalari uchun; android.permission.READ_PHONE_STATE kerak)
  2. Pseudo-unique ID (barcha Android qurilmalar uchun)
  3. Android ID (null boʻlishi mumkin, zavod sozlamalariga qaytarilgandan soʻng oʻzgarishi mumkin, ildiz otgan telefonda oʻzgartirilishi mumkin)
  4. WLAN MAC manzili qatori (kerak: android.permission.ACCESS_WIFI_STATE)
  5. BT MAC manzili qatori (Bluetooth'li qurilmalar uchun android.permission.BLUETOOTH kerak)
person stansult    schedule 08.02.2012
comment
Muhim nuqta qoldirilmagan (bu erda va maqolada): agar ular yoqilgan bo'lmasa, siz WLAN yoki BT MAC-ni ololmaysiz! Aks holda, WLAN MAC mukammal identifikator bo'ladi deb o'ylayman. Sizda foydalanuvchi hech qachon Wi-Fi-ni yoqishiga kafolat yo'q va men uni o'zingiz yoqishingiz "noto'g'ri" deb o'ylamayman. - person Tom; 08.10.2012
comment
@Tom siz noto'g'risiz. WLAN yoki BT MAC o'chirilgan bo'lsa ham o'qishingiz mumkin. Biroq, qurilmada WLAN yoki BT modullari mavjudligiga kafolat yo'q. - person Marqs; 04.08.2014
comment
Eng muhimi, Mahalliy WiFi va Bluetooth MAC manzillari endi mavjud emas. aWifiInfo ob'ektining getMacAddress() usuli va BluetoothAdapter.getDefaultAdapter().getAddress() usuli endi 02:00:00:00:00:00 ga qaytadi. - person sarika kate; 30.03.2016
comment
@sarikakate Bu faqat 6.0 Marshmallow va undan yuqori versiyalarda to'g'ri ... U hali ham 6.0 Marshmallow ostida kutilganidek ishlaydi. - person Smeet; 13.04.2016

Bu oddiy savol, oddiy javob yo'q.

Bundan tashqari, bu erda mavjud bo'lgan barcha javoblar eskirganmi yoki ishonchsizmi.

Shunday qilib, agar siz 2020-yilda yechim izlayotgan bo'lsangiz.

Bu erda bir nechta narsalarni yodda tutish kerak:

Uskunaga asoslangan barcha identifikatorlar (SSAID, IMEI, MAC va boshqalar) butun dunyo bo'ylab faol qurilmalarning 50% dan ortig'ini tashkil etuvchi Google-ga tegishli bo'lmagan qurilmalar (Pixels va Nexus-dan tashqari hamma narsa) uchun ishonchsizdir. Shuning uchun rasmiy Android identifikatorlari bo‘yicha eng yaxshi amaliyotlar aniq ko‘rsatilgan:

SSAID (Android ID), IMEI, MAC manzili va h.k. kabi apparat identifikatorlaridan foydalanmang...

Bu yuqoridagi javoblarning aksariyatini bekor qiladi. Shuningdek, turli xil android xavfsizlik yangilanishlari tufayli, ulardan ba'zilari foydalanuvchi tomonidan rad etilishi mumkin bo'lgan yangiroq va qattiqroq ish vaqti ruxsatnomalarini talab qiladi.

Misol sifatida, yuqorida aytib o'tilgan barcha WIFI-ga asoslangan texnikalarga ta'sir qiluvchi CVE-2018-9489.

Bu esa o'sha identifikatorlarni nafaqat ishonchsiz, balki ko'p hollarda ularga kirish imkonsiz qiladi.

Shunday qilib, oddiyroq so'zlar bilan aytganda: bu usullardan foydalanmang.

Bu erda ko'plab boshqa javoblar AdvertisingIdClient dan foydalanishni taklif qiladi, bu ham mos kelmaydi, chunki uning dizayni faqat reklama profilini yaratish uchun ishlatilishi kerak. Bu rasmiy ma'lumotnomada ham aytilgan.

Foydalanuvchi profilini yaratish yoki reklamalardan foydalanish holatlari uchun faqat reklama identifikatoridan foydalaning

Bu nafaqat qurilmani identifikatsiyalashda ishonchsiz, balki reklamani kuzatish bo'yicha foydalanuvchi maxfiyligi siyosati, unda foydalanuvchi istalgan vaqtda uni qayta o'rnatishi yoki bloklashi mumkinligi aniq ko'rsatilgan.

Shuning uchun uni ham ishlatmang.

Istalgan statik global noyob va ishonchli qurilma identifikatoriga ega bo'lolmaysiz. Androidning rasmiy ma'lumotnomasi quyidagilarni taklif qiladi:

Toʻlov firibgarligining oldini olish va telefoniyadan tashqari, iloji boʻlsa, FirebaseInstanceId yoki shaxsiy saqlangan GUIDdan foydalaning.

Bu qurilmada ilovalarni o'rnatish uchun noyobdir, shuning uchun foydalanuvchi dasturni o'chirib tashlaganida - u o'chib ketadi, shuning uchun u 100% ishonchli emas, lekin bu keyingi eng yaxshi narsa.

FirebaseInstanceId dan foydalanish uchun gradleingizga oxirgi firebase-messaging bog‘liqligini qo‘shing.

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

Va fonda quyidagi koddan foydalaning:

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

Agar siz qurilma identifikatorini masofaviy serveringizda saqlashingiz kerak bo'lsa, uni avvalgidek saqlamang (oddiy matn), balki tuz bilan xash.

Bugungi kunda bu nafaqat eng yaxshi amaliyot, balki uni GDPR - identifikatorlar< ga muvofiq qonun bo'yicha bajarishingiz kerak. /a> va shunga o'xshash qoidalar.

person Nikita Kurtin    schedule 28.11.2019
comment
Hozircha bu eng yaxshi javob va birinchi jumla eng yaxshi xulosa: Bu oddiy savol, oddiy javobsiz - shunchaki uni seving. - person b2mob; 22.01.2020
comment
@M.UsmanKhan, javob shundan so'ng darhol yoziladi: Bugungi kunda bu nafaqat eng yaxshi amaliyot, balki siz buni GDPR - identifikatorlar va shunga o'xshash qoidalarga muvofiq qonun bilan bajarishingiz kerak. - person Nikita Kurtin; 08.03.2020
comment
Siz joylashtirgan GDPR havolasining qaysi bo'limida identifikatorlarni xeshlash talabi esga olinishini aniqlay olasizmi? - person David Schneider; 21.07.2020
comment
@DavidSchneider veb-kontent o'z tabiatiga ko'ra dinamikdir va GDPR misollardan biri, iltimos, men GDPR va shunga o'xshash qoidalarni yozganimni unutmang, chunki sizning faoliyatingizga ta'sir qiladigan ko'plab mahalliy va global qoidalar mavjud. mahsulot / tizim / maydon. Har qanday holatda ham siz qidirayotgan GDPR bo'limlari: Identifikatsiya, Onlayn identifikatorlar va Ma'lumotlarni himoya qilish tamoyillari - person Nikita Kurtin; 21.07.2020
comment
proandroiddev.com/ - person william gouvea; 03.01.2021
comment
Agar ilova qayta o'rnatilsa, firebase noyob identifikatori o'zgaradi - person famfamfam; 23.02.2021
comment
@famfamfam, aynan - shuning uchun men shunday yozganman: Bu qurilmada ilovalarni o'rnatish uchun noyobdir, shuning uchun foydalanuvchi dasturni o'chirib tashlaganida - u o'chib ketadi, shuning uchun u 100% ishonchli emas, lekin keyingi eng yaxshi narsa . - person Nikita Kurtin; 25.02.2021
comment
rahmat, hayronman, nega Android ANDROID_ID-ni qurilma uuid-ga aylantira olmaydi, shuning uchun Android-ning dasturchi kodini qiyinlashtiradi - person famfamfam; 25.02.2021
comment
@famfamfam Mening eng yaxshi taxminimcha, bu Android-ning ochiq tabiati va Java-ning UUID.randomUUID() psuedo-tasodifiy platformasi vaqtga asoslangan tabiatga bog'liq. - person Nikita Kurtin; 25.02.2021
comment
Kutib turing, buni bir qiymatdan ikkinchisiga o'zgartirishga olib keladigan holatlar ko'p emasmi? - person Michael Paccione; 03.07.2021

Rasmiy Android Developers blogida endi aynan shu mavzu haqida toʻliq maqola bor, Identifying Ilovalarni oʻrnatish.

person BoD    schedule 06.04.2011
comment
Va bu dalilning asosiy nuqtasi shundaki, agar siz uskunadan noyob identifikatorni olishga harakat qilsangiz, ehtimol siz xatoga yo'l qo'ygan bo'lasiz. - person Tim Bray; 12.04.2011
comment
Va agar siz qurilmangiz qulfini zavod sozlamalariga qaytarish orqali qayta o'rnatishga ruxsat bersangiz, sinov dasturingiz modeli o'lik kabi yaxshi. - person Seva Alekseyev; 04.05.2011
comment
Blog posti allaqachon ushbu saytga havola qilingan: developer.android.com/training/ maqolalar/foydalanuvchi maʼlumotlari identifikatorlari - person Bruno Bieri; 16.09.2020

Google I/O da Reto Meier ko‘pchilik ishlab chiquvchilar kuzatishi kerak bo‘lgan talablarga javob beradigan bunga qanday yondashish kerakligi haqidagi ishonchli javobni e’lon qildi. o'rnatish bo'ylab foydalanuvchilar. Entoni Nolan o'z javobida yo'nalishni ko'rsatadi, lekin boshqalar buni qanday qilishni osonlik bilan ko'rishlari uchun men to'liq yondashuvni yozaman deb o'yladim (tafsilotlarni tushunish uchun biroz vaqt ketdi).

Ushbu yondashuv sizga anonim, xavfsiz foydalanuvchi identifikatorini beradi, u foydalanuvchi uchun turli qurilmalarda (asosiy Google hisobiga asoslangan) va oʻrnatishlarda doimiy boʻladi. Asosiy yondashuv tasodifiy foydalanuvchi identifikatorini yaratish va uni ilovalarning umumiy afzalliklarida saqlashdir. Keyin Google hisobiga bog'langan umumiy afzalliklarni bulutda saqlash uchun Google zaxira agentidan foydalanasiz.

Keling, to'liq yondashuvni ko'rib chiqaylik. Birinchidan, Android Zaxiralash xizmati yordamida SharedPreferences uchun zaxira nusxasini yaratishimiz kerak. Ilovangizni http://developer.android.com/google/backup/signup.html orqali roʻyxatdan oʻtkazishdan boshlang.

Google sizga manifestga qo'shishingiz kerak bo'lgan zaxira xizmat kalitini beradi. Shuningdek, dasturga BackupAgent-dan quyidagi tarzda foydalanishni aytishingiz kerak:

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

Keyin zaxira agentini yaratishingiz va unga umumiy afzalliklar uchun yordamchi agentdan foydalanishni aytishingiz kerak:

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

Zaxiralashni yakunlash uchun asosiy faoliyatingizda BackupManager nusxasini yaratishingiz kerak:

BackupManager backupManager = new BackupManager(context);

Nihoyat, agar u mavjud bo'lmasa, foydalanuvchi identifikatorini yarating va uni SharedPreferences-da saqlang:

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

Ushbu User_ID endi, hatto foydalanuvchi qurilmani boshqa joyga ko'chirsa ham, o'rnatishlarda doimiy bo'lib qoladi.

Ushbu yondashuv haqida qo'shimcha ma'lumot olish uchun Retoning nutqi.

Zaxira agentini qanday amalga oshirish haqida toʻliq maʼlumot olish uchun Maʼlumotlarni zaxiralash. Men, ayniqsa, testning pastki qismidagi bo'limni tavsiya qilaman, chunki zaxira bir zumda sodir bo'lmaydi va shuning uchun siz zahira nusxasini majburlashingiz kerak.

person TechnoTony    schedule 22.12.2012
comment
Agar foydalanuvchi bir nechta qurilmaga ega bo'lsa, bu bir xil identifikatorga ega bir nechta qurilmalarga olib kelmaydimi? Masalan, planshet va telefon. - person Tosa; 13.03.2013

Menimcha, bu noyob identifikator uchun skelet yasashning ishonchli usuli... buni tekshiring.

Barcha Android qurilmalarida ishlaydigan Pseudo-Unique ID Ba'zi qurilmalarda telefon yo'q (masalan, planshetlar) yoki ba'zi sabablarga ko'ra siz READ_PHONE_STATE ruxsatini qo'shishni xohlamaysiz. Siz hali ham ROM versiyasi, ishlab chiqaruvchi nomi, protsessor turi va boshqa apparat tafsilotlarini o'qishingiz mumkin, agar siz identifikatordan seriya kalitini tekshirish yoki boshqa umumiy maqsadlarda foydalanmoqchi bo'lsangiz juda mos keladi. Shu tarzda hisoblangan identifikator noyob bo'lmaydi: bir xil identifikatorga ega bo'lgan ikkita qurilmani topish mumkin (bir xil apparat va ROM tasviriga asoslangan), lekin real ilovalardagi o'zgarishlar ahamiyatsiz. Buning uchun siz Build sinfidan foydalanishingiz mumkin:

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 a'zolarining aksariyati satrlardir, biz bu erda ularning uzunligini olish va modul orqali raqamga aylantirishdir. Bizda 13 ta bunday raqam bor va biz IMEI (15 ta raqam) bilan bir xil o'lchamdagi identifikatorga ega bo'lish uchun old tomonga (35) yana ikkitasini qo'shmoqdamiz. Bu erda boshqa imkoniyatlar ham bor, shunchaki ushbu satrlarni ko'rib chiqing. 355715565309247 kabi narsalarni qaytaradi. Hech qanday maxsus ruxsat talab qilinmaydi, bu yondashuvni juda qulay qiladi.


(Qoʻshimcha maʼlumot: Yuqorida keltirilgan texnika Pocket Magic dagi maqoladan koʻchirilgan.)

person Lenn Dolling    schedule 24.03.2011
comment
Qiziqarli yechim. Ko'rinib turibdiki, siz o'zingizning xesh-funktsiyangizni o'ylab topishga urinib ko'rish o'rniga, barcha ma'lumotlarni birlashtirilgan xeshlash kerak bo'lgan vaziyat. Har bir qiymat uchun har xil bo'lgan muhim ma'lumotlar mavjud bo'lsa ham, siz to'qnashuvlarga duch keladigan ko'plab holatlar mavjud. Mening tavsiyam: xesh funktsiyasidan foydalaning va keyin ikkilik natijalarni o'nli kasrga aylantiring va kerak bo'lganda uni qisqartiring. Buni to'g'ri bajarish uchun siz haqiqatan ham UUID yoki to'liq xesh qatoridan foydalanishingiz kerak. - person Steve Pomeroy; 12.04.2011
comment
Men Build.CPU_ABI va Build.MANUFACTURER barcha versiyalarda mavjud emasligini aniqladim. - person Lenn Dolling; 15.05.2011
comment
Siz o'z manbalaringizga ishonch bildirishingiz kerak... Bu to'g'ridan-to'g'ri quyidagi maqoladan olib tashlandi: pocketmagic. net/?p=1662 - person Steve Haley; 16.05.2011
comment
Bu identifikator to'qnashuvlar uchun ochiq, chunki siz bilmasangiz. Bir xil tashuvchining bir xil qurilmalarida bir xil bo'lishi deyarli kafolatlangan. - person Seva Alekseyev; 27.05.2011
comment
Agar qurilma yangilansa, bu ham o'zgarishi mumkin. - person David Given; 25.01.2012
comment
Menimcha, bu yechimdan foydalanish yaxshi fikr emas. Men tushunganimdek, barcha Build maydonlari birgalikda ishlab chiqarilgan barcha telefonlar uchun bir xil bo'ladi. - person Victor Ronin; 26.07.2012
comment
Devid Givenning izohiga ko'ra, bu jiddiy tashvishga o'xshaydi. Qurilish atributlarini diqqat bilan inventarizatsiya qilish kerak, ularning qaysi biri havodan yangilanish natijasida o'zgarishi mumkin emas. Masalan, Javadoc bo'yicha yuqoridagi Build.DISPLAY foydalanuvchiga ko'rsatish uchun mo'ljallangan Build.DISPLAY, shuning uchun yangilanish sodir bo'lganda, bu o'zgarmasmidi? Men hali ham bu yondashuv qurilmadagi boshqa ma'lumotlar bilan birgalikda foydali farqlovchi atributlarni qo'shishi mumkin deb o'ylayman, lekin faqat OTA o'zgartirilishi mumkin bo'lgan atributlarni ehtiyotkorlik bilan yo'q qilish mumkin bo'lsa. - person Carl; 23.12.2012
comment
Xuddi shunday, Build.HOST ham inson o‘qishi mumkin bo‘lgan formatda qurilgan xostni yagona identifikatsiya qiluvchi qator sifatida aniqlanadi. OTA yangilanishi uchun tuzilmani yaratish uchun turli xil BUILD mashinalaridan foydalanish mumkin ko'rinadi. - person Carl; 23.12.2012
comment
Juda, juda yomon yechim. Ikki Nexus 5 da sinovdan o‘tgan... Xuddi shu raqamlarni qaytaring. - person Sinan Dizdarević; 04.03.2015

Quyidagi kod yashirin Android API yordamida qurilma seriya raqamini qaytaradi. Biroq, bu kod Samsung Galaxy Tab-da ishlamaydi, chunki bu qurilmada "ro.serialno" o'rnatilmagan.

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

}
person Roman SL    schedule 25.01.2011

Quyidagi koddan foydalanib, siz Android OS qurilmasining noyob qurilma identifikatorini qator sifatida olishingiz mumkin.

deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 
person Mohit Kanada    schedule 17.05.2011

API 9-darajadagi Build sinfiga Serial maydoni qo‘shildi. (Android 2.3 - Gingerbread). Hujjatlarda aytilishicha, u apparat seriya raqamini ifodalaydi. Shunday qilib, agar u qurilmada mavjud bo'lsa, u noyob bo'lishi kerak.

API darajasi >= 9 bo'lgan barcha qurilmalar tomonidan aslida qo'llab-quvvatlanadimi yoki yo'qligini bilmayman (= null emas).

person rony l    schedule 06.03.2011
comment
Afsuski, noma'lum. - person m0skit0; 15.04.2013

Men bir narsani qo'shaman - menda o'sha noyob vaziyatlardan biri bor.

Foydalanish:

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

Ma'lum bo'lishicha, mening Viewsonic G planshetim Null bo'lmagan DeviceID haqida xabar bergan bo'lsa ham, har bir G plansheti bir xil raqam haqida xabar beradi.

“Noyob” DeviceID asosida kimningdir akkauntiga bir zumda kirish imkonini beruvchi “Pocket Empires” oʻyinini qiziqarli qiladi.

Mening qurilmamda uyali radio yo'q.

person Tony Maro    schedule 21.03.2011
comment
@Treewallie ishlaydimi? Turli ilovalardan bir xil qurilma identifikatorini olishingiz mumkinmi? - person Arnold Brown; 04.02.2020

Ilovangiz oʻrnatilgan har bir Android qurilmasi uchun noyob identifikatorni qanday olish boʻyicha batafsil koʻrsatmalar uchun Android Developers.blogspot.com/2011/03-dagi rasmiy Android Developers blogiga qarang. /identifying-app-installations.html" rel="noreferrer">Ilova o‘rnatishlarini aniqlash.

O'rnatishdan so'ng uni o'zingiz yaratishingiz va keyinchalik dastur qayta ishga tushirilganda uni o'qib chiqishingiz eng yaxshi yo'l bo'lib tuyuladi.

Shaxsan men buni maqbul deb bilaman, lekin ideal emas. Android tomonidan taqdim etilgan hech bir identifikator barcha holatlarda ishlamaydi, chunki ko'pchilik telefonning radio holatiga bog'liq (Wi-Fi yoqish/o'chirish, uyali aloqani yoqish/o'chirish, Bluetooth yoqish/o'chirish). Boshqalar, masalan, Settings.Secure.ANDROID_ID ishlab chiqaruvchi tomonidan amalga oshirilishi kerak va noyob bo'lishi kafolatlanmaydi.

Quyida ilova mahalliy sifatida saqlaydigan boshqa maʼlumotlar bilan birga saqlanadigan oʻrnatish fayliga maʼlumotlarni yozish misoli keltirilgan.

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();
    }
}
person Kevin Parker    schedule 02.08.2011
comment
Agar siz ilovalarni o'rnatishni kuzatmoqchi bo'lsangiz, bu juda yaxshi. Kuzatuv qurilmalari ancha murakkabroq va havo o'tkazmaydigan yechim yo'q. - person Luca Spiller; 03.10.2011
comment
Ildizlangan qurilmalar haqida nima deyish mumkin? Ular ushbu o'rnatish identifikatorini osongina o'zgartirishi mumkin, to'g'rimi? - person tasomaniac; 10.05.2012
comment
Mutlaqo. Root o'rnatish identifikatorini o'zgartirishi mumkin. Siz ushbu kod bloki yordamida ildiz mavjudligini tekshirishingiz mumkin: stackoverflow.com/questions/1101380/ - person Kevin Parker; 18.05.2012
comment
Agar zavod sozlamalarini tiklasak, fayl o'chiriladimi? - person Jamshid; 08.01.2015
comment
Agar siz /data bo'limini zavod sozlamalariga qaytarsangiz va o'chirsangiz yoki format qilsangiz, UUID boshqacha bo'ladi. - person Kevin Parker; 12.01.2015

Sinf fayliga quyidagi kodni qo'shing:

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 ga qo'shing:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
person Android    schedule 27.02.2013

Ushbu ANDROID_ID muammolarni hal qilish uchun juda ko'p turli xil yondashuvlar mavjud (ba'zida null bo'lishi mumkin yoki muayyan modeldagi qurilmalar har doim bir xil identifikatorni qaytaradi) ijobiy va salbiy tomonlari bilan:

  • Shaxsiy identifikatorni yaratish algoritmini amalga oshirish (statik bo'lishi kerak bo'lgan va o'zgarmaydigan qurilma xususiyatlariga asoslangan -> kim biladi)
  • IMEI, seriya raqami, Wi-Fi/Bluetooth-MAC manzili (ular yutadi) kabi boshqa identifikatorlarni suiiste'mol qilish t barcha qurilmalarda mavjud yoki qo'shimcha ruxsatlar kerak bo'ladi)

Men o'zim mavjud OpenUDID ilovasidan foydalanishni afzal ko'raman (qarang: https://github.com/ylechelle/OpenUDID). Android (qarang: https://github.com/vieux/OpenUDID). U integratsiya qilish oson va yuqorida aytib o'tilgan muammolar uchun ANDROID_ID-dan zaxiralar bilan foydalanadi.

person Andreas Klöber    schedule 18.11.2012

TelephonyManager va ANDROID_ID dan foydalangan holda String sifatida Android OS qurilmasining noyob qurilma identifikatori quyidagilar orqali olinadi:

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

Lekin men Google tomonidan tavsiya etilgan usulni tavsiya qilaman, qarang: Identifikatsiya qilish Ilovalarni oʻrnatish.

person Jorgesys    schedule 13.01.2014

Bu erda 30 dan ortiq javoblar mavjud va ba'zilari bir xil va ba'zilari noyobdir. Bu javob o'sha javoblarning bir nechtasiga asoslanadi. Ulardan biri @Lenn Dollingning javobidir.

U 3 ta identifikatorni birlashtiradi va 32 xonali olti burchakli qatorni yaratadi. Bu men uchun juda yaxshi ishladi.

3 identifikator:
Pseudo-ID - U jismoniy qurilma spetsifikatsiyalari asosida yaratilgan
ANDROID_ID - Settings.Secure.ANDROID_ID
Bluetooth manzili - Bluetooth adapter manzili

U shunday qaytaradi: 551F27C060712A72730B0A0F734064B1

Eslatma: Siz har doim longId qatoriga qoʻshimcha identifikatorlar qoʻshishingiz mumkin. Masalan, seriya #. Wi-Fi adapter manzili. IMEI. Shunday qilib, siz uni har bir qurilma uchun yanada noyob qilasiz.

@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 "";
}
person ᴛʜᴇᴘᴀᴛᴇʟ    schedule 08.03.2017
comment
UUID ni longId raqamiga qo‘shish va uni faylda saqlash uni eng noyob identifikatorga aylantiradi. : String uuid = UUID.randomUUID().toString(); - person Mousa Alfhaily; 11.04.2017
comment
Agar barchasi bajarilmasa, foydalanuvchi API 9 dan pastroq (Gingerbread’dan past) bo‘lsa, telefonini yoki “Secure.ANDROID_ID” sozlamalarini asliga qaytargan. agar "null" qiymatini qaytarsa, qaytarilgan identifikator faqat Android qurilmasi ma'lumotlariga asoslanadi. Bu erda to'qnashuvlar sodir bo'lishi mumkin. DISPLAY, HOST yoki ID dan foydalanmaslikka harakat qiling - bu elementlar o'zgarishi mumkin. Agar to'qnashuvlar bo'lsa, bir-biriga mos keladigan ma'lumotlar bo'ladi. Manba: gist.github.com/pedja1/fe69e8a80ed505500caa - person Mousa Alfhaily; 11.04.2017
comment
@Ninja BLE mac manzili noyob bo'lgani uchun, ha, yaratilgan identifikator har doim noyob bo'ladi. Ammo, agar siz haqiqatan ham ishonch hosil qilishni istasangiz, longId ga UUID qo'shishni taklif qilaman. Bir qatorni shunday o'zgartiring: String longId = pseudoId + androidId + btId + UUID.randomUUID().toString(); Bu yaratilgan ID noyob bo'lishini kafolatlaydi. - person ᴛʜᴇᴘᴀᴛᴇʟ; 03.04.2019

IMEI haqida nima deyish mumkin? Bu Android yoki boshqa mobil qurilmalar uchun noyobdir.

person Elzo Valugi    schedule 14.07.2011
comment
Mening mobil operatorimga ulanmagani uchun IMEI-ga ega bo'lmagan planshetlarim uchun emas. - person Brill Pappin; 05.01.2012
comment
IMEI o'rniga ESNga ega bo'lgan CDMA qurilmalari haqida gapirmasa ham bo'ladi. - person David Given; 25.01.2012
comment
Bu faqat shunday qiladi, bu telefon :) Planshet bo'lmasligi mumkin. - person Brill Pappin; 26.01.2012
comment
@ElzoValugi Bu kunlar allaqachon va hali ham barcha planshetlarda SIM kartalar mavjud emas. - person MLQ; 25.09.2012

Men noyob identifikatorni qanday yarataman:

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;
}
person Eng.Fouad    schedule 27.05.2013
comment
Agar biz 6.0 versiyasida ReadPhoneState-dan foydalanish uchun ruxsat so'rasak - person Harsha; 17.11.2016

Mening ikki sentim - bu qurilma (xato) noyob identifikatori uchun - Android ishlab chiquvchilar blogi.

Shuni esda tutingki, @emmby tomonidan taqdim etilgan yechim har bir ilova identifikatoriga to'g'ri keladi, chunki SharedPreferences jarayonlar bo'ylab sinxronlashtirilmaydi (qarang. bu yerda va bu yerda). Shunday qilib, men bundan butunlay voz kechdim.

Buning o'rniga, enumda (qurilma) identifikatorini olishning turli strategiyalarini qamrab oldim - enum konstantalarining tartibini o'zgartirish ID olishning turli usullarining ustuvorligiga ta'sir qiladi. Birinchi null bo'lmagan identifikator qaytariladi yoki istisno qilinadi (Javaning null ma'nosini bermaslik amaliyotiga ko'ra). Masalan, menda birinchi TELEPHONY bor - lekin yaxshi birlamchi tanlov ANDROID_ID beta: bo'ladi.

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);
        }
    }
}
person Mr_and_Mrs_D    schedule 18.09.2013

Boshqa usul - /sys/class/android_usb/android0/iSerial ilovasida hech qanday ruxsatsiz foydalanish.

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 buni amalga oshirish uchun iSerial faylini ochish va belgilarni o'qish uchun FileInputStream-dan foydalanish kifoya. Uni istisno ishlovchiga o'rashingizga ishonch hosil qiling, chunki hamma qurilmalarda ham bu fayl mavjud emas.

Hech bo'lmaganda quyidagi qurilmalar ushbu faylni dunyo tomonidan o'qilishi mumkinligi ma'lum:

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

Siz mening blogimdagi postimni ham ko'rishingiz mumkin Android uskunasining sizib chiqishi imtiyozsiz ilovalar uchun seriya raqami, bu erda men ma'lumot olish uchun qanday boshqa fayllar mavjudligini muhokama qilaman.

person insitusec    schedule 31.01.2013
comment
Men hozirgina blogingizni o'qidim. Menimcha, bu noyob emas: Build.SERIAL har qanday ruxsatsiz ham mavjud va (nazariy jihatdan) noyob apparat seriya raqami. - person Tom; 01.05.2013
comment
Siz haqsiz. Bu sizning qurilmangizni kuzatishning yana bir usuli va siz aytganingizdek, bu ikkala usul ham ilova ruxsatini talab qilmaydi. - person insitusec; 14.03.2014

TelephonyManger.getDeviceId() Noyob qurilma identifikatorini qaytaradi, masalan, GSM uchun IMEI va CDMA telefonlari uchun MEID yoki ESN.

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

Lekin men foydalanishni tavsiya qilaman:

Settings.Secure.ANDROID_ID bu Android identifikatorini noyob 64 bitli olti burchakli qator sifatida qaytaradi.

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

Ba'zan TelephonyManger.getDeviceId() null qiymatini qaytaradi, shuning uchun noyob identifikatorga ishonch hosil qilish uchun siz ushbu usuldan foydalanasiz:

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;
}
person Jorgesys    schedule 06.02.2015
comment
Yaqinda men mijozning SM-G928F / Galaxy S6 edge+ tipidagi qurilmasi Android ID uchun 16 olti burchakli raqam o‘rniga atigi 15 tani taqdim etishini aniqladim. - person Holger Jakobs; 13.03.2016

Google Instance ID

I/O 2015 da chiqarilgan; Android-da o'yin xizmatlarini talab qiladi 7.5.

https://developers.google.com/instance-id/
https://developers.google.com/instance-id/guides/android-implementation

InstanceID iid = InstanceID.getInstance( context );   // Google docs are wrong - this requires context
String id = iid.getId();  // blocking call

Google ushbu identifikatordan Android, Chrome va iOS qurilmalaridagi oʻrnatishlarni aniqlash uchun foydalanish niyatida.

U qurilmani emas, balki o'rnatishni aniqlaydi, lekin yana ANDROID_ID (bu qabul qilingan javob) endi qurilmalarni ham aniqlamaydi. ARC ish vaqti bilan har bir o'rnatish uchun yangi ANDROID_ID yaratiladi (tafsilotlari bu yerda), xuddi shu yangi namuna identifikatori kabi. Bundan tashqari, menimcha, o'rnatishlarni aniqlash (qurilmalar emas) ko'pchiligimiz izlayotgan narsadir.

Identifikator namunasining afzalliklari

Menimcha, Google uni shu maqsadda qo'llashni (o'rnatishlaringizni aniqlash) mo'ljallangan, u o'zaro platformalardir va boshqa bir qator maqsadlarda foydalanish mumkin (yuqoridagi havolalarga qarang).

Agar siz GCM dan foydalansangiz, oxir-oqibat ushbu misol identifikatoridan foydalanishingiz kerak bo'ladi, chunki u sizga GCM tokenini (eski GCM ro'yxatga olish identifikatori o'rnini bosuvchi) olish uchun kerak bo'ladi.

Kamchiliklar/muammolar

Joriy tatbiqda (GPS 7.5) misol identifikatori ilovangiz talab qilganda serverdan olinadi. Bu shuni anglatadiki, yuqoridagi qo'ng'iroq blokirovka qiluvchi qo'ng'iroqdir - mening ilmiy asossiz sinovlarimga ko'ra, agar qurilma onlayn bo'lsa, bu 1-3 soniyani oladi, agar oflayn bo'lsa - 0,5 - 1,0 soniya (ehtimol, bu qo'ng'iroqdan voz kechishdan va yaratishdan oldin qancha vaqt kutadi). tasodifiy ID). Bu Shimoliy Amerikada Android 5.1.1 va GPS 7.5 bilan Nexus 5 da sinovdan o'tkazildi.

Agar siz identifikatordan ular mo'ljallangan maqsadlarda foydalansangiz - masalan. ilova autentifikatsiyasi, ilova identifikatsiyasi, GCM - Menimcha, bu 1-3 soniya noqulaylik tug'dirishi mumkin (albatta ilovangizga qarab).

person Tom    schedule 19.06.2015
comment
instanceID ning yana bir muhim salbiy tomoni shundaki, agar foydalanuvchi ilova ma'lumotlarini tozalasa, siz uchun yangi instanceID yaratiladi. - person idanakav; 08.07.2015
comment
Qiziqarli, lekin menimcha, bu potentsial foydalanish holatlarini o'zgartirmaydi: android_id kabi misol identifikatori qurilmani aniqlash uchun mos emas. Shunday qilib, sizning serveringiz foydalanuvchi ma'lumotlarini tozalashni foydalanuvchi ilovangizni o'chirish va qayta o'rnatish kabi ko'radi - bu asossiz emas. - person Tom; 08.07.2015

Muayyan Android qurilmasini apparat tomonidan tanib olish uchun MAC manzillarini tekshirishingiz mumkin.

buni shunday qilishingiz mumkin:

AndroidManifest.xml ichida

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

endi sizning kodingizda:

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

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

Har bir Android qurilmasida ularning kamida "wlan0" interfeysi jodugar WI-FI chipidir. Ushbu kod WI-FI yoqilmaganda ham ishlaydi.

P.S. Ular MACS o'z ichiga olgan ro'yxatdagi boshqa interfeyslar to'plamidir, ammo bu telefonlar o'rtasida o'zgarishi mumkin.

person Ilan.b    schedule 01.09.2015

Men IMEI ni olish uchun quyidagi koddan foydalanaman yoki qurilma telefon imkoniyatlariga ega boʻlmasa, muqobil sifatida Secure.ANDROID_ID dan foydalanaman:

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);
person Asaf Pinhassi    schedule 15.04.2013

Android qurilmalaridagi mavjud noyob identifikatorlarni tushunish uchun. Ushbu rasmiy qo'llanmadan foydalaning.

Noyob identifikatorlar uchun eng yaxshi amaliyotlar:

Qurilmalarni tekshirish uchun IMEI, Mac manzillari, namuna identifikatori, GUIDlar, SSAID, reklama identifikatori, Safety Net API.

https://developer.android.com/training/articles/user-data-ids

person Waheed Nazir    schedule 03.05.2019

Google endi Reklama identifikatoriga ega.
Bu ham mumkin foydalanish mumkin, lekin shuni yodda tuting:

Reklama identifikatori foydalanuvchiga xos, noyob, qayta tiklanadigan identifikatordir

va

foydalanuvchilarga identifikatorini tiklash yoki Google Play ilovalaridagi qiziqishlarga asoslangan reklamalardan voz kechish imkonini beradi.

Bu identifikator o'zgarishi mumkin bo'lsa-da, tez orada bizda tanlov bo'lmasligi mumkin, bu identifikatorning maqsadiga bog'liq.

Batafsil ma'lumot @ develper.android

Kodni shu yerdan nusxalash-joylashtirish

HTH

person Hertzel Guinness    schedule 02.11.2013
comment
Uni qayta tiklash mumkin: Reklama identifikatori noyob, lekin foydalanuvchi tomonidan qayta o'rnatiladigan qator identifikatori bo'lib, reklama tarmoqlari va boshqa ilovalarga foydalanuvchini anonim tarzda aniqlash imkonini beradi. - person Jared Burrows; 06.11.2013
comment
(@JaredBurrows ha, bu xabarda aytilgan ...) - person Hertzel Guinness; 06.11.2013

1. Noyob identifikatorni (ya'ni IMEI) taqdim etadigan telefoniya menejeridan foydalaning. Misolga qarang,

import android.telephony.TelephonyManager;
import android.content.Context;
// ...
TelephonyManager telephonyManager;
telephonyManager = (TelephonyManager) getSystemService(Context.
                TELEPHONY_SERVICE);
/*
* getDeviceId() returns the unique device ID.
* For example,the IMEI for GSM and the MEID or ESN for CDMA phones.
*/
String deviceId = telephonyManager.getDeviceId();
/*
* getSubscriberId() returns the unique subscriber ID,
*/
String subscriberId = telephonyManager.getSubscriberId();

Buning uchun foydalanuvchingizdan android.permission.READ_PHONE_STATE talab qilinadi, bu siz yaratgan ilova turiga qarab oqlash qiyin bo'lishi mumkin.

  1. Planshetlar kabi telefoniya xizmatlariga ega bo‘lmagan qurilmalar Android 2.3 Gingerbread’dan beri android.os.Build.SERIAL orqali mavjud bo‘lgan noyob qurilma identifikatorini bildirishi kerak. Telefoniya xizmatlariga ega bo'lgan ba'zi telefonlar seriya raqamini ham belgilashi mumkin. Barcha Android qurilmalari seriya raqamiga ega emasligi kabi, bu yechim ishonchli emas.

  2. Qurilmaning birinchi yuklanishida tasodifiy qiymat hosil qilinadi va saqlanadi. Bu qiymat Settings.Secure.ANDROID_ID orqali mavjud. Bu 64 bitli raqam bo'lib, u qurilmaning ishlash muddati davomida doimiy bo'lib qolishi kerak. ANDROID_ID noyob qurilma identifikatori uchun yaxshi tanlov ko'rinadi, chunki u smartfon va planshetlar uchun mavjud. Qiymatni olish uchun siz quyidagi koddan foydalanishingiz mumkin:

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

Biroq, agar qurilmada zavod sozlamalari o'zgartirilsa, qiymat o'zgarishi mumkin. Bundan tashqari, ishlab chiqaruvchining mashhur telefonida ma'lum xatolik mavjud bo'lib, har bir nusxada bir xil ANDROID_ID mavjud. Shubhasiz, yechim 100% ishonchli emas.

  1. UUID dan foydalaning. Ko'pgina ilovalar uchun talab jismoniy qurilma emas, balki ma'lum bir o'rnatishni aniqlash bo'lgani uchun, agar UUID sinfidan foydalansa, foydalanuvchi uchun noyob identifikatorni olish uchun yaxshi yechim. Quyidagi yechim Google kompaniyasidan Reto Meier tomonidan Google I/O taqdimotida taqdim etilgan,
SharedPreferences sharedPrefs = context.getSharedPreferences(
         PREF_UNIQUE_ID, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);

Yangilanish : #1 va #2 opsiyalari google tomonidan maxfiylik yangilanishi sifatida Android 10-dan keyin endi mavjud emas. chunki 2 va 3 variant muhim ruxsatni talab qiladi.

person Kiran Maniya    schedule 05.10.2018
comment
Har bir nusxada bir xil ANDROID_ID bo'lgan telefon qaysi? - person viper; 26.08.2019
comment
iltimos, rasmiy hujjatlarga qarang developer.android.com/reference/ android/provayder/ - person Kiran Maniya; 26.08.2019
comment
DeviceInfoProvider bu Android SDK qismi emas - person user924; 06.02.2020
comment
Buni ko'rsatganingiz uchun rahmat, @user924. Agar sizda qo'shimcha ma'lumotlar bo'lsa, uni yaxshilash uchun javobni tahrirlashingiz mumkin. - person Kiran Maniya; 06.02.2020
comment
@KiranManiya O'ylab topilgan javobingizni tahrirlang. Agar siz o'ylab topsangiz, odamlar uni qanday tahrirlashni bilishadi? Siz uni tahrirlashingiz kerak. Bu yerda savolga xayolingiz bilan javob bermang - person jerinho.com; 25.04.2020
comment
@jerinho Katta rahmat. O'ylaymanki, siz mening ikkala javobimni ham ko'rib chiqdingiz. - person Kiran Maniya; 26.04.2020

Android qurilmasi mac identifikatori ham noyob identifikator hisoblanadi. Qurilmaning o'zi formatlangan bo'lsa ham, u o'zgarmaydi.

Mac identifikatorini olish uchun quyidagi koddan foydalaning:

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

Shuningdek, AndroidManifest.xml faylingizga tegishli ruxsatnomalarni qo‘shishni unutmang:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
person Baskaran Veerabathiran    schedule 03.10.2016
comment
Afsuski, joriy Wi-Fi ulanishi bo'lmasa, bu ishlamaydi. hujjatlardan (ta'kidlangan) ): Joriy Wi-Fi ulanishi haqida dinamik ma'lumotni qaytaring, agar u faol bo'lsa. - person Ted Hopp; 05.10.2016
comment
Shuningdek, qurilmaga ildiz ruxsatini berish orqali, Mac manzilini aldash mumkin - person ; 03.07.2017
comment
Android 10 (API darajasi 29) va undan yuqori versiyalarda ishlaydigan qurilmalar qurilma egasi ilovalari boʻlmagan barcha ilovalarga tasodifiy MAC manzillari haqida xabar beradi. Shunday qilib, Android 10 yoki undan keyingi versiyada boʻlganingizda u noyob boʻlmaydi. - person Saddan; 23.05.2020

O'qiyotgan har bir kishi uchun eng so'nggi ma'lumotni qidirib toping. Android O bilan tizim ushbu identifikatorlarni qanday boshqarishi bo'yicha ba'zi o'zgarishlar mavjud.

https://android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html

tl;dr Serial PHONE ruxsatini talab qiladi va Android identifikatori paket nomi va imzosiga qarab turli ilovalar uchun o'zgaradi.

Shuningdek, Google apparat va dasturiy ta'minot identifikatorlaridan qachon foydalanish bo'yicha takliflarni taqdim etadigan yaxshi hujjat tuzdi.

https://developer.android.com/training/articles/user-data-ids.html

person bugraoral    schedule 11.04.2017

Odatda ilovalarim uchun qurilmaning noyob identifikatoridan foydalanaman. Lekin ba'zida men IMEI-dan foydalanaman. Ikkalasi ham noyob raqamlar.

IMEI (xalqaro mobil uskunalar identifikatori) olish uchun

public String getIMEI(Activity activity) {
    TelephonyManager telephonyManager = (TelephonyManager) activity
            .getSystemService(Context.TELEPHONY_SERVICE);
    return telephonyManager.getDeviceId();
}

qurilma noyob identifikatorini olish uchun

public String getDeviceUniqueID(Activity activity){
    String device_unique_id = Secure.getString(activity.getContentResolver(),
            Secure.ANDROID_ID);
    return device_unique_id;
}
person Zin Win Htet    schedule 19.06.2017

Men bu savolga bir necha yil oldin duch kelganman va turli javoblar asosida umumlashtirilgan yechimni amalga oshirishni o'rgandim.

Men umumlashtirilgan yechimni bir necha yil davomida haqiqiy mahsulotda ishlatganman. Hozirgacha bu menga juda yaxshi xizmat qilmoqda. Turli xil javoblarga asoslangan kod parchasi.

E'tibor bering, getEmail ko'pincha null qiymatini qaytaradi, chunki biz aniq ruxsat so'ramaganmiz.

private static UniqueId getUniqueId() {
    MyApplication app = MyApplication.instance();

    // Our prefered method of obtaining unique id in the following order.
    // (1) Advertising id
    // (2) Email
    // (2) ANDROID_ID
    // (3) Instance ID - new id value, when reinstall the app.

    ////////////////////////////////////////////////////////////////////////////////////////////
    // ADVERTISING ID
    ////////////////////////////////////////////////////////////////////////////////////////////
    AdvertisingIdClient.Info adInfo = null;
    try {
        adInfo = AdvertisingIdClient.getAdvertisingIdInfo(app);
    } catch (IOException e) {
        Log.e(TAG, "", e);
    } catch (GooglePlayServicesNotAvailableException e) {
        Log.e(TAG, "", e);
    } catch (GooglePlayServicesRepairableException e) {
        Log.e(TAG, "", e);
    }

    if (adInfo != null) {
        String aid = adInfo.getId();
        if (!Utils.isNullOrEmpty(aid)) {
            return UniqueId.newInstance(aid, UniqueId.Type.aid);
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////
    // EMAIL
    ////////////////////////////////////////////////////////////////////////////////////////////
    final String email = Utils.getEmail();
    if (!Utils.isNullOrEmpty(email)) {
        return UniqueId.newInstance(email, UniqueId.Type.eid);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////
    // ANDROID ID
    ////////////////////////////////////////////////////////////////////////////////////////////
    final String sid = Settings.Secure.getString(app.getContentResolver(), Settings.Secure.ANDROID_ID);
    if (!Utils.isNullOrEmpty(sid)) {
        return UniqueId.newInstance(sid, UniqueId.Type.sid);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////
    // INSTANCE ID
    ////////////////////////////////////////////////////////////////////////////////////////////
    final String iid = com.google.android.gms.iid.InstanceID.getInstance(MyApplication.instance()).getId();
    if (!Utils.isNullOrEmpty(iid)) {
        return UniqueId.newInstance(iid, UniqueId.Type.iid);
    }

    return null;
}

public final class UniqueId implements Parcelable {
    public enum Type implements Parcelable {
        aid,
        sid,
        iid,
        eid;

        ////////////////////////////////////////////////////////////////////////////
        // Handling Parcelable nicely.

        public static final Parcelable.Creator<Type> CREATOR = new Parcelable.Creator<Type>() {
            public Type createFromParcel(Parcel in) {
                return Type.valueOf(in.readString());
            }

            public Type[] newArray(int size) {
                return new Type[size];
            }
        };

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel parcel, int flags) {
            parcel.writeString(this.name());
        }

        // Handling Parcelable nicely.
        ////////////////////////////////////////////////////////////////////////////
    }

    public static boolean isValid(UniqueId uniqueId) {
        if (uniqueId == null) {
            return false;
        }
        return uniqueId.isValid();
    }

    private boolean isValid() {
        return !org.yccheok.jstock.gui.Utils.isNullOrEmpty(id) && type != null;
    }

    private UniqueId(String id, Type type) {
        if (org.yccheok.jstock.gui.Utils.isNullOrEmpty(id) || type == null) {
            throw new java.lang.IllegalArgumentException();
        }
        this.id = id;
        this.type = type;
    }

    public static UniqueId newInstance(String id, Type type) {
        return new UniqueId(id, type);
    }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + id.hashCode();
        result = 31 * result + type.hashCode();
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }

        if (!(o instanceof UniqueId)) {
            return false;
        }

        UniqueId uniqueId = (UniqueId)o;
        return this.id.equals(uniqueId.id) && this.type == uniqueId.type;
    }

    @Override
    public String toString() {
        return type + ":" + id;
    }

    ////////////////////////////////////////////////////////////////////////////
    // Handling Parcelable nicely.

    public static final Parcelable.Creator<UniqueId> CREATOR = new Parcelable.Creator<UniqueId>() {
        public UniqueId createFromParcel(Parcel in) {
            return new UniqueId(in);
        }

        public UniqueId[] newArray(int size) {
            return new UniqueId[size];
        }
    };

    private UniqueId(Parcel in) {
        this.id = in.readString();
        this.type = in.readParcelable(Type.class.getClassLoader());
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeString(this.id);
        parcel.writeParcelable(this.type, 0);
    }

    // Handling Parcelable nicely.
    ////////////////////////////////////////////////////////////////////////////

    public final String id;
    public final Type type;
}

public static String getEmail() {
    Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
    AccountManager accountManager = AccountManager.get(MyApplication.instance());
    Account[] accounts = accountManager.getAccountsByType("com.google");
    for (Account account : accounts) {
        if (emailPattern.matcher(account.name).matches()) {
            String possibleEmail = account.name;
            return possibleEmail;
        }
    }

    accounts = accountManager.getAccounts();
    for (Account account : accounts) {
        if (emailPattern.matcher(account.name).matches()) {
            String possibleEmail = account.name;
            return possibleEmail;
        }
    }

    return null;
} 
person Cheok Yan Cheng    schedule 07.11.2017
comment
Lekin bu foydalanuvchi telefonini qayta o'rnatganda ishlaydimi? u holda android identifikatori o'zgaradi, reklama identifikatori qayta o'rnatiladi va elektron pochta ham. - person G3n1t0; 09.03.2021

DeviceId sifatida tavsiya etilmaydi, uchinchi tomon qo'llarida kuzatuv sifatida ishlatilishi mumkin, ammo bu boshqa usul.

@SuppressLint("HardwareIds")
private String getDeviceID() {
    deviceId = Settings.Secure.getString(getApplicationContext().getContentResolver(),
                    Settings.Secure.ANDROID_ID);
    return deviceId;
}
person Ege Kuzubasioglu    schedule 28.12.2017
comment
Android ba'zi o'zgarishlarni amalga oshirmoqda: Settings.Secure.ANDROID_ID; Android 8.0 (API darajasi 26) va platformaning yuqoriroq versiyalarida ilova imzolash kaliti, foydalanuvchi va qurilmaning har bir kombinatsiyasiga xos bo‘lgan 64 bitli raqam (o‘n oltilik qator sifatida ifodalangan). Bu shuni anglatadiki, Settings.Secure.ANDROID_ID endi ilova/qurilma kombinatsiyasiga xos identifikatorlarni qaytaradi, bu esa foydalanuvchi uchun ishlarni xavfsizroq qiladi. - person Jeff Padgett; 22.06.2018

Mana, AAID olish uchun oddiy javob, 2019-yil iyun oyida toʻgʻri ishlagan

 AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            String token = null;
            Info adInfo = null;
            try {
                adInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
            } catch (IOException e) {
                // ...
            } catch ( GooglePlayServicesRepairableException e) {
                // ...
            } catch (GooglePlayServicesNotAvailableException e) {
                // ...
            }
            String android_id = adInfo.getId();
            Log.d("DEVICE_ID",android_id);

            return android_id;
        }

        @Override
        protected void onPostExecute(String token) {
            Log.i(TAG, "DEVICE_ID Access token retrieved:" + token);
        }

    };
    task.execute();

to'liq javobni batafsil o'qing bu yerda:

person Raj    schedule 11.06.2019

Quyidagi funksiya yordamida Device UUID, brend nomi bilan model raqami va uning versiya raqamini oling.

Android 10 da mukammal ishlaydi va telefon holatini oʻqishga ruxsat berish shart emas.

Kod parchalari:

private void fetchDeviceInfo() {
    String uniquePseudoID = "35" +
            Build.BOARD.length() % 10 +
            Build.BRAND.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 serial = Build.getRadioVersion();
    String uuid=new UUID(uniquePseudoID.hashCode(), serial.hashCode()).toString();
    String brand=Build.BRAND;
    String modelno=Build.MODEL;
    String version=Build.VERSION.RELEASE;
    Log.e(TAG, "fetchDeviceInfo: \n "+
            "\n uuid is : "+uuid+
            "\n brand is: "+brand+
            "\n model is: "+modelno+
            "\n version is: "+version);
}

Yuqoridagi qo'ng'iroq funksiyasi va yuqoridagi kodning chiqishini tekshirish uchun. Iltimos, android studiodagi jurnalga kiruvchi mushukingizni ko'ring. Bu quyida ko'rinadi:

rasm tavsifini shu yerga kiriting

person CodeInsideCoffee    schedule 07.06.2020
comment
kodingizdagi %10 va 35+... nima? Aytmoqchimanki, nima uchun noyob identifikatorni yaratish uchun ushbu yondashuvdan foydalanasiz? Nima uchun bu satrlarni birlashtirib, noyob UUID yaratmaysiz? bu usulning chiqishi dunyodagi barcha qurilmalar uchun mutlaqo noyobmi? - person porya74; 15.06.2020

Android 9ni qo'shish uchun menda (ehtimol) hech qanday shartlarni buzmaydigan, ruxsat talab qiladigan va o'rnatish va ilovalarda ishlashi mumkin bo'lgan faqat bitta fikr bor.

Server ishtirokidagi barmoq izi qurilmani noyob tarzda aniqlay olishi kerak. Uskuna ma'lumotlari + o'rnatilgan ilovalar va o'rnatish vaqtlarining kombinatsiyasi yordam berishi kerak. Ilova oʻchirilmasa va qayta oʻrnatilmasa, birinchi oʻrnatish vaqtlari oʻzgarmaydi. Ammo bu qurilmani aniqlab bo'lmasligi uchun (ya'ni zavod sozlamalarini tiklashdan keyin) qurilmadagi barcha ilovalar uchun bajarilishi kerak.

Men bu borada shunday yo'l tutgan bo'lardim:

  1. Uskuna ma'lumotlarini, ilovalar paketi nomlarini va birinchi o'rnatish vaqtlarini chiqarib oling.

Android-dan barcha ilovalarni shu tarzda chiqarasiz (ruxsat shart emas):

final PackageManager pm = application.getPackageManager();
List<ApplicationInfo> packages = 
pm.getInstalledApplications(PackageManager.GET_META_DATA);

for (ApplicationInfo packageInfo : packages) {
    try {
        Log.d(TAG, "Installed package :" + packageInfo.packageName);
        Log.d(TAG, "Installed :" + pm.getPackageInfo(packageInfo.packageName, 0).firstInstallTime);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
}
  1. Siz uni serverga yuborishdan oldin har bir paket nomi va oʻrnatish vaqt tamgʻasi kombinatsiyasidan xeshni yasashni xohlashingiz mumkin, chunki u foydalanuvchi qurilmaga oʻrnatgan biznesingiz boʻlishi mumkin yoki boʻlmasligi mumkin.
  2. Ba'zi ilovalar (aslida juda ko'p) tizim ilovalari. Ular zavod sozlamalariga qaytarilgandan so'ng oxirgi tizim yangilanishiga mos keladigan bir xil o'rnatish vaqt tamg'asiga ega bo'lishi mumkin. Ular bir xil o'rnatish vaqt belgisiga ega bo'lgani uchun ularni foydalanuvchi o'rnatib bo'lmaydi va ularni filtrlash mumkin.
  3. Ma'lumotni serverga yuboring va unga avval saqlangan ma'lumotlar orasida eng yaqin moslikni izlashga ruxsat bering. Ilovalar oʻrnatilgan va oʻchirilganda, avval saqlangan qurilma maʼlumotlari bilan solishtirganda chegara qoʻyishingiz kerak. Ammo mening taxminimcha, bu chegara juda past bo'lishi mumkin, chunki har qanday paket nomi va birinchi marta o'rnatish vaqt tamg'asi kombinatsiyasi faqat qurilma uchun juda noyob bo'ladi va ilovalar tez-tez o'rnatilmaydi va o'chirilmaydi. Bir nechta ilovalarga ega bo'lish noyob bo'lish ehtimolini oshiradi.
  4. Oʻyin uchun yaratilgan noyob identifikatorni qaytaring yoki noyob identifikatorni yarating, qurilma maʼlumotlarini saqlang va ushbu yangi identifikatorni qaytaring.

E'tibor bering: Bu sinovdan o'tmagan va isbotlanmagan usul! Ishonchim komilki, bu ishlaydi, lekin agar bu davom etsa, ular uni u yoki bu tarzda yopishlariga ishonchim komil.

person Jens Vesti    schedule 31.01.2019

Agar siz qo'shsangiz:

Settings.Secure.getString(context.contentResolver,
    Settings.Secure.ANDROID_ID)

Android Lint sizga quyidagi ogohlantirishni beradi:

Qurilma identifikatorlarini olish uchun getString dan foydalanish tavsiya etilmaydi. Tekshiruv haqida ma'lumot: Ushbu qurilma identifikatorlaridan foydalanish yuqori qiymatli firibgarlikning oldini olish va telefoniyadan foydalanishning ilg'or holatlaridan tashqari tavsiya etilmaydi. Reklamadan foydalanish holatlari uchun AdvertisingIdClient$Info#getId va tahlillar uchun InstanceId#getId dan foydalaning.

Shunday ekan, buni ishlatishdan qochishingiz kerak.

Android dasturchi hujjatlarida aytib o'tilganidek :

1: Uskuna identifikatorlaridan foydalanishdan saqlaning.

Aksariyat hollarda siz SSAID (Android ID) va IMEI kabi apparat identifikatorlaridan kerakli funksiyalarni cheklamasdan foydalanishdan qochishingiz mumkin.

2: Foydalanuvchi profili yoki reklamalardan foydalanish holatlari uchun faqat reklama identifikatoridan foydalaning.

Reklama identifikatoridan foydalanganda har doim foydalanuvchilarning reklama kuzatuviga oid tanlovlarini hurmat qiling. Shuningdek, identifikatorni shaxsni identifikatsiya qiluvchi maʼlumotlarga (PII) ulab boʻlmasligiga ishonch hosil qiling va Reklama identifikatori sozlamalarini tiklashdan saqlaning.

3: Toʻlovlarni firibgarlikning oldini olish va telefoniyadan tashqari, iloji boricha boshqa barcha foydalanish holatlari uchun Instance ID yoki shaxsiy saqlangan GUID dan foydalaning.

Reklamasiz foydalanish holatlarining aksariyati uchun Instance ID yoki GUID etarli bo'lishi kerak.

4: Maxfiylik xavfini minimallashtirish uchun foydalanish holatlaringizga mos API-lardan foydalaning.

Yuqori qiymatli kontentni himoya qilish uchun DRM API va suiiste'moldan himoya qilish uchun SafetyNet API'laridan foydalaning. SafetyNet API'lari maxfiylikka xavf tug'dirmasdan qurilmaning haqiqiyligini aniqlashning eng oson yo'lidir.

person Malwinder Singh    schedule 24.07.2019

String SERIAL_NUMER = Build.SERIAL;

SERIAL NUMBER ni har bir qurilmada noyob bo'lgan qator sifatida qaytaradi.

person Jeffy    schedule 07.09.2017

Seriya raqami - bu android.os.Build.SERIAL orqali mavjud bo'lgan noyob qurilma identifikatoridir.

public static String getSerial() {
    String serial = "";
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
        serial = Build.getSerial();
    }else{ 
        serial = Build.SERIAL;    
    }
    return serial;
}

getSerial() ga qo‘ng‘iroq qilishdan oldin READ_PHONE_STATE ruxsatiga ega ekanligingizga ishonch hosil qiling.

QAYD:- Bu Telefoniyasiz qurilmalarda ishlamaydi (masalan, faqat Wi-Fi planshetlari).

person shivampip    schedule 14.12.2017
comment
Hujjatlar shuni ko'rsatadiki, bu agar mavjud bo'lsa uskunaning seriya raqamini qaytaradi, bu Build.SERIAL (yoki Build.getSerial()) har doim ham mavjud emasligini ko'rsatadi. Batafsil ma'lumotni blog postida topishingiz mumkin O'zgartirishlar Android Oda qurilma identifikatorlari. Shuningdek, o‘qishga arziydi: Noyob identifikatorlar bo‘yicha eng yaxshi amaliyotlar. - person Ted Hopp; 14.12.2017

To'liqlik uchun Xamarin.Android va C# da Id ni qanday qilib olishingiz mumkin:

var id = Settings.Secure.GetString(ContentResolver, Settings.Secure.AndroidId);

Yoki Activity ichida bo'lmasangiz:

var id = Settings.Secure.GetString(context.ContentResolver, Settings.Secure.AndroidId);

Bu erda context kontekstda uzatilgan.

person Martin Zikmund    schedule 21.01.2019

android.telephony.TelephonyManager.getDeviceId()

Bu qurilmani noyob tarzda identifikatsiya qiladigan har qanday satrni qaytaradi (GSM da IMEI, CDMA uchun MEID).

AndroidManifest.xml faylida sizga quyidagi ruxsat kerak boʻladi:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
person Anubhav    schedule 25.09.2019
comment
U eskirgan - person Googlian; 23.10.2019

Ha, har bir Android qurilmasi noyob seriya raqamlariga ega, uni ushbu koddan olishingiz mumkin. Build.SERIAL. E'tibor bering, u faqat API 9-darajasida qo'shilgan va u barcha qurilmalarda mavjud bo'lmasligi mumkin. Oldingi platformalarda noyob identifikatorni olish uchun siz MAC manzili yoki IMEI kabi narsalarni o'qishingiz kerak bo'ladi.

person Stephan John    schedule 11.09.2019

SystemInfo.deviceUniqueIdentifier-ni tekshiring

Hujjatlar: http://docs.unity3d.com/Documentation/ScriptReference/SystemInfo-deviceUniqueIdentifier.html

Noyob qurilma identifikatori. Har bir qurilma uchun noyob bo'lishi kafolatlangan (Faqat o'qish).

iOS: iOS7-dan oldingi qurilmalarda u MAC manzilining xeshini qaytaradi. iOS7 qurilmalarida u UIDevice identifierForVendor yoki biron sababga ko'ra muvaffaqiyatsiz bo'lsa, ASIdentifierManager advertisingIdentifier bo'ladi.

person Ciul    schedule 06.01.2014

Qurilma identifikatorini faqat bir marta oling va keyin uni ma'lumotlar bazasida yoki faylda saqlang. Bunday holda, agar u ilovaning birinchi yuklanishi bo'lsa, u identifikatorni yaratadi va uni saqlaydi. Keyingi safar u faqat faylda saqlangan identifikatorni oladi.

person TootsieRockNRoll    schedule 21.10.2013
comment
Maqsad, ilova oʻchirilgan va qayta oʻrnatilganda omon qoladigan identifikatorga ega boʻlishdir. Identifikatorni ma'lumotlar bazasiga saqlash yordam bermaydi, chunki ilova o'chirilganda ma'lumotlar bazasi o'chiriladi. - person Ted Hopp; 21.10.2013

Foydalanuvchi identifikatorini olish uchun siz Google Play Litsenziyalash kutubxonasidan foydalanishingiz mumkin.

Ushbu kutubxonani yuklab olish uchun SDK Manager => SDK Tools-ni oching. Yuklab olingan kutubxona fayllariga yo'l:

path_to_android_sdk_on_your_pc/extras/google/market_licensing/library

Kutubxonani loyihangizga qo'shing (uning fayllarini shunchaki nusxalashingiz mumkin).

Keyin sizga Policy interfeysini bir oz amalga oshirish kerak (siz shunchaki kutubxonadagi ikkita fayldan birini ishlatishingiz mumkin: ServerManagedPolicy yoki StrictPolicy).

Foydalanuvchi identifikatori processServerResponse() funksiyasi ichida sizga taqdim etiladi:

public void processServerResponse(int response, ResponseData rawData) {
    if(rawData != null) {
        String userId = rawData.userId
        // use/save the value
    }
    // ...
}

Keyin LicenseChecker ni siyosat bilan qurishingiz va checkAccess() funksiyasini chaqirishingiz kerak. Buni qanday qilish kerakligiga misol sifatida MainActivity.java dan foydalaning. MainActivity.java ushbu jild ichida joylashgan:

path_to_android_sdk_on_your_pc/extras/google/market_licensing/sample/src/com/example/android/market/licensing

AndroidManifest.xml faylingizga CHECK_LICENSE ruxsatini qo‘shishni unutmang.

Litsenziyalash kutubxonasi haqida batafsil: https://developer.android.com/google/play/licensing

person Vitaly Zinchenko    schedule 03.08.2019

Android Android O dan keyin apparat bilan bog'liq identifikatorni cheklaydi, shuning uchun Android_Id noyob identifikator uchun yechimdir, lekin qurilma reflektor paytida muammo yuzaga keladi, bu muammoni bartaraf etish uchun yangi android_id hosil qiladi, biz DRUMIDdan foydalanishimiz mumkin.

val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
val drumIDByteArray = MediaDrm(WIDEVINE_UUID).getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)

val drumID = android.util.Base64.encodeToString(drumIDByteArray,android.util.Base64.DEFAULT)
person jai khambhayta    schedule 19.05.2020

Wi-Fi-ga ulanishga harakat qilganingizda tasodifiy manzildan foydalanganingiz yoki ishlatmaganligingizdan va Wi-Fi yoqilgan yoki o'chirilganligidan qat'i nazar, quyidagi kod yordamida Wi-Fi mac manzilini olasiz.

Men quyidagi havoladagi usuldan foydalandim va tasodifiy manzil o'rniga aniq manzilni olish uchun kichik o'zgartirish qo'shdim:

Android 6.0 da MAC manzilini olish

public static String getMacAddr() {
StringBuilder res1 = new StringBuilder();
try {
List<NetworkInterface> all =     
Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {    
if (!nif.getName().equalsIgnoreCase("p2p0")) continue;

        byte[] macBytes = nif.getHardwareAddress();
        if (macBytes == null) {
            continue;
        }

        res1 = new StringBuilder();
        for (byte b : macBytes) {
            res1.append(String.format("%02X:",b));
        }

        if (res1.length() > 0) {
            res1.deleteCharAt(res1.length() - 1);
        }
    }
} catch (Exception ex) {
}
return res1.toString();

}

person Abdallah AlTaher    schedule 23.09.2020