كيف تحصل على IMEI/ESN للجهاز برمجيًا في Android؟

StackOverflow https://stackoverflow.com/questions/1972381

  •  21-09-2019
  •  | 
  •  

سؤال

لتحديد كل جهاز فريد أود استخدام IMEI (أو رقم ESN لأجهزة CDMA). كيفية الوصول إلى هذا برمجيا؟

هل كانت مفيدة؟

المحلول

أنت تريد أن تتصل android.telephony.TelephonyManager.getDeviceId().

سيؤدي هذا إلى إرجاع أي سلسلة تحدد الجهاز بشكل فريد (IMEI على GSM ، MEID لـ CDMA).

ستحتاج إلى الإذن التالي في AndroidManifest.xml:

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

من أجل القيام بذلك.

ومع ذلك ، كن حذرًا في القيام بذلك. لن يتساءل المستخدمون عن سبب وصول التطبيق الخاص بك إلى مكدس الهاتفي الخاص بهم ، فقد يكون من الصعب ترحيل البيانات إذا حصل المستخدم على جهاز جديد.

تحديث: كما هو مذكور في التعليقات أدناه ، فإن هذه ليست طريقة آمنة لمصادقة المستخدمين ، وزيادة مخاوف تتعلق بالخصوصية. لا ينصح به. بدلا من ذلك ، انظر إلى Google+ تسجيل الدخول API إذا كنت ترغب في تنفيذ نظام تسجيل الدخول بدون احتكاك.

ال Android Backup API متاح أيضًا إذا كنت تريد فقط طريقة خفيفة الوزن لاستمرار مجموعة من الأوتار عندما يقوم المستخدم بإعادة ضبط هاتفه (أو يشتري جهازًا جديدًا).

نصائح أخرى

بالإضافة إلى إجابة تريفور جونز ، يمكنك استخدام هذا على النحو التالي:

TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.getDeviceId();

ويجب عليك إضافة الإذن التالي إلى ملف missest.xml الخاص بك:

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

في المحاكي ، ستحصل على الأرجح على قيمة "00000 ...". GetDeviceId () إرجاع فارغة إذا لم يكن معرف الجهاز متاحًا.

أستخدم الكود التالي للحصول على IMEI أو استخدام Secure.android_id كبديل ، عندما لا يحتوي الجهاز على إمكانيات الهاتف:

/**
 * Returns the unique identifier for the device
 *
 * @return unique identifier for the device
 */
public String getDeviceIMEI() {
    String deviceUniqueIdentifier = null;
    TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
    if (null != tm) {
        deviceUniqueIdentifier = tm.getDeviceId();
    }
    if (null == deviceUniqueIdentifier || 0 == deviceUniqueIdentifier.length()) {
        deviceUniqueIdentifier = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
    }
    return deviceUniqueIdentifier;
}

أو يمكنك استخدام إعداد Android_ID من Android.provider.settings.System (كما هو موضح هنا Strazerre.com).

هذا له ميزة أنه لا يتطلب أذونات خاصة ولكن يمكن أن يتغير إذا كان تطبيقًا آخر قد كتب وصوله ويغيره (وهو أمر غير عادي ولكن ليس مستحيلًا).

فقط للرجوع هنا هو الرمز من المدونة:

import android.provider.Settings;
import android.provider.Settings.System;   

String androidID = System.getString(this.getContentResolver(),Secure.ANDROID_ID);

ملاحظة التنفيذ: إذا كان المعرف أمرًا ضروريًا لهندسة النظام ، فيجب أن تدرك أنه في الممارسة العملية ، تم العثور على بعض الهواتف والأجهزة اللوحية ذات الطرف المنخفض للغاية لإعادة استخدام نفس Android_ID (9774D56D682E549C كانت القيمة التي تظهر في سجلاتنا)

من عند: http://mytechead.wordpress.com/2011/08/28/how-to-get-ipei-number-of-android-device/:

الرمز التالي يساعد في الحصول على عدد IMEI من أجهزة Android:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String device_id = tm.getDeviceId();

الأذونات المطلوبة في Android Deivest:

android.permission.READ_PHONE_STATE

ملاحظة: في حالة الأجهزة اللوحية أو الأجهزة التي لا يمكن أن تعمل كهاتف محمول ، سيكون IMEI فارغًا.

لتأخذ، لتمتلك إيمي (معرف معدات الهاتف المحمول الدولي)

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

لتأخذ، لتمتلك معرف الجهاز الفريد

public String getDeviceUniqueID(Activity activity){
    String device_unique_id = Secure.getString(activity.getContentResolver(),
            Secure.ANDROID_ID);
    return device_unique_id;
}

بالنسبة إلى Android 6.0+ ، تغيرت اللعبة لذلك أقترح استخدام هذا ؛

أفضل طريقة للذهاب هي أثناء وقت التشغيل ، تحصل على أخطاء إذن.

   /**
 * A loading screen after AppIntroActivity.
 */
public class LoadingActivity extends BaseActivity {
private static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 0;
private TextView loading_tv2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_loading);

    //trigger 'loadIMEI'
    loadIMEI();
    /** Fading Transition Effect */
    overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}

/**
 * Called when the 'loadIMEI' function is triggered.
 */
public void loadIMEI() {
    // Check if the READ_PHONE_STATE permission is already available.
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
            != PackageManager.PERMISSION_GRANTED) {
        // READ_PHONE_STATE permission has not been granted.
        requestReadPhoneStatePermission();
    } else {
        // READ_PHONE_STATE permission is already been granted.
        doPermissionGrantedStuffs();
    }
}



/**
 * Requests the READ_PHONE_STATE permission.
 * If the permission has been denied previously, a dialog will prompt the user to grant the
 * permission, otherwise it is requested directly.
 */
private void requestReadPhoneStatePermission() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.READ_PHONE_STATE)) {
        // Provide an additional rationale to the user if the permission was not granted
        // and the user would benefit from additional context for the use of the permission.
        // For example if the user has previously denied the permission.
        new AlertDialog.Builder(LoadingActivity.this)
                .setTitle("Permission Request")
                .setMessage(getString(R.string.permission_read_phone_state_rationale))
                .setCancelable(false)
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        //re-request
                        ActivityCompat.requestPermissions(LoadingActivity.this,
                                new String[]{Manifest.permission.READ_PHONE_STATE},
                                MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
                    }
                })
                .setIcon(R.drawable.onlinlinew_warning_sign)
                .show();
    } else {
        // READ_PHONE_STATE permission has not been granted yet. Request it directly.
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE},
                MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
    }
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {

    if (requestCode == MY_PERMISSIONS_REQUEST_READ_PHONE_STATE) {
        // Received permission result for READ_PHONE_STATE permission.est.");
        // Check if the only required permission has been granted
        if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // READ_PHONE_STATE permission has been granted, proceed with displaying IMEI Number
            //alertAlert(getString(R.string.permision_available_read_phone_state));
            doPermissionGrantedStuffs();
        } else {
            alertAlert(getString(R.string.permissions_not_granted_read_phone_state));
          }
    }
}

private void alertAlert(String msg) {
    new AlertDialog.Builder(LoadingActivity.this)
            .setTitle("Permission Request")
            .setMessage(msg)
            .setCancelable(false)
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // do somthing here
                }
            })
            .setIcon(R.drawable.onlinlinew_warning_sign)
            .show();
}


public void doPermissionGrantedStuffs() {
    //Have an  object of TelephonyManager
    TelephonyManager tm =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
    //Get IMEI Number of Phone  //////////////// for this example i only need the IMEI
    String IMEINumber=tm.getDeviceId();

    /************************************************
     * **********************************************
     * This is just an icing on the cake
     * the following are other children of TELEPHONY_SERVICE
     *
     //Get Subscriber ID
     String subscriberID=tm.getDeviceId();

     //Get SIM Serial Number
     String SIMSerialNumber=tm.getSimSerialNumber();

     //Get Network Country ISO Code
     String networkCountryISO=tm.getNetworkCountryIso();

     //Get SIM Country ISO Code
     String SIMCountryISO=tm.getSimCountryIso();

     //Get the device software version
     String softwareVersion=tm.getDeviceSoftwareVersion()

     //Get the Voice mail number
     String voiceMailNumber=tm.getVoiceMailNumber();


     //Get the Phone Type CDMA/GSM/NONE
     int phoneType=tm.getPhoneType();

     switch (phoneType)
     {
     case (TelephonyManager.PHONE_TYPE_CDMA):
     // your code
     break;
     case (TelephonyManager.PHONE_TYPE_GSM)
     // your code
     break;
     case (TelephonyManager.PHONE_TYPE_NONE):
     // your code
     break;
     }

     //Find whether the Phone is in Roaming, returns true if in roaming
     boolean isRoaming=tm.isNetworkRoaming();
     if(isRoaming)
     phoneDetails+="\nIs In Roaming : "+"YES";
     else
     phoneDetails+="\nIs In Roaming : "+"NO";


     //Get the SIM state
     int SIMState=tm.getSimState();
     switch(SIMState)
     {
     case TelephonyManager.SIM_STATE_ABSENT :
     // your code
     break;
     case TelephonyManager.SIM_STATE_NETWORK_LOCKED :
     // your code
     break;
     case TelephonyManager.SIM_STATE_PIN_REQUIRED :
     // your code
     break;
     case TelephonyManager.SIM_STATE_PUK_REQUIRED :
     // your code
     break;
     case TelephonyManager.SIM_STATE_READY :
     // your code
     break;
     case TelephonyManager.SIM_STATE_UNKNOWN :
     // your code
     break;

     }
     */
    // Now read the desired content to a textview.
    loading_tv2 = (TextView) findViewById(R.id.loading_tv2);
    loading_tv2.setText(IMEINumber);
}
}

آمل أن يساعدك هذا أو شخص ما.

تحديث جديد:

بالنسبة إلى Android الإصدار 6 وما فوق ، تم إهمال عنوان WLAN MAC ، اتبع Trevor Johns Assem

تحديث:

لتحديد فريد للأجهزة ، يمكنك استخدام Secure.android_id.

الجواب القديم:

عيوب استخدام IMEI كمعرف فريد من نوعه:

  • يعتمد IMEI على فتحة SimCard للجهاز ، لذلك لا يمكن الحصول على IMEI للأجهزة التي لا تستخدم Simcard. في أجهزة SIM المزدوجة ، نحصل على اثنين من imeis مختلفان لنفس الجهاز لأنه يحتوي على فتحتين لـ Simcard.

يمكنك استخدام سلسلة عناوين WLAN MAC (لا ينصح بها Marshmallow و Marshmallow+ حيث تم إهمال عنوان WLAN MAC على مارشموور إلى الأمام. لذا ستحصل على قيمة زائفة)

يمكننا الحصول على المعرف الفريد لهواتف Android باستخدام عنوان WLAN MAC أيضًا. عنوان MAC فريد من نوعه لجميع الأجهزة ويعمل لجميع أنواع الأجهزة.

مزايا استخدام عنوان WLAN MAC كمعرف الجهاز:

  • إنه معرف فريد لجميع أنواع الأجهزة (الهواتف الذكية والأجهزة اللوحية).

  • يظل فريدًا إذا تم إعادة تثبيت التطبيق

عيوب استخدام عنوان WLAN MAC كمعرف الجهاز:

  • يعطيك قيمة زائفة من الخطمي وما فوق.

  • إذا لم يكن لدى الجهاز أجهزة WiFi ، فستحصل على عنوان Mac Null ، ولكن بشكل عام ، يُرى أن معظم أجهزة Android تحتوي على أجهزة WiFi ولا يوجد عدد قليل من الأجهزة في السوق بدون أجهزة WiFi.

مصدر : Technetexperts.com

كما هو الحال في API 26 getDeviceId () يتم انخفاضه حتى تتمكن من استخدام التعليمات البرمجية التالية لتلبية API 26 والإصدارات السابقة

TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String imei="";
if (android.os.Build.VERSION.SDK_INT >= 26) {
  imei=telephonyManager.getImei();
}
else
{
  imei=telephonyManager.getDeviceId();
}

لا تنس إضافة طلب إذن لـ "read_phone_state" لاستخدام الرمز أعلاه.

تقوم طريقة GetDeviceId () من TelephonyManager بإرجاع معرف الجهاز الفريد ، على سبيل المثال ، IMEI لـ GSM و MEID أو ESN لهواتف CDMA. إرجاع NULL إذا لم يكن معرف الجهاز متاحًا.

كود جافا

package com.AndroidTelephonyManager;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.TextView;

public class AndroidTelephonyManager extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    TextView textDeviceID = (TextView)findViewById(R.id.deviceid);

    //retrieve a reference to an instance of TelephonyManager
    TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

    textDeviceID.setText(getDeviceID(telephonyManager));

}

String getDeviceID(TelephonyManager phonyManager){

 String id = phonyManager.getDeviceId();
 if (id == null){
  id = "not available";
 }

 int phoneType = phonyManager.getPhoneType();
 switch(phoneType){
 case TelephonyManager.PHONE_TYPE_NONE:
  return "NONE: " + id;

 case TelephonyManager.PHONE_TYPE_GSM:
  return "GSM: IMEI=" + id;

 case TelephonyManager.PHONE_TYPE_CDMA:
  return "CDMA: MEID/ESN=" + id;

 /*
  *  for API Level 11 or above
  *  case TelephonyManager.PHONE_TYPE_SIP:
  *   return "SIP";
  */

 default:
  return "UNKNOWN: ID=" + id;
 }

}
}

XML

<linearlayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
<textview android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="@string/hello">
<textview android:id="@+id/deviceid" android:layout_height="wrap_content" android:layout_width="fill_parent">
</textview></textview></linearlayout> 

إذن مطلوبread_phone_state في ملف واضح.

يمكنك استخدام هذا TelephonyManager Telephony_Service وظيفة للحصول معرف الجهاز الفريد، يتطلب إذنًا: read_phone_state

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

مثال ، imei لـ GSM و ال Meid أو ESN لـ CDMA الهواتف.

/**
 * Gets the device unique id called IMEI. Sometimes, this returns 00000000000000000 for the
 * rooted devices.
 **/
public static String getDeviceImei(Context ctx) {
    TelephonyManager telephonyManager = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
    return telephonyManager.getDeviceId();
}

العودة لاغية لو معرف الجهاز غير متوفر.

طريقة getDeviceId() تم إهماله. هناك طريقة جديدة لهذا getImei(int)

تحقق هنا

استخدام الرمز أدناه يمنحك رقم IMEI:

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
System.out.println("IMEI::" + telephonyManager.getDeviceId());

جرب هذا (بحاجة إلى الحصول على أول imei دائمًا)

TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        if (ActivityCompat.checkSelfPermission(LoginActivity.this,Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED) {

         return;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (mTelephony.getPhoneCount() == 2) {
                    IME = mTelephony.getImei(0);
                }else{
                    IME = mTelephony.getImei();
                }
            }else{
                if (mTelephony.getPhoneCount() == 2) {
                    IME = mTelephony.getDeviceId(0);
                } else {
                    IME = mTelephony.getDeviceId();
                }
            }
        } else {
            IME = mTelephony.getDeviceId();
        }

لمستوى API 11 أو أعلى:

case TelephonyManager.PHONE_TYPE_SIP: 
return "SIP";

TelephonyManager tm= (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
textDeviceID.setText(getDeviceID(tm));

رمز Kotlin للحصول على DeviceId (IMEI) مع معالجة الإذن والتحقق من قابلية المقارنة لجميع إصدارات Android:

 val  telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
        == PackageManager.PERMISSION_GRANTED) {
        // Permission is  granted
        val imei : String? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)  telephonyManager.imei
        // older OS  versions
        else  telephonyManager.deviceId

        imei?.let {
            Log.i("Log", "DeviceId=$it" )
        }

    } else {  // Permission is not granted

    }

أضف أيضًا هذا الإذن إلى AndroidManifest.xml:

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

لأولئك الذين يبحثون عن إصدار Kotlin ، يمكنك استخدام شيء مثل هذا ؛

private fun telephonyService() {
    val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
    val imei = if (android.os.Build.VERSION.SDK_INT >= 26) {
        Timber.i("Phone >= 26 IMEI")
        telephonyManager.imei
    } else {
        Timber.i("Phone IMEI < 26")
        telephonyManager.deviceId
    }

    Timber.i("Phone IMEI $imei")
}

ملاحظة: يجب أن تلتف telephonyService() أعلاه مع فحص إذن باستخدام checkselfpermission أو أي طريقة تستخدمها.

أضف أيضًا هذا الإذن في ملف البيان ؛

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top