android - क्या कोई अनूठी एंड्रॉइड डिवाइस आईडी है?




uniqueidentifier (25)

Google इंस्टेंस आईडी

I / O 2015 में जारी किया गया; एंड्रॉइड पर प्ले सेवाओं 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 इस आईडी को एंड्रॉइड, क्रोम और आईओएस में इंस्टॉलेशन की पहचान के लिए इस्तेमाल करने का इरादा रखता है।

यह एक डिवाइस की बजाय एक डिवाइस की पहचान करता है, लेकिन फिर, ANDROID_ID (जो स्वीकार्य उत्तर है) अब डिवाइस को पहचानता नहीं है। एआरसी रनटाइम के साथ इस नए इंस्टेंस आईडी की तरह, प्रत्येक इंस्टॉलेशन ( यहां विवरण ) के लिए एक नया ANDROID_ID उत्पन्न होता है । साथ ही, मुझे लगता है कि इंस्टॉलेशन (डिवाइस नहीं) की पहचान करना हम में से अधिकांश वास्तव में खोज रहे हैं।

उदाहरण आईडी के फायदे

ऐसा लगता है कि Google इस उद्देश्य के लिए इसका उपयोग करने का इरादा रखता है (आपके इंस्टॉलेशन की पहचान), यह क्रॉस-प्लेटफ़ॉर्म है, और कई अन्य उद्देश्यों के लिए उपयोग किया जा सकता है (उपरोक्त लिंक देखें)।

यदि आप जीसीएम का उपयोग करते हैं, तो आपको अंततः इस इंस्टेंस आईडी का उपयोग करने की आवश्यकता होगी क्योंकि आपको जीसीएम टोकन (जो पुराने जीसीएम पंजीकरण आईडी को प्रतिस्थापित करता है) प्राप्त करने के लिए इसकी आवश्यकता है।

नुकसान / मुद्दे

वर्तमान कार्यान्वयन (जीपीएस 7.5) में जब आपका ऐप अनुरोध करता है तो इंस्टेंस आईडी किसी सर्वर से पुनर्प्राप्त की जाती है। इसका मतलब यह है कि उपर्युक्त कॉल एक अवरुद्ध कॉल है - मेरे अवैज्ञानिक परीक्षण में यदि डिवाइस ऑनलाइन है, तो 1-3 सेकेंड लगते हैं, और ऑफ-लाइन होने पर 0.5 - 1.0 सेकेंड (संभवतः यह छोड़ने और उत्पन्न करने से पहले कितना समय लगता है यादृच्छिक आईडी)। यह एंड्रॉइड 5.1.1 और जीपीएस 7.5 के साथ नेक्सस 5 पर उत्तरी अमेरिका में परीक्षण किया गया था।

यदि आप उन प्रयोजनों के लिए आईडी का उपयोग करते हैं जो वे चाहते हैं - उदाहरण के लिए। ऐप प्रमाणीकरण, ऐप पहचान, जीसीएम - मुझे लगता है कि यह 1-3 सेकंड एक उपद्रव हो सकता है (निश्चित रूप से आपके ऐप के आधार पर)।

क्या एंड्रॉइड डिवाइसों में एक अद्वितीय आईडी है, और यदि हां, तो जावा का उपयोग करके इसे एक्सेस करने का एक आसान तरीका क्या है?


आधिकारिक एंड्रॉइड डेवलपर्स ब्लॉग में अब इस विषय के बारे में एक पूर्ण लेख है, android-developers.blogspot.com/2011/03/…


एपीआई लेवल 9 (एंड्रॉइड 2.3 - जिंजरब्रेड) में कक्षा में एक Serial फ़ील्ड जोड़ा गया था Build। दस्तावेज़ीकरण का कहना है कि यह हार्डवेयर सीरियल नंबर का प्रतिनिधित्व करता है। इस प्रकार यह अद्वितीय होना चाहिए, अगर यह डिवाइस पर मौजूद है।

मुझे नहीं पता कि यह एपीआई स्तर> = 9 के साथ सभी उपकरणों द्वारा वास्तव में समर्थित है (= शून्य नहीं)।


स्ट्रिंग के रूप में एंड्रॉइड ओएस डिवाइस की अनूठी डिवाइस आईडी, का उपयोग करके TelephonyManagerऔर ANDROID_IDप्राप्त की जाती है:

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 साथ कई मुद्दों का समाधान किया गया है, और मेरा मानना ​​है कि यह दृष्टिकोण अब आवश्यक नहीं है। एंथनी के जवाब पर एक नज़र डालें।

पूर्ण प्रकटीकरण: मेरा ऐप मूल रूप से नीचे दिए गए दृष्टिकोण का उपयोग करता है लेकिन अब इस दृष्टिकोण का उपयोग नहीं करता है, और अब हम android-developers.blogspot.com/2011/03/… एंट्री में उल्लिखित दृष्टिकोण का उपयोग करते हैं, जो एम्मी के उत्तर लिंक (अर्थात्, UUID#randomUUID() उत्पन्न करना और सहेजना)।

इस सवाल के कई जवाब हैं, जिनमें से अधिकांश समय के "कुछ" काम करेंगे, और दुर्भाग्यवश यह पर्याप्त नहीं है।

उपकरणों के अपने परीक्षणों के आधार पर (सभी फोन, जिनमें से कम से कम एक सक्रिय नहीं है):

  1. परीक्षण किए गए सभी उपकरणों ने TelephonyManager.getDeviceId() लिए एक मान वापस कर दिया
  2. सभी जीएसएम डिवाइस (सभी सिम के साथ परीक्षण किए गए) ने TelephonyManager.getSimSerialNumber() लिए एक मान वापस कर दिया
  3. सभी सीडीएमए डिवाइस getSimSerialNumber() (अपेक्षित के रूप में getSimSerialNumber() लिए शून्य वापस लौटे
  4. Google खाते वाले सभी डिवाइसों ने ANDROID_ID लिए एक मान वापस कर दिया
  5. सभी सीडीएमए डिवाइसों ने ANDROID_ID और TelephonyManager.getDeviceId() दोनों के लिए एक ही मान (या समान मान का व्युत्पन्न) लौटाया - जब तक कि Google खाता सेटअप के दौरान जोड़ा गया हो।
  6. मुझे अभी तक कोई सिम के साथ जीएसएम डिवाइस का परीक्षण करने का मौका नहीं मिला है, जीएसएम डिवाइस जिसमें कोई Google खाता नहीं है, या हवाई जहाज मोड में से कोई भी डिवाइस नहीं है।

तो यदि आप डिवाइस के लिए कुछ अद्वितीय चाहते हैं, तो TM.getDeviceId() पर्याप्त होना चाहिए। जाहिर है कि कुछ उपयोगकर्ता दूसरों की तुलना में अधिक पागल हैं, इसलिए यह इन पहचानकर्ताओं में से 1 या अधिक के लिए उपयोगी हो सकता है, ताकि स्ट्रिंग अभी भी डिवाइस के लिए लगभग अनूठी हो, लेकिन स्पष्ट रूप से उपयोगकर्ता के वास्तविक डिवाइस की पहचान नहीं करता है। उदाहरण के लिए, एक UUID के साथ संयुक्त, String.hashCode() का उपयोग 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" />

आयात libs

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

एंड्रॉइड डिवाइस मैक आईडी भी एक अनूठी आईडी है, यह मानना ​​नहीं बदलेगा कि अगर हम डिवाइस को स्वयं प्रारूपित करते हैं तो मैक आईडी प्राप्त करने के लिए निम्न कोड का उपयोग करके

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

अपने AndroidManifest.xml में उचित अनुमतियां भी शामिल न करें

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

कक्षा फ़ाइल में कोड के नीचे जोड़ें:

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" />

यहां 30+ उत्तर हैं और कुछ समान हैं और कुछ अद्वितीय हैं। यह उत्तर उन उत्तरों में से कुछ पर आधारित है। उनमें से एक @ लेन डॉलिंग का जवाब है।

यह 3 आईडी को जोड़ता है और 32-अंकों वाली हेक्स स्ट्रिंग बनाता है। यह मेरे लिए बहुत अच्छा काम किया है।

3 आईडी हैं:
छद्म-आईडी - यह भौतिक डिवाइस विनिर्देशों के आधार पर उत्पन्न होता है
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 "";
}

जैसा कि डेव वेबब का उल्लेख है, एंड्रॉइड डेवलपर ब्लॉग में एक लेख है जो इसे शामिल करता है। उनका पसंदीदा समाधान डिवाइस के बजाय ऐप इंस्टॉल को ट्रैक करना है, और यह अधिकांश उपयोग मामलों के लिए अच्छा काम करेगा। ब्लॉग पोस्ट आपको उस काम को करने के लिए आवश्यक कोड दिखाएगा, और मैं आपको इसकी जांच करने की सलाह देता हूं।

हालांकि, ब्लॉग पोस्ट समाधान पर चर्चा करने के लिए आगे बढ़ता है यदि आपको ऐप इंस्टॉलेशन पहचानकर्ता की बजाय डिवाइस पहचानकर्ता की आवश्यकता है। मैंने आपको ऐसा करने की आवश्यकता होने पर कुछ आइटमों पर कुछ अतिरिक्त स्पष्टीकरण प्राप्त करने के लिए Google पर किसी के साथ बात की थी। यहां बताया गया है कि मैंने डिवाइस पहचानकर्ताओं के बारे में क्या खोजा है जिनका उपर्युक्त ब्लॉग पोस्ट में उल्लेख नहीं किया गया है:

  • ANDROID_ID पसंदीदा डिवाइस पहचानकर्ता है। ANDROID_ID Android <= 2.1 या> = 2.3 के संस्करणों पर पूरी तरह विश्वसनीय है। केवल 2.2 में पोस्ट में उल्लिखित समस्याएं हैं।
  • कई निर्माताओं द्वारा कई डिवाइस 2.2 में ANDROID_ID बग से प्रभावित होते हैं।
  • जहां तक ​​मैं निर्धारित करने में सक्षम हूं, सभी प्रभावित उपकरणों में एक ही ANDROID_ID है , जो कि 9774d56d682e549c । एमुलेटर, बीटीडब्ल्यू द्वारा रिपोर्ट की गई एक ही डिवाइस आईडी भी है।
  • Google का मानना ​​है कि OEM ने कई या अधिकांश उपकरणों के लिए इस मुद्दे को पैच किया है, लेकिन मैं यह सत्यापित करने में सक्षम था कि कम से कम अप्रैल 2011 की शुरुआत के रूप में, टूटी हुई एंड्रॉइड_आईडी डिवाइसों को ढूंढना अभी भी आसान है।

Google की सिफारिशों के आधार पर, मैंने एक कक्षा को कार्यान्वित किया है जो एंड्रॉइड_आईडी का उपयोग करके उपयुक्त उपकरण के रूप में एंड्रॉइड_आईडी का उपयोग करके प्रत्येक डिवाइस के लिए एक अद्वितीय यूयूआईडी उत्पन्न करेगा, और आवश्यकतानुसार टेलीफ़ोनी मैनेजर.getDeviceId () पर वापस आ रहा है, और यदि यह विफल रहता है, तो यादृच्छिक रूप से जेनरेट किए गए अद्वितीय UUID का उपयोग करना यह ऐप पुनरारंभ करने पर जारी है (लेकिन ऐप पुन: इंस्टॉल नहीं)।

ध्यान दें कि डिवाइस आईडी पर फ़ॉलबैक करने वाले उपकरणों के लिए, अद्वितीय आईडी फ़ैक्टरी रीसेट पर जारी रहेगी। यह कुछ पता होना चाहिए। यदि आपको यह सुनिश्चित करने की आवश्यकता है कि फ़ैक्टरी रीसेट आपकी अनन्य आईडी रीसेट करेगा, तो आप डिवाइस आईडी के बजाय यादृच्छिक यूयूआईडी पर सीधे वापस गिरने पर विचार करना चाहेंगे।

दोबारा, यह कोड एक डिवाइस आईडी के लिए है, न कि ऐप इंस्टॉलेशन आईडी। ज्यादातर स्थितियों के लिए, एक ऐप इंस्टॉलेशन आईडी शायद वह है जिसे आप ढूंढ रहे हैं। लेकिन अगर आपको डिवाइस आईडी की आवश्यकता है, तो निम्न कोड शायद आपके लिए काम करेगा।

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

नीचे दिए गए कोड का उपयोग करके, आप एक एंड्रॉइड ओएस डिवाइस की एक स्ट्रिंग के रूप में अद्वितीय डिवाइस आईडी प्राप्त कर सकते हैं।

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

यहां कोड है जो उपयोगकर्ता के लिए एक अद्वितीय आईडी प्राप्त करने के लिए इस वर्ष 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;
}

यदि आप इसे क्लाउड पर वरीयताओं को भेजने के लिए बैकअप रणनीति के साथ जोड़ते हैं (रेटो की talk में भी वर्णित है, तो आपके पास एक आईडी होना चाहिए जो उपयोगकर्ता से संबंध रखता है और डिवाइस को मिटा दिए जाने के बाद चारों ओर चिपक जाता है, या यहां तक ​​कि प्रतिस्थापित किया जाता है। मैं इसका उपयोग करने की योजना बना रहा हूं। आगे बढ़ने वाले विश्लेषिकी में (दूसरे शब्दों में, मैंने अभी तक यह कुछ नहीं किया है :)।


यहां बल्कि उपयोगी जानकारी here

इसमें पांच अलग-अलग आईडी प्रकार शामिल हैं:

  1. आईएमईआई (केवल फोन उपयोग के साथ एंड्रॉइड डिवाइस के लिए; android.permission.READ_PHONE_STATE आवश्यकता है)
  2. छद्म-अद्वितीय आईडी (सभी एंड्रॉइड डिवाइसों के लिए)
  3. एंड्रॉइड आईडी (शून्य हो सकता है, फ़ैक्टरी रीसेट पर बदल सकता है, रूट किए गए फोन पर बदला जा सकता है)
  4. डब्ल्यूएलएएन मैक पता स्ट्रिंग (जरूरत है android.permission.ACCESS_WIFI_STATE )
  5. बीटी मैक पता स्ट्रिंग (ब्लूटूथ के साथ डिवाइस, जरूरत है android.permission.BLUETOOTH )

प्रत्येक एंड्रॉइड डिवाइस के लिए एक अद्वितीय पहचानकर्ता कैसे प्राप्त करें, इसके बारे में विस्तृत निर्देशों के लिए, आपका एप्लिकेशन इंस्टॉल किया गया है, आधिकारिक एंड्रॉइड डेवलपर ब्लॉग पोस्टिंग android-developers.blogspot.com/2011/03/…

ऐसा लगता है कि इंस्टॉलेशन पर खुद को उत्पन्न करने का सबसे अच्छा तरीका है और बाद में इसे फिर से लॉन्च होने पर इसे पढ़ा जाता है।

मुझे व्यक्तिगत रूप से यह स्वीकार्य लगता है लेकिन आदर्श नहीं है। एंड्रॉइड द्वारा प्रदान किए गए कोई भी पहचानकर्ता सभी मामलों में काम करता है क्योंकि अधिकांश फोन के रेडियो स्टेटस (वाई-फाई चालू / बंद, सेलुलर चालू / बंद, ब्लूटूथ चालू / बंद) पर निर्भर हैं। दूसरों को, जैसे 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();
    }
}

Google के पास अब एक विज्ञापन आईडी है
इसका भी उपयोग किया जा सकता है, लेकिन ध्यान दें कि:

विज्ञापन आईडी उपयोगकर्ता-विशिष्ट, अद्वितीय, रीसेट करने योग्य आईडी है

तथा

उपयोगकर्ताओं को Google Play ऐप्स के भीतर अपने पहचानकर्ता को रीसेट करने या रुचि-आधारित विज्ञापनों से ऑप्ट आउट करने में सक्षम बनाता है।

हालांकि यह आईडी बदल सकती है, ऐसा लगता है कि जल्द ही हमारे पास कोई विकल्प नहीं हो सकता है , इस आईडी के उद्देश्य पर निर्भर करता है।

http://developer.android.com/google/play-services/id.html

यहां कॉपी-पेस्ट कोड

HTH


TelephonyManger.getDeviceId () अद्वितीय डिवाइस आईडी देता है, उदाहरण के लिए, जीएसएम के लिए आईएमईआई और सीडीएमए फोन के लिए एमईआईडी या ईएसएन।

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

लेकिन मैं उपयोग करने की सलाह देते हैं:

सेटिंग्स. Secure.ANDROID_ID जो एंड्रॉइड आईडी को एक अद्वितीय 64-बिट हेक्स स्ट्रिंग के रूप में देता है।

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

मैं 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);

अंतिम अपडेट: 6/2/15

एक अद्वितीय आईडी बनाने के बारे में प्रत्येक स्टैक ओवरफ़्लो पोस्ट पढ़ने के बाद, Google डेवलपर ब्लॉग और एंड्रॉइड दस्तावेज़, मुझे लगता है कि 'छद्म आईडी' सबसे अच्छा संभव विकल्प है।

मुख्य मुद्दा: हार्डवेयर बनाम सॉफ्टवेयर

हार्डवेयर

  • उपयोगकर्ता अपने हार्डवेयर, एंड्रॉइड टैबलेट या फोन को बदल सकते हैं, इसलिए हार्डवेयर के आधार पर अद्वितीय आईडी ट्रेकिंग यूजर के लिए अच्छे विचार नहीं हैं
  • ट्रैकिंग हार्डवेयर के लिए , यह एक अच्छा विचार है

सॉफ्टवेयर

  • उपयोगकर्ता रूट होने पर अपने रोम को मिटा / बदल सकते हैं
  • आप प्लेटफार्मों (आईओएस, एंड्रॉइड, विंडोज़ और वेब) में उपयोगकर्ताओं को ट्रैक कर सकते हैं
  • सबसे अच्छा उपयोगकर्ता को उनकी सहमति के साथ एक व्यक्तिगत उपयोगकर्ता को ट्रैक करना है, बस उन्हें लॉगिन करना है (ओएथ का उपयोग करके यह निर्बाध बनाना)

एंड्रॉइड के साथ कुल मिलाकर टूटना

- एपीआई> = 9/10 (एंड्रॉइड डिवाइसों का 99.5%) के लिए गारंटी विशिष्टता (रूट डिवाइस शामिल हैं)

- कोई अतिरिक्त अनुमति नहीं है

Psuedo कोड:

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

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

else

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

हमारे सभी विकल्पों को पोस्ट करने के लिए @ स्टंसल्ट के लिए धन्यवाद (इस स्टैक ओवरफ़्लो प्रश्न में)।

विकल्पों की सूची - कारणों का उपयोग क्यों नहीं करें:

  • उपयोगकर्ता ईमेल - सॉफ्टवेयर

  • उपयोगकर्ता फोन नंबर - सॉफ्टवेयर

    • उपयोगकर्ता फोन नंबर बदल सकते हैं - बेहद असंभव
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • आईएमईआई - हार्डवेयर (केवल फोन, जरूरत है android.permission.READ_PHONE_STATE )

    • अधिकांश उपयोगकर्ता इस तथ्य से नफरत करते हैं कि यह अनुमति में "फोन कॉल" कहता है। कुछ उपयोगकर्ता खराब रेटिंग देते हैं, क्योंकि उनका मानना ​​है कि आप बस अपनी व्यक्तिगत जानकारी चुरा रहे हैं, जब आप वास्तव में करना चाहते हैं तो ट्रैक डिवाइस इंस्टॉल है। यह स्पष्ट है कि आप डेटा एकत्र कर रहे हैं।
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • एंड्रॉइड आईडी - हार्डवेयर (शून्य हो सकता है, फ़ैक्टरी रीसेट पर बदल सकता है, रूट डिवाइस पर बदला जा सकता है)

    • चूंकि यह 'शून्य' हो सकता है, इसलिए हम 'शून्य' की जांच कर सकते हैं और इसके मूल्य को बदल सकते हैं, लेकिन इसका मतलब है कि यह अब अद्वितीय नहीं होगा।
    • यदि आपके पास फ़ैक्टरी रीसेट डिवाइस वाला कोई उपयोगकर्ता है, तो रूट रूट डिवाइस पर बदल या बदल सकता है, इसलिए यदि आप उपयोगकर्ता इंस्टॉल को ट्रैक कर रहे हैं तो डुप्लीकेट प्रविष्टियां हो सकती हैं।
  • डब्ल्यूएलएएन मैक पता - हार्डवेयर (जरूरत है android.permission.ACCESS_WIFI_STATE )

    • यह दूसरा सबसे अच्छा विकल्प हो सकता है, लेकिन आप अभी भी एक अद्वितीय पहचानकर्ता एकत्रित और संग्रहीत कर रहे हैं जो सीधे उपयोगकर्ता से आता है। यह स्पष्ट है कि आप डेटा एकत्र कर रहे हैं।
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
  • ब्लूटूथ मैक पता - हार्डवेयर (ब्लूटूथ के साथ डिवाइस, जरूरत है android.permission.BLUETOOTH )

    • बाजार पर अधिकांश एप्लिकेशन ब्लूटूथ का उपयोग नहीं करते हैं, और इसलिए यदि आपका एप्लिकेशन ब्लूटूथ का उपयोग नहीं करता है और आप इसमें शामिल हैं, तो उपयोगकर्ता संदिग्ध हो सकता है।
    • <uses-permission android:name="android.permission.BLUETOOTH "/>
  • छद्म-अद्वितीय आईडी - सॉफ्टवेयर (सभी एंड्रॉइड डिवाइसों के लिए)

    • बहुत संभव है, टकराव हो सकता है - नीचे दी गई मेरी विधि देखें!
    • यह आपको निजी से कुछ भी लेने के बिना उपयोगकर्ता से 'लगभग अद्वितीय' आईडी प्राप्त करने की अनुमति देता है। आप डिवाइस की जानकारी से अपना अनाम आईडी बना सकते हैं।

मुझे पता है कि अनुमतियों का उपयोग किये बिना एक अद्वितीय आईडी प्राप्त करने का कोई 'सही' तरीका नहीं है; हालांकि, कभी-कभी हमें केवल डिवाइस स्थापना को ट्रैक करने की आवश्यकता होती है। जब एक अद्वितीय आईडी बनाने की बात आती है, तो हम पूरी तरह से जानकारी के आधार पर एक 'छद्म अद्वितीय आईडी' बना सकते हैं जो एंड्रॉइड एपीआई अतिरिक्त अनुमतियों के बिना हमें देता है। इस तरह, हम उपयोगकर्ता सम्मान दिखा सकते हैं और एक अच्छा उपयोगकर्ता अनुभव भी प्रदान करने का प्रयास कर सकते हैं।

एक छद्म-अद्वितीय आईडी के साथ, आप वास्तव में केवल इस तथ्य में भाग लेते हैं कि इस तरह के उपकरणों के आधार पर डुप्लिकेट हो सकते हैं। आप इसे अधिक अद्वितीय बनाने के लिए संयुक्त विधि को ट्विक कर सकते हैं; हालांकि, कुछ डेवलपर्स को डिवाइस इंस्टॉल को ट्रैक करने की आवश्यकता है और यह समान उपकरणों के आधार पर चाल या प्रदर्शन करेगा।

एपीआई> = 9:

यदि उनका एंड्रॉइड डिवाइस एपीआई 9 या उससे अधिक है, तो यह 'Build.SERIAL' फ़ील्ड के कारण अद्वितीय होने की गारंटी है।

याद रखें , आप तकनीकी रूप से लगभग 0.5% उपयोगकर्ताओं के बारे में याद कर रहे हैं जिनके पास एपीआई <9 है । तो आप बाकी पर ध्यान केंद्रित कर सकते हैं: यह 99.5% उपयोगकर्ताओं का है!

एपीआई <9:

यदि उपयोगकर्ता का एंड्रॉइड डिवाइस एपीआई 9 से कम है; उम्मीद है कि उन्होंने फ़ैक्टरी रीसेट नहीं किया है और उनके 'सुरक्षित .ANDROID_ID' को संरक्षित किया जाएगा या नहीं 'शून्य'। ( http://developer.android.com/about/dashboards/index.html देखें)

यदि सभी अन्य विफल होते हैं:

यदि सब कुछ विफल हो जाता है, यदि उपयोगकर्ता एपीआई 9 (जिंजरब्रेड से कम) से कम है, तो अपने डिवाइस या 'सुरक्षित .ANDROID_ID' रिटर्न 'शून्य' को रीसेट कर दिया गया है, तो बस लौटाई गई आईडी पूरी तरह से उनके एंड्रॉइड डिवाइस की जानकारी के आधार पर होगी। यह वह जगह है जहां टक्कर हो सकती है।

परिवर्तन:

  • फ़ैक्टरी रीसेट की वजह से 'Android.SECURE_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://.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://.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 सेवाओं वाले ऐप्स के लिए):

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/AdvertisingIdClient.html

जरूरी:

इसका उद्देश्य यह है कि विज्ञापन आईडी विज्ञापन प्रयोजनों के लिए अन्य पहचानकर्ताओं के मौजूदा उपयोग को पूरी तरह से प्रतिस्थापित करती है (जैसे सेटिंग्स में सुरक्षित और एंड्रॉइड_आईडी का उपयोग)। Google Play सेवाएं उपलब्ध होने पर। जिन मामलों में Google Play सेवाएं अनुपलब्ध हैं, उन्हें Google PlayServicesNotAvailableException द्वारा GetAdvertisingIdInfo () द्वारा फेंक दिया जा रहा है।

चेतावनी, उपयोगकर्ता रीसेट कर सकते हैं:

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

मैंने उन सभी लिंक को संदर्भित करने का प्रयास किया है जिनसे मैंने जानकारी ली है। यदि आप गायब हैं और शामिल होने की आवश्यकता है, तो कृपया टिप्पणी करें!

Google प्लेयर सेवा इंस्टेंस आईडी

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


एक चीज जो मैं जोड़ूंगा - मेरे पास उन अद्वितीय परिस्थितियों में से एक है।

का उपयोग करते हुए:

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

यह पता चला है कि भले ही मेरा व्यूजनिक जी टैबलेट एक डिवाइसआईडी की रिपोर्ट करता है जो शून्य नहीं है, हर एक जी टैबलेट एक ही संख्या की रिपोर्ट करता है।

इसे "पॉकेट एम्पायर्स" खेलना दिलचस्प बनाता है जो आपको "अद्वितीय" डिवाइस आईडी के आधार पर किसी के खाते में तत्काल पहुंच प्रदान करता है।

मेरे डिवाइस में सेल रेडियो नहीं है।


पेशेवरों और विपक्ष के साथ उन ANDROID_IDमुद्दों के आसपास काम करने के लिए कई अलग-अलग दृष्टिकोण हैं ( nullकभी-कभी या एक विशिष्ट मॉडल के उपकरण हमेशा एक ही आईडी वापस कर सकते हैं):

  • एक कस्टम आईडी पीढ़ी एल्गोरिदम लागू करना (डिवाइस गुणों के आधार पर जो स्थिर होना चाहिए और नहीं बदलेगा -> कौन जानता है)
  • IMEI , सीरियल नंबर, वाई-फाई / ब्लूटूथ-मैक पता जैसे अन्य आईडी का दुरुपयोग (वे सभी उपकरणों या अतिरिक्त अनुमतियों पर मौजूद नहीं होंगे)

मैं एंड्रॉइड के लिए एक मौजूदा ओपनयूडीआईडी ​​कार्यान्वयन ( https://github.com/ylechelle/OpenUDID ) का उपयोग करना पसंद करता हूं ( https://github.com/vieux/OpenUDID )। ANDROID_IDऊपर उल्लिखित मुद्दों के लिए फॉलबैक के साथ एकीकृत करना और उपयोग करना आसान है ।


एक और तरीका /sys/class/android_usb/android0/iSerialकिसी ऐप में किसी भी अनुमति के बिना उपयोग करना है।

[email protected]:~$ adb shell ls -l /sys/class/android_usb/android0/iSerial
-rw-r--r-- root     root         4096 2013-01-10 21:08 iSerial
[email protected]:~$ adb shell cat /sys/class/android_usb/android0/iSerial
0A3CXXXXXXXXXX5

जावा में ऐसा करने के लिए iSerial फ़ाइल खोलने और अक्षरों को पढ़ने के लिए बस एक FileInputStream का उपयोग करेगा। बस सुनिश्चित करें कि आप इसे अपवाद हैंडलर में लपेटें, क्योंकि सभी उपकरणों में यह फ़ाइल नहीं है।

कम से कम निम्न डिवाइस इस फ़ाइल को विश्व-पठनीय बनाने के लिए जाने जाते हैं:

  • गैलेक्सी नेक्सस
  • नेक्सस एस
  • मोटोरोला ज़ूम 3 जी
  • तोशिबा एटी 300
  • एचटीसी वन वी
  • मिनी एमके 802
  • सैमसंग गैलेक्सी एस II

आप अनजान ऐप्स पर एंड्रॉइड हार्डवेयर सीरियल नंबर लीक करने के लिए मेरे ब्लॉग पोस्ट को भी देख सकते हैं जहां मैं चर्चा करता हूं कि जानकारी के लिए अन्य फाइलें क्या उपलब्ध हैं।


इसके अलावा आप वाई-फाई एडाप्टर के मैक पते पर विचार कर सकते हैं। इस प्रकार पुनः प्राप्त किया गया:

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

मैनिफेस्ट में android.permission.ACCESS_WIFI_STATE अनुमति की आवश्यकता है।

वाई-फाई कनेक्ट नहीं होने पर भी उपलब्ध होने की सूचना दी गई। यदि उपर्युक्त उत्तर से जो इसे अपने कई उपकरणों पर आज़माता है, तो यह अच्छा होगा।

कुछ उपकरणों पर, यह वाई-फाई बंद होने पर उपलब्ध नहीं है।

नोट: एंड्रॉइड 6.x से, यह लगातार नकली मैक पता देता है: 02:00:00:00:00:00


मुझे लगता है कि यह एक अद्वितीय आईडी के लिए एक कंकाल बनाने का आग तरीका है ... इसे देखें।

छद्म-अद्वितीय आईडी, जो सभी एंड्रॉइड डिवाइस पर काम करती है कुछ उपकरणों में फ़ोन नहीं होता है (उदाहरण के लिए टैबलेट) या किसी कारण से, आप 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 ऐसे अंक हैं और हम आईएमईआई (15 अंक) के समान आकार आईडी रखने के लिए सामने (35) में दो और जोड़ रहे हैं। यहां अन्य संभावनाएं अच्छी तरह से हैं, बस इन तारों पर एक नज़र डालें। कुछ ऐसा देता है 355715565309247। इस दृष्टिकोण को बहुत सुविधाजनक बनाने के लिए कोई विशेष अनुमति की आवश्यकता नहीं है।

(अतिरिक्त जानकारी: ऊपर दी गई तकनीक को here पर एक लेख से कॉपी किया गया था ।)


यहां बताया गया है कि मैं अद्वितीय आईडी कैसे बना रहा हूं:

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

IMEI बारे में कैसे । यह एंड्रॉइड या अन्य मोबाइल उपकरणों के लिए अद्वितीय है।


ऐसा होने के नाते मैं एक्सएमएल को कार्यक्षमता से संबंधित किसी चीज़ के साथ प्रदूषित नहीं करना चाहता, मैंने इस विधि को बनाया कि "पारदर्शी रूप से" पहले फोकस करने योग्य दृश्य से फोकस चुरा लेता है और फिर आवश्यक होने पर स्वयं को हटाना सुनिश्चित करता है!

public static View preventInitialFocus(final Activity activity)
{
    final ViewGroup content = (ViewGroup)activity.findViewById(android.R.id.content);
    final View root = content.getChildAt(0);
    if (root == null) return null;
    final View focusDummy = new View(activity);
    final View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View view, boolean b)
        {
            view.setOnFocusChangeListener(null);
            content.removeView(focusDummy);
        }
    };
    focusDummy.setFocusable(true);
    focusDummy.setFocusableInTouchMode(true);
    content.addView(focusDummy, 0, new LinearLayout.LayoutParams(0, 0));
    if (root instanceof ViewGroup)
    {
        final ViewGroup _root = (ViewGroup)root;
        for (int i = 1, children = _root.getChildCount(); i < children; i++)
        {
            final View child = _root.getChildAt(i);
            if (child.isFocusable() || child.isFocusableInTouchMode())
            {
                child.setOnFocusChangeListener(onFocusChangeListener);
                break;
            }
        }
    }
    else if (root.isFocusable() || root.isFocusableInTouchMode())
        root.setOnFocusChangeListener(onFocusChangeListener);

    return focusDummy;
}




android uniqueidentifier