android - एंड्रॉइड डिवाइस की सीरियल नंबर कैसे खोजें?




serial-number (10)

@ हसरमैन कहते हैं:

TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

लेकिन मैनिफेस्ट फ़ाइल में अनुमति सहित जरूरी है:

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

मुझे एंड्रॉइड ऐप के लिए एक अद्वितीय आईडी का उपयोग करने की ज़रूरत है और मैंने सोचा कि डिवाइस के लिए सीरियल नंबर एक अच्छा उम्मीदवार होगा। मैं अपने ऐप में एंड्रॉइड डिवाइस की सीरियल नंबर कैसे प्राप्त करूं?


आईएमईआई अच्छा है लेकिन फोन के साथ एंड्रॉइड डिवाइस पर ही काम करता है। आपको टैबलेट या अन्य एंड्रॉइड डिवाइसों के लिए समर्थन पर विचार करना चाहिए, जिसमें फोन नहीं है।

आपके पास कुछ विकल्प हैं: क्लास के सदस्यों, बीटी मैक, डब्ल्यूएलएएन मैक, या इससे भी बेहतर बनाएं - इन सभी का संयोजन।

मैंने अपने ब्लॉग पर एक लेख में इन विवरणों को समझाया है, देखें: http://www.pocketmagic.net/?p=1662


उपरोक्त सभी दृष्टिकोणों में समस्याएं हैं। Google i / o रेटो मेयर में इस बात का एक मजबूत जवाब जारी किया गया कि इस बात को कैसे पहुंचाया जाए, जो अधिकांश डेवलपर्स को पूरा करना चाहिए, इंस्टॉलेशन में उपयोगकर्ताओं को ट्रैक करने की आवश्यकता है।

यह दृष्टिकोण आपको एक अज्ञात, सुरक्षित उपयोगकर्ता आईडी देगा जो उपयोगकर्ता के लिए विभिन्न उपकरणों (टैबलेट सहित, प्राथमिक Google खाते के आधार पर) और उसी डिवाइस पर इंस्टॉल के दौरान लगातार रहेगा। मूल दृष्टिकोण एक यादृच्छिक उपयोगकर्ता आईडी उत्पन्न करना और ऐप्स को साझा प्राथमिकताओं में संग्रहीत करना है। फिर आप क्लाउड में Google खाते से जुड़े साझा वरीयताओं को संग्रहीत करने के लिए Google के बैकअप एजेंट का उपयोग करते हैं।

चलिए पूर्ण दृष्टिकोण से गुजरते हैं। सबसे पहले हमें एंड्रॉइड बैकअप सेवा का उपयोग करके हमारे साझा किए गए संदर्भों के लिए बैकअप बनाना होगा। इस लिंक के माध्यम से अपना ऐप पंजीकृत करके शुरू करें: http://developer.android.com/google/backup/signup.html

Google आपको एक बैकअप सेवा कुंजी देगा जो आपको मैनिफेस्ट में जोड़ना होगा। आपको बैकअपएजेंट का उपयोग निम्नानुसार करने के लिए एप्लिकेशन को बताने की भी आवश्यकता है:

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

यह उपयोगकर्ता_आईडी अब इंस्टॉलेशन में लगातार रहेगा, भले ही उपयोगकर्ता डिवाइस स्विच करता हो।

इस दृष्टिकोण के बारे में अधिक जानकारी के लिए यहां रेटो की बात देखें http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html

और बैकअप एजेंट को कार्यान्वित करने के तरीके के बारे में पूरी जानकारी के लिए यहां डेवलपर साइट देखें: http://developer.android.com/guide/topics/data/backup.html मैं विशेष रूप से बैकअप के रूप में परीक्षण पर नीचे दिए गए अनुभाग की अनुशंसा करता हूं तत्काल नहीं होता है और इसलिए परीक्षण करने के लिए आपको बैकअप को मजबूर करना पड़ता है।


एक और तरीका किसी ऐप में / 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

आप यहां मेरे ब्लॉग पोस्ट को भी देख सकते हैं: http://insitusec.blogspot.com/2013/01/leaking-android-hardware-serial-number.html जहां मैं चर्चा करता हूं कि जानकारी के लिए अन्य फाइलें क्या उपलब्ध हैं।


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

कोड से पहले, 3 तथ्यों:

  1. TelephonyManager.getDeviceId() (akaIMEI) गैर-जीएसएम, 3 जी, एलटीई, आदि उपकरणों के लिए अच्छी तरह से काम नहीं करेगा, लेकिन संबंधित हार्डवेयर मौजूद होने पर हमेशा एक अद्वितीय आईडी लौटाएगा , भले ही कोई सिम डाली न हो या फिर भी कोई सिम स्लॉट मौजूद नहीं है (कुछ OEM ने यह किया है)।

  2. चूंकि जिंजरब्रेड (एंड्रॉइड 2.3) android.os.Build.SERIAL किसी भी डिवाइस पर मौजूद होना चाहिए जो आईएमईआई प्रदान नहीं करता है , यानि, एंड्रॉइड पॉलिसी के अनुसार उपर्युक्त हार्डवेयर मौजूद नहीं है।

  3. तथ्य के कारण (2.), कम से कम इन दो अद्वितीय पहचानकर्ताओं में से एक उपस्थित होगा , और सीईआरआईएल एक ही समय में उपस्थित हो सकता है जब आईएमईआई है।

नोट: तथ्य (1.) और (2.) Google कथन पर आधारित हैं

उपाय

उपर्युक्त तथ्यों के साथ, आईएमईआई बाध्य हार्डवेयर होने पर जांच कर एक अनूठा पहचानकर्ता हो सकता है, और जब यह नहीं होता है तो सीरियल पर वापस आ जाता है, क्योंकि कोई यह जांच नहीं सकता कि मौजूदा सीरियल मान्य है या नहीं। निम्नलिखित स्थैतिक वर्ग ऐसी उपस्थिति की जांच करने और आईएमईआई या सीरियल का उपयोग करने के लिए 2 विधियों को प्रस्तुत करता है:

import java.lang.reflect.Method;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;

public class IDManagement {

    public static String getCleartextID_SIMCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

        if(isSIMAvailable(mContext,telMgr)){
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId());
            return telMgr.getDeviceId();

        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static String getCleartextID_HARDCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if(telMgr != null && hasTelephony(mContext)){           
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId() + "");

            return telMgr.getDeviceId();    
        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static boolean isSIMAvailable(Context mContext, 
            TelephonyManager telMgr){

        int simState = telMgr.getSimState();

        switch (simState) {
        case TelephonyManager.SIM_STATE_ABSENT:
            return false;
        case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
            return false;
        case TelephonyManager.SIM_STATE_PIN_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_PUK_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_READY:
            return true;
        case TelephonyManager.SIM_STATE_UNKNOWN:
            return false;
        default:
            return false;
        }
    }

    static public boolean hasTelephony(Context mContext)
    {
        TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm == null)
            return false;

        //devices below are phones only
        if (Build.VERSION.SDK_INT < 5)
            return true;

        PackageManager pm = mContext.getPackageManager();

        if (pm == null)
            return false;

        boolean retval = false;
        try
        {
            Class<?> [] parameters = new Class[1];
            parameters[0] = String.class;
            Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
            Object [] parm = new Object[1];
            parm[0] = "android.hardware.telephony";
            Object retValue = method.invoke(pm, parm);
            if (retValue instanceof Boolean)
                retval = ((Boolean) retValue).booleanValue();
            else
                retval = false;
        }
        catch (Exception e)
        {
            retval = false;
        }

        return retval;
    }


}

मैं getCleartextID_HARDCHECK का उपयोग करने पर सलाह getCleartextID_HARDCHECK । यदि प्रतिबिंब आपके पर्यावरण में नहीं getCleartextID_SIMCHECK , तो इसके बजाय getCleartextID_SIMCHECK विधि का उपयोग करें, लेकिन ध्यान दें कि इसे आपकी विशिष्ट सिम-उपस्थिति आवश्यकताओं के अनुरूप अनुकूलित किया जाना चाहिए।

पीएस : कृपया ध्यान दें कि OEM ने Google नीति (उसी सीरियल के साथ कई डिवाइस) के खिलाफ सीरियल को बग करने में कामयाब रहा है , और Google ने कहा है कि एक बड़े OEM में कम से कम एक ज्ञात मामला है (खुलासा नहीं किया गया है और मुझे नहीं पता कि कौन सा ब्रांड यह या तो, मैं सैमसंग अनुमान लगा रहा हूँ)।

अस्वीकरण : यह एक अद्वितीय डिवाइस आईडी प्राप्त करने के मूल प्रश्न का उत्तर देता है, लेकिन ओपी ने अस्पष्टता पेश की है जिसमें कहा गया है कि उसे एपीपी के लिए एक अद्वितीय आईडी की आवश्यकता है। यहां तक ​​कि अगर ऐसे परिदृश्यों के लिए एंड्रॉइड_आईडी बेहतर होगा, तो यह 2 अलग-अलग रोम इंस्टॉलेशन (एक ही रोम भी हो सकता है) के माध्यम से ऐप के टाइटेनियम बैकअप के बाद काम नहीं करेगा। मेरा समाधान दृढ़ता बनाए रखता है जो फ़्लैश या फ़ैक्टरी रीसेट से स्वतंत्र होता है, और केवल तभी विफल होगा जब IMEI या SERIAL छेड़छाड़ हैक्स / हार्डवेयर मोड के माध्यम से होती है।


जैसा कि डेव वेबब का उल्लेख है, android-developers.blogspot.com/2011/03/… जो इसे शामिल करता है।

मैंने कुछ वस्तुओं पर कुछ अतिरिक्त स्पष्टीकरण प्राप्त करने के लिए 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 static volatile 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;
    }
}

मुझे पता है कि यह सवाल पुराना है लेकिन यह कोड की एक पंक्ति में किया जा सकता है

String deviceID = Build.SERIAL;


स्ट्रिंग के रूप में एंड्रॉइड ओएस डिवाइस की अनूठी डिवाइस आईडी।

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 :: द्वारा सुझाए गए इस विधि की दृढ़ता से अनुशंसा करता हूं

ऐप इंस्टॉलेशन की पहचान करना


String deviceId = Settings.System.getString(getContentResolver(),
                                Settings.System.ANDROID_ID);

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


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

यह कोड एक छिपी हुई एंड्रॉइड एपीआई का उपयोग कर डिवाइस सीरियल नंबर देता है।





serial-number