Как получить IMEI / ESN устройства программно в Android?


343

Для уникальной идентификации каждого устройства я хотел бы использовать IMEI (или номер ESN для устройств CDMA). Как получить доступ к этому программно?


Чтобы получить IMEI для обеих SIM-карт в двух SIM-телефонах, используйте отражения Java. Смотрите здесь демо
Вайбхав Яни

5
@PiedPiper: IMEI не зависит от SIM-карты. Вы думаете, IMSI.
Филипп

@ Филлип Спасибо, приятель. Я обновил свой ответ :)
Vaibhav Jani

1
Все .. есть ли изменения в Android 6? Можем ли мы получить доступ к IMEI каким-либо образом?
новость

1
Вам нужно запросить разрешение READ_PHONE_STATE во время выполнения, тогда вы все равно можете получить IMEI
Flo We

Ответы:


388

Вы хотите позвонить android.telephony.TelephonyManager.getDeviceId().

Это вернет любую строку, однозначно идентифицирующую устройство (IMEI в GSM, MEID для CDMA).

Вам понадобится следующее разрешение в вашем AndroidManifest.xml:

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

для того, чтобы сделать это.

При этом будьте осторожны с этим. Пользователи не только будут удивляться, почему ваше приложение получает доступ к своему стеку телефонии, но и будет сложно перенести данные, если пользователь получит новое устройство.

Обновление: как упоминалось в комментариях ниже, это не безопасный способ аутентификации пользователей, и это вызывает проблемы конфиденциальности. Не рекомендуется Вместо этого посмотрите API входа в Google+, если хотите внедрить систему входа без трения.

Android резервное копирование API также доступно , если вы просто хотите легкий способ упорствовать связку строк для того, когда пользователь сбрасывает свой телефон (или покупает новое устройство).


1
Что может быть лучшим решением, которое позволит им переносить данные в будущем? Адрес электронной почты Google? Если так, как я могу вытащить это из системы?
Том

3
Самый надежный способ сделать это - просто создать учетную запись при первом запуске приложения. Есть способы получить адрес электронной почты пользователя (см. Документацию по AccountManager), но для проверки того, что злоумышленник не подделал эту информацию, требуется немного знаний о том, как работают API данных Google - больше, чем я могу в этом указать. Небольшое поле для комментариев. ;)
Тревор Джонс

1
На самом деле, у вас нет никаких гарантий, что пользователь также не подделал свой IMEI / MEID. Если безопасность вызывает какое-либо беспокойство, вам действительно нужно использовать имя пользователя / пароль или метод getAuthToken () в AccountManager (и снова вам нужно будет проверить этот токен на сервере, который его выдал).
Тревор Джонс

2
Ади: код для получения идентификатора устройства? Там нет ничего, кроме одного метода + разрешение, которое я упомянул выше. Тем не менее, вы должны заглянуть в Google+ Login API, это рекомендуемый подход для аутентификации пользователей в наши дни: developer.android.com/google/play-services/auth.html
Тревор Джонс

2
Это работает под управлением Android 6? И вы нацеливаетесь на SDK 23? Затем вам нужно запросить READ_PHONE_STATE во время выполнения, прежде чем запрашивать IMEI
Flo We

284

В дополнение к ответу Тревора Джонса вы можете использовать это следующим образом:

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

И вы должны добавить следующее разрешение в ваш файл Manifest.xml:

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

В эмуляторе вы, вероятно, получите значение «00000 ...». getDeviceId () возвращает NULL, если идентификатор устройства недоступен.


1
Есть ли способ заставить эмулятор вернуть номер IMEI?
MikeSchem

@MikeSchem, эмулятор не имеет значимой строки IMEI.
Шижень

Попробуйте не использовать: <использование-разрешение android: name = "android.permission.READ_PHONE_STATE" /> это разрешение очень чувствительное, вы можете получить отклоненное приложение из команды Google Play (новые правила безопасности добавлены в конце 2016 года). В качестве совета лучше использовать Advertising ID.
Дуна

@Taner Будет ли он работать на Dual SIM устройстве? (Нужно получить только первый IMEI)
Арнольд Браун

Есть ли какие-либо проблемы с безопасностью для использования READ_PHONE_STATEразрешения?
Гадюка

62

Я использую следующий код, чтобы получить 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;
}

17
TextUtils.isEmpty () -> if (идентификатор == нулевой || идентификатор .length () == 0)
Михаил

2
Привет, Пинхасси. Был ли у вас случай, когда идентификатор устройства, возвращенный диспетчером телефонии, был нулевым или пустым, но значение, считанное из Secure.ANDROID_ID, было непустым? Спасибо
Будда

4
Насколько я помню, это было для планшетов без SIM-карты (но я не уверен на 100%).
Асаф Пинхасси

Secure.ANDROID_ID изменяется, если устройство отформатировано, или rom перезагружен
shridutt kothari

Мой Nexus7 (1stGen) возвращается nullдля устройства телефонии. Кто-нибудь знает, как получить IMEI с планшета?
Сакибой

38

Или вы можете использовать настройку 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 были найдены с повторным использованием ANDROID_ID (значение 9774d56d682e549c было показано в наших журналах)


15
Эта константа не рекомендуется. Вместо этого вам нужно использовать android.provider.Settings.Secure.ANDROID_ID;
Маккорли

@mcorley, когда я использую android.provider.Settings.Secure.ANDROID_ID для планшета Nexus 7 и Nexus 4, он возвращает одинаковое значение 'android_id'
vuhung3990

3
@meowmeo делал то же самое для меня, пока я не использовал код, который теперь является частью ответа (ish). String androidID = android.provider.Settings.System.getString(this.getContentResolver(), Secure.ANDROID_ID);
Матиас

Но не восстановится ли это до нового ANDROID_ID после сброса настроек? Что делать, если мне нужен постоянный ANDROID_ID, который может выжить, сбрасывается.
Игорь Ганапольский

35

От: http://mytechead.wordpress.com/2011/08/28/how-to-get-imei-number-of-android-device/ :

Следующий код помогает в получении IMEI количества устройств Android:

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

Разрешения, необходимые в манифесте Android:

android.permission.READ_PHONE_STATE

ПРИМЕЧАНИЕ. В случае планшетов или устройств, которые не могут работать в качестве мобильного телефона, IMEI будет нулевым.


1
это фактический код, который я нахожу для получения IMEI
Anand Savjani

2
К сожалению, с Marshmallow forward вы теперь должны запросить это разрешение во время выполнения. Это разрешение не является идеальным, поскольку оно мешает работе пользователей и может вызвать подозрение у некоторых пользователей.
Игорь Ганапольский

Попробуйте не использовать: <использование-разрешение android: name = "android.permission.READ_PHONE_STATE" /> это разрешение очень чувствительное, вы можете получить отклоненное приложение из команды Google Play (новые правила безопасности добавлены в конце 2018 года). В качестве совета лучше использовать Advertising ID вместо IMEI
Duna

какое решение для андроида 10?
Амин Пинджари

23

получить 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;
}

2
Показ альтернативы device_unique_id действительно полезен
JoeGalind

20

Для 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);
}
}

Надеюсь, это поможет вам или кому-то.


16

Новое обновление:

Для Android версии 6 и выше MAC-адрес WLAN устарел, следуйте ответу Тревора Джонса

Обновить:

Для однозначной идентификации устройств вы можете использовать Secure.ANDROID_ID .

Старый ответ:

Недостатки использования IMEI в качестве уникального идентификатора устройства:

  • IMEI зависит от слота Simcard устройства, поэтому получить IMEI для устройств, которые не используют Simcard, невозможно. В устройствах Dual sim мы получаем 2 разных IMEI для одного и того же устройства, поскольку у него есть 2 слота для симкарты.

Вы можете использовать строку MAC-адреса WLAN (не рекомендуется для Marshmallow и Marshmallow +, так как MAC-адрес WLAN устарел при использовании Marshmallow. Таким образом, вы получите поддельное значение)

Мы также можем получить уникальный идентификатор для телефонов Android, используя MAC-адрес WLAN. MAC-адрес уникален для всех устройств и работает для всех типов устройств.

Преимущества использования MAC-адреса WLAN в качестве идентификатора устройства:

  • Это уникальный идентификатор для всех типов устройств (смартфонов и планшетов).

  • Он остается уникальным, если приложение переустановлено

Недостатки использования MAC-адреса WLAN в качестве идентификатора устройства:

  • Дай вам фиктивную ценность от Зефира и выше.

  • Если устройство не имеет оборудования Wi-Fi, тогда вы получаете нулевой MAC-адрес, но, как правило, видно, что большинство устройств Android имеют оборудование Wi-Fi, и на рынке практически нет устройств без оборудования Wi-Fi.

ИСТОЧНИК: technetexperts.com


7
«IMEI зависит от симкарты» ... Это неверно. Вы, кажется,
путаете

2
Международное обозначение оборудования мобильной станции или сокращенно IMEI - это номер, который идентифицирует мобильные телефоны, работающие в сети GSM. Я лично попробовал это, и это дает мне нулевое программное значение, если на телефоне GSM нет оператора беспроводной связи. smartmobilephonesolutions.com/content/...
Джамиль

3
Вы правы, я не читал внимательно. IMEI связан с приемопередатчиком SIM-карты, а не с SIM-картой. Виноват!
Мерливед

2
WLAN MAC-адрес устарел на Зефир вперед. Таким образом, вы получите поддельное значение!
Игорь Ганапольский

1
Android 6 не возвращает правильный MAC-адрес WIFI с вашим кодом. Заметь это.
zszen

15

Как в 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на использование вышеуказанного кода.

ОБНОВЛЕНИЕ: Начиная с Android 10 пользовательские приложения могут получать не сбрасываемые идентификаторы оборудования, такие как IMEI.


Разум делиться, где я могу найти ссылку на метод 'getImei () "?
sam byte

2
Обязательно используйте developer.android.com/reference/android/telephony/… для справки по getImei ()
Мухаммед Хамза Шахид

какое решение для андроида 10?
Амин Пинджари

1
Амин, к сожалению, в Android 10 из-за соображений безопасности теперь сторонним приложениям запрещено получать идентификаторы оборудования, такие как IMEI, для получения дополнительной информации об изменениях конфиденциальности в Android 10 посетите developer.android.com/about/versions/10/privacy
Мухаммед Хамза Шахид

Работает на Android Oreo.
Сатиш Шетти

10

Метод getDeviceId () TelephonyManager возвращает уникальный идентификатор устройства, например, IMEI для GSM и MEID или ESN для телефонов CDMA. Вернуть ноль, если идентификатор устройства недоступен.

Java-код

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 в файле манифеста.


4

Вы можете использовать эту функцию 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();
}

Вернуть ноль, если идентификатор устройства недоступен .


а почему идентификатор устройства нулевой? из-за рутированного устройства.
Вишал Соджитра

какое решение для андроида 10?
Амин Пинджари


3

Попробуйте это (необходимо получить первый 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();
        }

какое решение для андроида 10? developer.android.com/about/versions/10/privacy
Амин Пинджари,

2

Используйте код ниже, чтобы получить номер IMEI:

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

1

для API уровня 11 или выше:

case TelephonyManager.PHONE_TYPE_SIP: 
return "SIP";

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

1

Код 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-->

1

Вам понадобится следующее разрешение в вашем AndroidManifest.xml:

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

Чтобы получить IMEI (международный идентификатор мобильного оборудования), и если он выше API-уровня 26, тогда мы получаем telephonyManager.getImei()нулевое значение, поэтому для этого мы используем ANDROID_ID в качестве уникального идентификатора.

 public static String getIMEINumber(@NonNull final Context context)
            throws SecurityException, NullPointerException {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        String imei;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            assert tm != null;
            imei = tm.getImei();
            //this change is for Android 10 as per security concern it will not provide the imei number.
            if (imei == null) {
                imei = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            }
        } else {
            assert tm != null;
            if (tm.getDeviceId() != null && !tm.getDeviceId().equals("000000000000000")) {
                imei = tm.getDeviceId();
            } else {
                imei = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            }
        }

        return imei;
    }

0

Для тех, кто ищет версию 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"/>

0

используйте код ниже:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        String[] permissions = {Manifest.permission.READ_PHONE_STATE};
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(permissions, READ_PHONE_STATE);
        }
    } else {
        try {
            TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            String imei = telephonyManager.getDeviceId();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

И вызовите метод onRequestPermissionsResult из следующего кода:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case READ_PHONE_STATE:
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED)
                try {
                    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    String imei = telephonyManager.getDeviceId();

                } catch (Exception e) {
                    e.printStackTrace();
                }
    }
}

Добавьте следующее разрешение в свой AndroidManifest.xml:

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

0

Для Android 10 Следующий код работает для меня.

val uid: String = Settings.Secure.getString(ctx.applicationContext.contentResolver, Settings.Secure.ANDROID_ID)
if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            imei = when {
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
                    uid
                }
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
                    telephonyManager.imei
                }
                else -> {
                    telephonyManager.deviceId
                }
            }
        }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.