क्या एंड्रॉइड डिवाइस में एक अद्वितीय आईडी है, और यदि हां, तो जावा का उपयोग करके इसे एक्सेस करने का एक सरल तरीका क्या है?
क्या एंड्रॉइड डिवाइस में एक अद्वितीय आईडी है, और यदि हां, तो जावा का उपयोग करके इसे एक्सेस करने का एक सरल तरीका क्या है?
जवाबों:
Settings.Secure#ANDROID_ID
प्रत्येक उपयोगकर्ता 64-बिट हेक्स स्ट्रिंग के लिए एक अद्वितीय के रूप में एंड्रॉइड आईडी देता है ।
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
अद्यतन : Android के हाल के संस्करणों के रूप में, के साथ कई मुद्दों ANDROID_ID
को हल कर दिया गया है, और मेरा मानना है कि यह दृष्टिकोण अब आवश्यक नहीं है। कृपया एंथनी के जवाब पर एक नज़र डालें ।
पूर्ण प्रकटीकरण: मेरे ऐप ने मूल रूप से नीचे दिए गए दृष्टिकोण का उपयोग किया था लेकिन अब इस दृष्टिकोण का उपयोग नहीं करता है, और हम अब एंड्रॉइड डेवलपर ब्लॉग प्रविष्टि में उल्लिखित दृष्टिकोण का उपयोग करते हैं जो एमएमबी के उत्तर लिंक (अर्थात्, उत्पन्न और बचत UUID#randomUUID()
) के लिए लिंक का उपयोग करता है ।
इस सवाल के कई जवाब हैं, जिनमें से अधिकांश केवल समय के "कुछ" काम करेंगे, और दुर्भाग्य से यह काफी अच्छा नहीं है।
उपकरणों के मेरे परीक्षणों के आधार पर (सभी फोन, जिनमें से कम से कम एक सक्रिय नहीं है):
TelephonyManager.getDeviceId()
TelephonyManager.getSimSerialNumber()
getSimSerialNumber()
(उम्मीद के मुताबिक)ANDROID_ID
ANDROID_ID
और TelephonyManager.getDeviceId()
- जब तक कि सेटअप के दौरान Google खाता जोड़ा गया हो।इसलिए यदि आप डिवाइस के लिए कुछ अनूठा चाहते हैं, तो TM.getDeviceId()
करना चाहिए तो पर्याप्त चाहिए। स्पष्ट रूप से कुछ उपयोगकर्ता दूसरों की तुलना में अधिक पागल हैं, इसलिए हो सकता है कि यह 1 या उससे अधिक पहचानकर्ताओं के लिए उपयोगी हो, ताकि स्ट्रिंग अभी भी डिवाइस के लिए लगभग अद्वितीय है, लेकिन उपयोगकर्ता के वास्तविक डिवाइस की स्पष्ट रूप से पहचान नहीं करता है। उदाहरण के लिए, String.hashCode()
यूयूआईडी के साथ संयुक्त , उपयोग करना :
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();
परिणाम कुछ इस तरह हो सकता है: 00000000-54b3-e7c7-0000-000046bffd97
यह मेरे लिए काफी अच्छा काम करता है।
जैसा कि नीचे रिचर्ड का उल्लेख है, यह मत भूलो कि आपको TelephonyManager
संपत्तियों को पढ़ने की अनुमति की आवश्यकता है , इसलिए इसे अपने प्रकट में जोड़ें:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
आयात लिबास
import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
मैनिफ़ेस्ट फ़ाइल में जोड़ना याद रखें । यदि डेटाबेस में स्टोर किया जाता है, तो लौटा हुआ स्ट्रिंग 36 वर्ण लंबा होता है।
यूनिक आईडी बनाने के बारे में हर स्टैक ओवरफ्लो पोस्ट को पढ़ने के बाद, Google डेवलपर ब्लॉग और एंड्रॉइड डॉक्यूमेंटेशन, मुझे लगता है कि 'स्यूडो आईडी' सबसे अच्छा संभव विकल्प है।
Psuedo कोड:
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)
हमारे सभी विकल्पों को पोस्ट करने के लिए @stansult का धन्यवाद (इस स्टैक ओवरफ्लो प्रश्न में) ।
उपयोगकर्ता ईमेल - सॉफ्टवेयर
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
या<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
( एंड्रॉइड डिवाइस का प्राथमिक ई-मेल पता कैसे प्राप्त करें )उपयोगकर्ता फोन नंबर - सॉफ्टवेयर
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
IMEI - हार्डवेयर (केवल फोन, आवश्यकताएं android.permission.READ_PHONE_STATE
)
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
एंड्रॉइड आईडी - हार्डवेयर (शून्य हो सकता है, फ़ैक्टरी रीसेट पर बदल सकता है, रूट किए गए डिवाइस पर बदला जा सकता है)
WLAN MAC पता - हार्डवेयर (ज़रूरतें android.permission.ACCESS_WIFI_STATE
)
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
ब्लूटूथ मैक पता - हार्डवेयर (ब्लूटूथ, आवश्यकता वाले उपकरण android.permission.BLUETOOTH
)
<uses-permission android:name="android.permission.BLUETOOTH "/>
स्यूडो-यूनिक आईडी - सॉफ्टवेयर (सभी Android उपकरणों के लिए)
मुझे पता है कि अनुमतियों का उपयोग किए बिना एक अद्वितीय आईडी प्राप्त करने का कोई 'सही' तरीका नहीं है; हालाँकि, कभी-कभी हमें केवल डिवाइस इंस्टॉलेशन को ट्रैक करने की आवश्यकता होती है। जब एक अद्वितीय आईडी बनाने की बात आती है, तो हम पूरी तरह से सूचना के आधार पर 'छद्म अद्वितीय आईडी' बना सकते हैं जो Android API हमें बिना अतिरिक्त अनुमतियों के उपयोग के देता है। इस तरह, हम उपयोगकर्ता को सम्मान दिखा सकते हैं और साथ ही एक अच्छा उपयोगकर्ता अनुभव प्रदान करने का प्रयास कर सकते हैं।
एक छद्म-अद्वितीय आईडी के साथ, आप वास्तव में केवल इस तथ्य पर चलते हैं कि इस तथ्य के आधार पर डुप्लिकेट हो सकते हैं कि समान डिवाइस हैं। आप इसे और अधिक अद्वितीय बनाने के लिए संयुक्त विधि को घुमा सकते हैं; हालांकि, कुछ डेवलपर्स को डिवाइस इंस्टॉल को ट्रैक करने की आवश्यकता होती है और यह इसी तरह के उपकरणों के आधार पर चाल या प्रदर्शन करेगा।
यदि उनका Android उपकरण API 9 या अधिक है, तो यह 'Build.SERIAL' क्षेत्र के कारण अद्वितीय होने की गारंटी है।
याद रखें , आप तकनीकी रूप से केवल उन लगभग 0.5% उपयोगकर्ताओं को याद कर रहे हैं जिनके पास API <9 है । तो आप बाकी पर ध्यान केंद्रित कर सकते हैं: यह 99.5% उपयोगकर्ता हैं!
यदि उपयोगकर्ता का एंड्रॉइड डिवाइस एपीआई 9 से कम है; उम्मीद है, उन्होंने फ़ैक्टरी रीसेट नहीं किया है और उनका 'Secure.ANDROID_ID' संरक्षित रहेगा या 'शून्य' नहीं होगा। (देखें http://developer.android.com/about/dashboards/index.html )
यदि अन्य सभी विफल हो जाते हैं, यदि उपयोगकर्ता के पास एपीआई 9 (जिंजरब्रेड से कम) है, तो अपने डिवाइस को रीसेट कर दिया है या 'Secure.ANDROID_ID' रिटर्न 'शून्य' कर दिया है, तो बस लौटी आईडी पूरी तरह से उनके एंड्रॉइड फोन की जानकारी से दूर होगी। यह वह जगह है जहां टकराव हो सकता है।
परिवर्तन:
कृपया नीचे दी गई विधि पर एक नज़र डालें:
/**
* Return pseudo unique ID
* @return ID
*/
public static String getUniquePsuedoID() {
// If all else fails, if the user does have lower than API 9 (lower
// than Gingerbread), has reset their device or 'Secure.ANDROID_ID'
// returns 'null', then simply the ID returned will be solely based
// off their Android device information. This is where the collisions
// can happen.
// Thanks http://www.pocketmagic.net/?p=1662!
// Try not to use DISPLAY, HOST or ID - these items could change.
// If there are collisions, there will be overlapping data
String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);
// Thanks to @Roman SL!
// https://stackoverflow.com/a/4789483/950427
// Only devices with API >= 9 have android.os.Build.SERIAL
// http://developer.android.com/reference/android/os/Build.html#SERIAL
// If a user upgrades software or roots their device, there will be a duplicate entry
String serial = null;
try {
serial = android.os.Build.class.getField("SERIAL").get(null).toString();
// Go ahead and return the serial for api => 9
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
// String needs to be initialized
serial = "serial"; // some value
}
// Thanks @Joe!
// https://stackoverflow.com/a/2853253/950427
// Finally, combine the values we have found by using the UUID class to create a unique identifier
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
Google Play डेवलपर के कंसोल से:
1 अगस्त 2014 से, Google Play डेवलपर प्रोग्राम नीति को किसी भी अन्य विज्ञापनदाताओं को किसी भी विज्ञापन उद्देश्यों के लिए किसी अन्य स्थायी पहचानकर्ता के बदले विज्ञापन आईडी का उपयोग करने के लिए सभी नए एप्लिकेशन अपलोड और अपडेट की आवश्यकता होती है। और अधिक जानें
कार्यान्वयन :
अनुमति:
<uses-permission android:name="android.permission.INTERNET" />
कोड:
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();
}
स्रोत / डॉक्स:
http://developer.android.com/google/play-services/id.html http://developer.android.com/reference/com/google/android/gms/ads/identifier/AdolarsIdClient.html
यह इरादा है कि विज्ञापन आईडी Google उद्देश्यों के लिए विज्ञापन पहचान के अन्य उपयोगों (जैसे कि सेटिंग में ANDROID_ID के उपयोग के रूप में) को पूरी तरह से बदल देती है। ऐसे मामले जहां Google Play सेवाएं उपलब्ध नहीं हैं, GooglePlayServicesNotAvailableException getAdpretIdInfo () द्वारा फेंके जाने के संकेत हैं।
http://en.kioskea.net/faq/34732-android-reset-your-advertising-id
मैंने हर उस लिंक को संदर्भित करने की कोशिश की है जिससे मैंने जानकारी ली थी। यदि आप गायब हैं और शामिल करने की आवश्यकता है, तो कृपया टिप्पणी करें!
Build
OS अपडेट पर वर्ग परिवर्तन नहीं होगा ? खासकर अगर एपीआई अपडेट हो गया? यदि हां, तो आप कैसे गारंटी देते हैं कि यह अद्वितीय है? (आपके लिखे तरीके के बारे में बात करते हुए)
जैसा कि डेव वेब का उल्लेख है, एंड्रॉइड डेवलपर ब्लॉग में एक लेख है जो इसे कवर करता है। उनका पसंदीदा समाधान उपकरणों के बजाय ऐप इंस्टॉल को ट्रैक करना है, और यह अधिकांश उपयोग के मामलों के लिए अच्छी तरह से काम करेगा। ब्लॉग पोस्ट आपको वह काम करने के लिए आवश्यक कोड दिखाएगा, और मैं आपको इसकी जांच करने की सलाह देता हूं।
हालाँकि, यदि आप ऐप इंस्टॉलेशन आइडेंटिफायर के बजाय डिवाइस आइडेंटिफायर की जरूरत है तो ब्लॉग पोस्ट समाधानों पर चर्चा करता है। मैंने Google पर किसी व्यक्ति के साथ उस घटना में कुछ वस्तुओं पर कुछ अतिरिक्त स्पष्टीकरण प्राप्त करने के लिए बात की थी जो आपको करने की आवश्यकता है। यहाँ मैंने उन डिवाइस पहचानकर्ताओं के बारे में पता लगाया है जिनका उल्लेख उपरोक्त ब्लॉग पोस्ट में नहीं किया गया है:
Google की सिफारिशों के आधार पर, मैंने एक वर्ग लागू किया है जो ANDROID_ID को बीज के रूप में उपयोग करते हुए प्रत्येक डिवाइस के लिए एक अद्वितीय UUID उत्पन्न करेगा, जहां उपयुक्त हो, आवश्यक रूप से TelephonyManager.getDeviceId () पर वापस गिर रहा है, और यदि वह विफल रहता है, तो एक यादृच्छिक रूप से उत्पन्न अद्वितीय UUID का सहारा लेना यह एप रीस्टार्ट (लेकिन एप री-इंस्टॉलेशन नहीं) है।
ध्यान दें कि जिन डिवाइसों में डिवाइस आईडी पर कमबैक करना है, उनके लिए यूनीक आईडी WILL फैक्ट्री रिसेट्स में बनी रहती है। इसके लिए जागरूक होना कुछ है। यदि आपको यह सुनिश्चित करने की आवश्यकता है कि फ़ैक्टरी रीसेट आपकी अद्वितीय आईडी को रीसेट कर देगा, तो आप डिवाइस आईडी के बजाय सीधे यादृच्छिक यूयूआईडी पर वापस गिरने पर विचार कर सकते हैं।
फिर, यह कोड डिवाइस आईडी के लिए है, न कि ऐप इंस्टॉलेशन आईडी के लिए। ज्यादातर स्थितियों के लिए, एक ऐप इंस्टॉलेशन आईडी संभवतः वह है जो आप खोज रहे हैं। लेकिन अगर आपको डिवाइस आईडी की आवश्यकता है, तो निम्नलिखित कोड शायद आपके लिए काम करेगा।
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;
}
}
यहाँ कोड है कि रेटो मीयर ने इस वर्ष Google I / O प्रस्तुति में उपयोग किया था ताकि उपयोगकर्ता को एक अद्वितीय आईडी मिल सके:
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;
}
यदि आप इसे क्लाउड पर प्राथमिकताएं भेजने के लिए एक बैकअप रणनीति के साथ जोड़ते हैं (रेटो की बात में भी वर्णित है , तो आपके पास एक आईडी होनी चाहिए जो डिवाइस को मिटा दिए जाने के बाद किसी उपयोगकर्ता से चिपक जाती है या प्रतिस्थापित हो जाती है। मैं इसे उपयोग करने की योजना बना रहा हूं। विश्लेषण में आगे जा रहा है (दूसरे शब्दों में, मैंने अभी तक ऐसा नहीं किया है :)।
इसके अलावा, आप वाई-फाई एडेप्टर के मैक पते पर विचार कर सकते हैं। इस प्रकार लिया गया:
WifiManager wm = (WifiManager)Ctxt.getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo().getMacAddress();
अनुमति की आवश्यकता है android.permission.ACCESS_WIFI_STATE
मेनिफेस्ट में ।
वाई-फाई कनेक्ट नहीं होने पर भी उपलब्ध होने की सूचना दी। यदि ऊपर दिए गए उत्तर में से जो यह अपने कई उपकरणों पर कोशिश करता है, तो यह अच्छा होगा।
कुछ उपकरणों पर, वाई-फाई बंद होने पर यह उपलब्ध नहीं होता है।
नोट: Android 6.x से, यह लगातार नकली मैक पते देता है:02:00:00:00:00:00
android.permission.ACCESS_WIFI_STATE
02:00:00:00:00:00
यहाँ बल्कि उपयोगी जानकारी है ।
इसमें पांच अलग-अलग आईडी प्रकार शामिल हैं:
android.permission.READ_PHONE_STATE
)android.permission.ACCESS_WIFI_STATE
)android.permission.BLUETOOTH
)आधिकारिक एंड्रॉइड डेवलपर्स ब्लॉग में अब इस विषय के बारे में एक पूर्ण लेख है, आइडेंटिफिकेशन ऐप प्रतिष्ठान ।
पर गूगल आई / ओ रीटो मायर इस जो प्रतिष्ठानों भर में उपयोगकर्ताओं को ट्रैक करने के लिए सबसे डेवलपर्स की जरूरतों को पूरा करना चाहिए कि दृष्टिकोण करने के लिए एक मजबूत जवाब का विमोचन किया। एंथनी नोलन अपने जवाब में दिशा दिखाते हैं, लेकिन मुझे लगा कि मैं पूरा तरीका लिखूंगा ताकि दूसरे आसानी से देख सकें कि यह कैसे करना है (विवरण निकालने में मुझे थोड़ा समय लगा)।
यह दृष्टिकोण आपको एक अनाम, सुरक्षित उपयोगकर्ता आईडी देगा जो विभिन्न उपकरणों (प्राथमिक Google खाते के आधार पर) और इंस्टॉल के दौरान उपयोगकर्ता के लिए निरंतर रहेगा। मूल दृष्टिकोण एक यादृच्छिक उपयोगकर्ता आईडी उत्पन्न करना है और इसे ऐप्स की साझा प्राथमिकताओं में संग्रहीत करना है। फिर आप क्लाउड में Google खाते से जुड़ी साझा प्राथमिकताओं को संग्रहीत करने के लिए Google के बैकअप एजेंट का उपयोग करते हैं।
चलो पूर्ण दृष्टिकोण से गुजरते हैं। सबसे पहले, हमें एंड्रॉइड बैकअप सेवा का उपयोग करके अपने SharedPreferences के लिए एक बैकअप बनाने की आवश्यकता है। के माध्यम से अपने एप्लिकेशन को पंजीकृत करके शुरू करेंhttp://developer.android.com/google/backup/signup.html
।
Google आपको एक बैकअप सेवा कुंजी देगा जिसे आपको मैनिफ़ेस्ट में जोड़ना होगा। आपको निम्नानुसार BackupAgent का उपयोग करने के लिए एप्लिकेशन को भी बताने की आवश्यकता है:
<application android:label="MyApplication"
android:backupAgent="MyBackupAgent">
...
<meta-data android:name="com.google.android.backup.api_key"
android:value="your_backup_service_key" />
</application>
फिर आपको बैकअप एजेंट बनाने और इसे साझा करने वाले के लिए सहायक एजेंट का उपयोग करने की आवश्यकता है:
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);
}
}
बैकअप को पूरा करने के लिए आपको अपनी मुख्य गतिविधि में BackupManager का एक उदाहरण बनाना होगा:
BackupManager backupManager = new BackupManager(context);
अंत में एक उपयोगकर्ता आईडी बनाएं, यदि यह पहले से मौजूद नहीं है, और इसे साझा किए गए संदर्भों में संग्रहीत करें:
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;
}
यह User_ID अब पूरे इंस्टॉलेशन में लगातार रहेगा, भले ही उपयोगकर्ता डिवाइस को चलाए।
इस दृष्टिकोण की अधिक जानकारी के लिए रेटो की बात देखें ।
और बैकअप एजेंट को कैसे लागू किया जाए इसकी पूरी जानकारी के लिए डेटा बैकअप देखें । मैं विशेष रूप से परीक्षण पर नीचे के खंड की सलाह देता हूं क्योंकि बैकअप तुरंत नहीं होता है और इसलिए परीक्षण के लिए आपको बैकअप को मजबूर करना पड़ता है।
मुझे लगता है कि यह एक अद्वितीय आईडी के लिए कंकाल बनाने का निश्चित रूप से आग का तरीका है ... इसे देखें।
स्यूडो-यूनिक आईडी, जो सभी एंड्रॉइड डिवाइसों पर काम करता है। कुछ डिवाइसों में फोन (जैसे टैबलेट) नहीं है या किसी कारण से, आप READ_PHONE_STATE अनुमति शामिल नहीं करना चाहते हैं। आप अभी भी रॉम संस्करण, निर्माता का नाम, सीपीयू प्रकार, और अन्य हार्डवेयर विवरण जैसे विवरण पढ़ सकते हैं, यदि आप सीरियल कुंजी की जांच, या अन्य सामान्य प्रयोजनों के लिए आईडी का उपयोग करना चाहते हैं तो यह अच्छी तरह से अनुकूल होगा। इस तरह से गणना की गई आईडी अद्वितीय नहीं होगी: एक ही आईडी (एक ही हार्डवेयर और रोम छवि के आधार पर) के साथ दो डिवाइस ढूंढना संभव है, लेकिन वास्तविक दुनिया के अनुप्रयोगों में परिवर्तन नगण्य हैं। इस उद्देश्य के लिए आप बिल्ड क्लास का उपयोग कर सकते हैं:
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
बिल्ड के अधिकांश सदस्य स्ट्रिंग्स हैं, जो हम यहां कर रहे हैं वह उनकी लंबाई लेने के लिए है और इसे एक अंक में मोडुलो के माध्यम से बदलना है। हमारे पास 13 ऐसे अंक हैं और हम दो और सामने जोड़ रहे हैं (35) IMEI के समान आकार की आईडी (15 अंक)। यहां अन्य संभावनाएं भी अच्छी हैं, बस इन तारों पर एक नजर है। कुछ इस तरह लौटता है 355715565309247
। कोई विशेष अनुमति की आवश्यकता नहीं है, जिससे यह दृष्टिकोण बहुत सुविधाजनक हो।
(अतिरिक्त जानकारी: ऊपर दी गई तकनीक को पॉकेट मैजिक के एक लेख से कॉपी किया गया था ।)
निम्न कोड एक छिपे हुए एंड्रॉइड एपीआई का उपयोग करके डिवाइस सीरियल नंबर देता है। लेकिन, यह कोड सैमसंग गैलेक्सी टैब पर काम नहीं करता है क्योंकि इस डिवाइस पर "ro.serialno" सेट नहीं है।
String serial = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
}
catch (Exception ignored) {
}
ro.serialno
जिसका उपयोग उत्पन्न करने के लिए किया जाता है Settings.Secure.ANDROID_ID
। इसलिए वे मूल रूप से एक ही मूल्य के विभिन्न प्रतिनिधित्व हैं।
ANDROID_ID
प्राप्त होता है।
android.os.Build.SERIAL
android.os.Build.SERIAL
एंड्रॉयड हे में हटा दिया जाएगा, देख android-developers.googleblog.com/2017/04/...
यह एक सरल प्रश्न है, कोई सरल उत्तर नहीं है।
इससे अधिक, यहां सभी मौजूदा उत्तर हैं कि क्या यह पुराना है या अविश्वसनीय है।
तो अगर आप 2020 में एक समाधान के लिए खोज रहे हैं ।
यहां कुछ बातों को ध्यान में रखा गया है:
सभी हार्डवेयर आधारित पहचानकर्ता (SSAID, IMEI, MAC, इत्यादि) गैर-Google के उपकरणों (पिक्सेल और नेक्सस को छोड़कर सब कुछ) के लिए अविश्वसनीय हैं, जो दुनिया भर में सक्रिय उपकरणों के 50% से अधिक हैं। इसलिए आधिकारिक एंड्रॉइड पहचानकर्ता सर्वोत्तम प्रथाओं को स्पष्ट रूप से बताता है:
SSAID (Android ID), IMEI, MAC एड्रेस आदि जैसे हार्डवेयर पहचानकर्ताओं का उपयोग करने से बचें ...
यह अधिकांश उत्तरों को अमान्य बना देता है। अलग-अलग एंड्रॉइड सुरक्षा अपडेट्स के कारण, उनमें से कुछ को नए और सख्त रनटाइम अनुमतियों की आवश्यकता होती है, जिन्हें उपयोगकर्ता द्वारा केवल नकार दिया जा सकता है।
उदाहरण के रूप में CVE-2018-9489
जो उपरोक्त सभी वाईफ़ाई आधारित तकनीकों को प्रभावित करता है।
यह उन पहचानकर्ताओं को न केवल अविश्वसनीय बनाता है, बल्कि कई मामलों में अस्वीकार्य भी बनाता है।
तो सरल शब्दों में: उन तकनीकों का उपयोग न करें ।
यहाँ कई अन्य उत्तर AdvertisingIdClient
भी उपयोग करने का सुझाव दे रहे हैं , जो कि असंगत भी है, क्योंकि इसके डिज़ाइन द्वारा इसका उपयोग केवल विज्ञापनों की रूपरेखा के लिए किया जाना चाहिए। यह आधिकारिक संदर्भ में भी कहा गया है
उपयोगकर्ता प्रोफाइलिंग या विज्ञापनों के मामलों के लिए केवल एक विज्ञापन आईडी का उपयोग करें
यह न केवल डिवाइस पहचान के लिए अविश्वसनीय है, बल्कि आपको विज्ञापन ट्रैकिंग के बारे में उपयोगकर्ता की गोपनीयता का भी पालन करना चाहिए नीति के , जो स्पष्ट रूप से बताता है कि उपयोगकर्ता किसी भी समय इसे रीसेट या ब्लॉक कर सकता है।
तो यह भी उपयोग न करें ।
चूँकि आपके पास वांछित स्थिर विश्वव्यापी अद्वितीय और विश्वसनीय उपकरण पहचानकर्ता नहीं हो सकता है। Android का आधिकारिक संदर्भ सुझाव:
भुगतान धोखाधड़ी की रोकथाम और टेलीफोनी को छोड़कर, अन्य सभी उपयोग के मामलों के लिए जब भी संभव हो एक FirebaseInstanceId या एक निजी रूप से संग्रहीत GUID का उपयोग करें।
यह डिवाइस पर एप्लिकेशन इंस्टॉलेशन के लिए अद्वितीय है, इसलिए जब उपयोगकर्ता एप्लिकेशन को अनइंस्टॉल करता है - यह मिटा दिया जाता है, तो यह 100% विश्वसनीय नहीं है, लेकिन यह अगली सबसे अच्छी बात है।
अपने ग्रेड में नवीनतम फायरबेस-मैसेजिंग निर्भरताFirebaseInstanceId
जोड़ने के लिए उपयोग करें
implementation 'com.google.firebase:firebase-messaging:20.2.0'
और एक पृष्ठभूमि थ्रेड में नीचे दिए गए कोड का उपयोग करें:
String reliableIdentifier = FirebaseInstanceId.getInstance().getId();
यदि आपको अपने दूरस्थ सर्वर पर डिवाइस पहचान को संग्रहीत करने की आवश्यकता है, तो इसे (सादे पाठ) के रूप में संग्रहीत न करें, लेकिन नमक के साथ एक हैश ।
आज यह न केवल एक सर्वोत्तम प्रथा है, आपको वास्तव में इसे GDPR के अनुसार करना होगा - पहचानकर्ता और समान नियम।
नीचे दिए गए कोड का उपयोग करके, आप एक स्ट्रिंग के रूप में एंड्रॉइड ओएस डिवाइस की अनूठी डिवाइस आईडी प्राप्त कर सकते हैं।
deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID);
एक सीरियल फ़ील्ड को जोड़ा गया थाBuild
एपीआई स्तर 9 (एंड्रॉइड 2.3 - जिंजरब्रेड) में कक्षा में । प्रलेखन का कहना है कि यह हार्डवेयर सीरियल नंबर का प्रतिनिधित्व करता है। इस प्रकार यह अद्वितीय होना चाहिए, अगर यह डिवाइस पर मौजूद है।
मुझे नहीं पता कि यह एपीआई स्तर> = 9 के साथ सभी उपकरणों द्वारा वास्तव में समर्थित (= शून्य नहीं) है।
एक चीज जो मैं जोड़ूंगा - मेरे पास उन अद्वितीय स्थितियों में से एक है।
का उपयोग करते हुए:
deviceId = Secure.getString(this.getContext().getContentResolver(), Secure.ANDROID_ID);
यह बताते हुए कि मेरी Viewsonic G Tablet एक डिवाइसआईडी की रिपोर्ट करती है, जो अशक्त नहीं है, हर एक जी टैबलेट एक ही नंबर की रिपोर्ट करता है।
यह दिलचस्प खेल बनाता है "पॉकेट एम्पायर" जो आपको "अद्वितीय" डिवाइसआईडी के आधार पर किसी के खाते में त्वरित पहुंच प्रदान करता है।
मेरे डिवाइस में सेल रेडियो नहीं है।
9774d56d682e549c
?
आपके Android एप्लिकेशन के लिए एक विशिष्ट पहचानकर्ता कैसे प्राप्त किया जाए, इस बारे में विस्तृत निर्देशों के लिए, आधिकारिक Android डेवलपर्स ब्लॉग पोस्टिंग आइडेंटीटीज़ टूल देखें ।
ऐसा लगता है कि आपके लिए सबसे अच्छा तरीका है कि आप खुद को इंस्टॉलेशन के लिए जनरेट करें और बाद में जब एप्लिकेशन दोबारा लॉन्च किया जाए तो इसे पढ़ें।
मुझे व्यक्तिगत रूप से यह स्वीकार्य लगता है लेकिन आदर्श नहीं। सभी उदाहरणों में एंड्रॉइड द्वारा प्रदान किया गया कोई भी पहचानकर्ता नहीं है क्योंकि अधिकांश फोन के रेडियो स्टेट्स (वाई-फाई ऑन / ऑफ, सेलुलर ऑन / ऑफ, ब्लूटूथ ऑन / ऑफ) पर निर्भर हैं। अन्य, जैसे Settings.Secure.ANDROID_ID
निर्माता द्वारा लागू किया जाना चाहिए और अद्वितीय होने की गारंटी नहीं है।
निम्नलिखित एक इंस्टॉलेशन फ़ाइल में डेटा लिखने का एक उदाहरण है जिसे किसी भी अन्य डेटा के साथ संग्रहीत किया जाएगा जो एप्लिकेशन स्थानीय रूप से बचाता है।
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();
}
}
वर्ग फ़ाइल में नीचे कोड जोड़ें:
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 में जोड़ें:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
TelephonyManager
और ANDROID_ID
, के रूप में एक Android OS डिवाइस की अद्वितीय डिवाइस आईडी इसके द्वारा प्राप्त की जाती है: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);
}
लेकिन मैं Google द्वारा सुझाई गई विधि की दृढ़ता से अनुशंसा करता हूं, पहचानना ऐप प्रतिष्ठान देखें ।
उन ANDROID_ID
मुद्दों के आसपास काम करने के लिए बहुत सारे अलग-अलग दृष्टिकोण हैं ( null
कभी-कभी हो सकते हैं या किसी विशिष्ट मॉडल के उपकरण हमेशा एक ही आईडी लौटा सकते हैं) पेशेवरों और के साथ:
मैं खुद एंड्रॉइड के लिए एक मौजूदा OpenUDID कार्यान्वयन ( https://github.com/ylechelle/OpenUDID देखें ) का उपयोग करना पसंद करता हूं ( https://github.com/vieux/OpenUDID देखें )। यह ANDROID_ID
ऊपर वर्णित उन मुद्दों के लिए कमियों के साथ एकीकृत करना और उपयोग करना आसान है ।
कैसे के बारे में आईएमईआई । यह Android या अन्य मोबाइल उपकरणों के लिए अद्वितीय है।
यहां बताया गया है कि मैं कैसे विशिष्ट आईडी बना रहा हूं:
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;
}
मेरे दो सेंट - एनबी यह एक डिवाइस (इरेट) यूनिक आईडी के लिए है - इंस्टॉलेशन एक नहीं जैसा कि एंड्रॉइड डेवलपर्स के ब्लॉग में चर्चा की गई है ।
ध्यान दें कि @emmby द्वारा प्रदान किया गया समाधान प्रति एप्लिकेशन ID में वापस आता है क्योंकि SharedPreferences प्रक्रियाओं के दौरान सिंक्रनाइज़ नहीं किए जाते हैं ( यहां और यहां देखें )। इसलिए मैंने इससे पूरी तरह परहेज किया।
इसके बजाय, मैंने एक एनरम में एक डिवाइस (डिवाइस) आईडी प्राप्त करने के लिए विभिन्न रणनीतियों का एनकाउंटर किया - एनुम स्थिरांक के क्रम को बदलने से आईडी प्राप्त करने के विभिन्न तरीकों की प्राथमिकता प्रभावित होती है। पहली गैर-नल आईडी लौटा दी जाती है या एक अपवाद फेंक दिया जाता है (जैसा कि अच्छे जावा अभ्यास के अनुसार अशक्त अर्थ नहीं देता है)। इसलिए उदाहरण के लिए मेरे पास एक पहले TELEPHONY है - लेकिन एक अच्छा डिफ़ॉल्ट विकल्प ANDROID_ID बीटा होगा:
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);
}
}
}
यहां 30+ उत्तर हैं और कुछ समान हैं और कुछ अद्वितीय हैं। यह उत्तर उन कुछ जवाबों पर आधारित है। उनमें से एक है @Lenn गुड़िया का जवाब।
यह 3 आईडी को जोड़ती है और 32 अंकों की हेक्स स्ट्रिंग बनाता है। इसने मेरे लिए बहुत अच्छा काम किया है।
3 आईडी हैं:
Pseudo-ID - यह भौतिक उपकरण विशिष्टताओं
ANDROID_ID - ब्लूटूथ पते के आधार पर उत्पन्न होता हैSettings.Secure.ANDROID_ID
- ब्लूटूथ एडाप्टर पता
यह कुछ इस तरह लौटेगा: 551F27C060712A72730B0A0F734064B1
नोट: आप हमेशा longId
स्ट्रिंग में अधिक आईडी जोड़ सकते हैं । उदाहरण के लिए, सीरियल #। वाईफाई एडेप्टर पता। आईएमईआई। इस तरह आप इसे प्रति डिवाइस अधिक विशिष्ट बना रहे हैं।
@SuppressWarnings("deprecation")
@SuppressLint("HardwareIds")
public static String generateDeviceIdentifier(Context context) {
String pseudoId = "35" +
Build.BOARD.length() % 10 +
Build.BRAND.length() % 10 +
Build.CPU_ABI.length() % 10 +
Build.DEVICE.length() % 10 +
Build.DISPLAY.length() % 10 +
Build.HOST.length() % 10 +
Build.ID.length() % 10 +
Build.MANUFACTURER.length() % 10 +
Build.MODEL.length() % 10 +
Build.PRODUCT.length() % 10 +
Build.TAGS.length() % 10 +
Build.TYPE.length() % 10 +
Build.USER.length() % 10;
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String btId = "";
if (bluetoothAdapter != null) {
btId = bluetoothAdapter.getAddress();
}
String longId = pseudoId + androidId + btId;
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(longId.getBytes(), 0, longId.length());
// get md5 bytes
byte md5Bytes[] = messageDigest.digest();
// creating a hex string
String identifier = "";
for (byte md5Byte : md5Bytes) {
int b = (0xFF & md5Byte);
// if it is a single digit, make sure it have 0 in front (proper padding)
if (b <= 0xF) {
identifier += "0";
}
// add number to string
identifier += Integer.toHexString(b);
}
// hex string to uppercase
identifier = identifier.toUpperCase();
return identifier;
} catch (Exception e) {
Log.e("TAG", e.toString());
}
return "";
}
longId
और किसी फ़ाइल में संग्रहीत करना, इसे सबसे विशिष्ट पहचानकर्ता बना देगा:String uuid = UUID.randomUUID().toString();
longId
। इस तरह एक पंक्ति को बदलें: String longId = pseudoId + androidId + btId + UUID.randomUUID().toString();
यह गारंटी देता है कि उत्पन्न आईडी अद्वितीय होगी।
दूसरा तरीका यह है कि /sys/class/android_usb/android0/iSerial
किसी भी अनुमति के बिना किसी ऐप में उपयोग किया जाए।
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
जावा में ऐसा करने के लिए iSerial फ़ाइल खोलने और वर्णों को पढ़ने के लिए एक FileInputStream का उपयोग करना होगा। बस सुनिश्चित करें कि आप इसे अपवाद हैंडलर में लपेटते हैं, क्योंकि सभी उपकरणों में यह फ़ाइल नहीं है।
कम से कम निम्नलिखित उपकरणों को इस फ़ाइल को विश्व-पठनीय माना जाता है:
आप मेरे ब्लॉग पोस्ट को लीक करने वाले एंड्रॉइड हार्डवेयर सीरियल नंबर को बिना पढ़े ऐप में भी देख सकते हैं, जहां मैं चर्चा करता हूं कि जानकारी के लिए अन्य फाइलें क्या उपलब्ध हैं।
TelephonyManger.getDeviceId () अद्वितीय डिवाइस ID लौटाता है, उदाहरण के लिए, GSM के लिए IMEI और CDMA फोन के लिए MEID या ESN।
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String myAndroidDeviceId = mTelephony.getDeviceId();
लेकिन मैं उपयोग करने की सलाह देता हूं:
Settings.Secure.ANDROID_ID जो एक अद्वितीय 64-बिट हेक्स स्ट्रिंग के रूप में Android आईडी लौटाता है।
String myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID);
कभी-कभी TelephonyManger.getDeviceId () अशक्त वापस आ जाएगी, इसलिए एक अनूठी आईडी को आश्वस्त करने के लिए आप इसे प्रदान करेंगे:
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;
}
एक विशिष्ट एंड्रॉइड डिवाइस की हार्डवेयर पहचान के लिए आप मैक एड्रेस की जांच कर सकते हैं।
आप इसे इस तरह से कर सकते हैं:
AndroidManifest.xml में
<uses-permission android:name="android.permission.INTERNET" />
अब आपके कोड में:
List<NetworkInterface> interfacesList = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface interface : interfacesList) {
// This will give you the interface MAC ADDRESS
interface.getHardwareAddress();
}
हर Android डिवाइस में उनका कम से कम "wlan0" इंटरफ़ेस डायन WI-FI चिप होता है। यह कोड तब भी काम करता है जब WI-FI चालू नहीं होता है।
PS उनके अन्य इंटरफेस का एक गुच्छा है जो आपको MACS वाली सूची से मिलेगा लेकिन यह फोन के बीच बदल सकता है।
IMEI
सुरक्षित पाने या उपयोग करने के लिए मैं निम्नलिखित कोड का उपयोग करता हूं । ANDROID_ID
एक विकल्प के रूप में, जब डिवाइस में फोन क्षमताएं नहीं होती हैं:
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);
विशेष रूप से, Settings.Secure.ANDROID_ID
। यह 64-बिट की मात्रा है जो डिवाइस के पहले बूट होने पर जेनरेट और स्टोर की जाती है। जब डिवाइस मिटा दिया जाता है तो यह रीसेट हो जाता है।
ANDROID_ID
एक अद्वितीय उपकरण पहचानकर्ता के लिए एक अच्छा विकल्प लगता है। डाउनसाइड्स हैं: पहला, यह 2.2 से पहले एंड्रॉइड की रिलीज़ पर 100% विश्वसनीय नहीं है। (“Froyo”).
इसके अलावा, एक प्रमुख निर्माता से एक लोकप्रिय हैंडसेट में कम से कम एक व्यापक रूप से देखा गया बग है, जहां हर उदाहरण में एक ही ANDROID_ID है।
एंड्रॉइड डिवाइसों में उपलब्ध यूनीक आईडीएस को समझने के लिए। इस आधिकारिक गाइड का उपयोग करें।
विशिष्ट पहचानकर्ताओं के लिए सर्वोत्तम अभ्यास:
IMEI, मैक एड्रेस, इंस्टेंस आईडी, GUIDs, SSAID, विज्ञापन आईडी, उपकरणों को सत्यापित करने के लिए सेफ्टी नेट एपीआई।
https://developer.android.com/training/articles/user-data-ids
Google इंस्टेंस आईडी
I / O 2015 में जारी; Android पर खेल सेवाओं 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 का इरादा इस ID का उपयोग Android, Chrome और iOS में स्थापना की पहचान करने के लिए करना है।
यह एक इंस्टॉलेशन की पहचान करता है फिर एक डिवाइस, लेकिन फिर, ANDROID_ID (जो स्वीकृत उत्तर है) अब डिवाइस की पहचान नहीं करता है। ARC रनटाइम के साथ एक नया ANDROID_ID हर इंस्टॉलेशन ( यहां विवरण ) के लिए उत्पन्न होता है , ठीक इसी तरह नई इंस्टेंस आईडी। इसके अलावा, मुझे लगता है कि प्रतिष्ठानों की पहचान करना (उपकरणों का नहीं) वास्तव में हम में से अधिकांश की तलाश क्या है।
उदाहरण ID के फायदे
यह मुझे प्रतीत होता है कि Google इस उद्देश्य के लिए इसका उपयोग करने का इरादा रखता है (आपके प्रतिष्ठानों की पहचान), यह क्रॉस-प्लेटफ़ॉर्म है, और इसका उपयोग कई अन्य उद्देश्यों के लिए किया जा सकता है (ऊपर लिंक देखें)।
यदि आप GCM का उपयोग करते हैं, तो आपको अंततः इस उदाहरण ID का उपयोग करने की आवश्यकता होगी क्योंकि GCM टोकन प्राप्त करने के लिए आपको इसकी आवश्यकता है (जो पुराने GCM पंजीकरण आईडी को बदल देता है)।
नुकसान / मुद्दे
वर्तमान कार्यान्वयन (GPS 7.5) में उदाहरण ID तब सर्वर से पुनर्प्राप्त किया जाता है जब आपका ऐप इसका अनुरोध करता है। इसका मतलब है कि उपरोक्त कॉल एक अवरुद्ध कॉल है - मेरे अवैज्ञानिक परीक्षण में डिवाइस ऑनलाइन होने पर 1-3 सेकंड लगते हैं, और 0.5 - 1.0 सेकंड अगर ऑफ-लाइन (संभवतः यह है कि यह छोड़ने और उत्पन्न करने से पहले कितने समय तक इंतजार करता है यादृच्छिक आईडी)। यह एंड्रॉइड 5.1.1 और जीपीएस 7.5 के साथ नेक्सस 5 पर उत्तरी अमेरिका में परीक्षण किया गया था।
यदि आप उन उद्देश्यों के लिए आईडी का उपयोग करते हैं जो वे चाहते हैं - जैसे। ऐप प्रमाणीकरण, ऐप पहचान, जीसीएम - मुझे लगता है कि यह 1-3 सेकंड एक उपद्रव हो सकता है (आपके ऐप पर निर्भर करता है, निश्चित रूप से)।
ANDROID_ID
को पढ़ना सुनिश्चित कर रहे हैं ।