How to get the device's IMEI/ESN programmatically in android?
Asked Answered
F

22

382

To identify each devices uniquely I would like to use the IMEI (or ESN number for CDMA devices). How to access this programmatically?

Frye answered 29/12, 2009 at 0:52 Comment(5)
To get IMEI for both SIM in dual SIM Phones use Java reflections. See here is demoUltima
@PiedPiper: IMEI is not SIM-specific. You're thinking IMSI.Macknair
Everyone .. are there some changes in android 6? can we still access the IMEI by some means?Montpelier
You need to request the Permission READ_PHONE_STATE at runtime, then you can still get the IMEIMaduro
you can't get IMEI info in Android 10.Persse
D
413

You want to call android.telephony.TelephonyManager.getDeviceId().

This will return whatever string uniquely identifies the device (IMEI on GSM, MEID for CDMA).

You'll need the following permission in your AndroidManifest.xml:

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

in order to do this.

That being said, be careful about doing this. Not only will users wonder why your application is accessing their telephony stack, it might be difficult to migrate data over if the user gets a new device.

Update: As mentioned in the comments below, this is not a secure way to authenticate users, and raises privacy concerns. It is not recommended. Instead, look at the Google+ Login API if you want to implement a frictionless login system.

The Android Backup API is also available if you just want a lightweight way to persist a bundle of strings for when a user resets their phone (or buys a new device).

Drove answered 29/12, 2009 at 1:1 Comment(13)
What would be a better solution then which would enable them to migrate data in the future? Google email address? If so how can I pull that out from the system?Frye
The most reliable way to do this is to just have them create an account the first time they launch your app. There are ways to get the user's email address (see the docs on AccountManager), but verifying that a malicious user hasn't forged this information requires a bit of knowledge about how the Google Data APIs work -- more than I can put in this small comment box. ;)Drove
Actually, for that matter, you don't have any guarantee that the user hasn't forged their IMEI/MEID either. If security is of any concern, you really need to use either a username/password, or the getAuthToken() method in AccountManager (and again, you'd need to verify this token with the server that originally issued it).Drove
Trevor is it possible that you provide me the complete code ?Gardening
Adi: The code for getting the device ID? There's nothing more than the one method + permission I mentioned above. That said, you should look into the Google+ Login API, that's the recommended approach for authenticating users these days: developer.android.com/google/play-services/auth.htmlDrove
Check this answer : #2480788Lauzon
Hi, OP has asked how to get IMEI, MEID/ESN ids. Will getDeviceId() query respective one in the respective phone? Or is getDeviceId only for IMEI, and for MEID/ESN there's another line of code?Krugersdorp
Is it possible to get the IMEI of a device without a SIM card? My Nexus7 tablet always returns null when using this method.Gaeta
Is it running Android 6? And are you targeting SDK 23? Then you need to request READ_PHONE_STATE at runtime before querying the IMEIMaduro
i think getDeviceId not working anymore guys, getDeviceId() This method was deprecated in API level O. Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns MEID for CDMA.Swiss
what is the solution for android 10?Micturition
For Android 10 you now need READ_PRIVILEGED_PHONE_STATE which is protected so it will not workVapory
There are MANY problems in trying to use the device IMEI as a device identifier: First and foremost since Android 10 there is NO WAY of getting such information, In second place there are devices that have NO IMEI (there are a lot of tablets that have only the wifi adapter) and there are DUAL SIM phones which actually have TWO different IMEIs: the API call cited in all these answers will return the IMEI of the first sim slot containing a SIM card: if user moves the sim card to the other slot, your device will return the other IMEI... you can't rely on it unless you track ALL device IMEIsBeadledom
E
291

In addition to the answer of Trevor Johns, you can use this as follows:

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

And you should add the following permission into your Manifest.xml file:

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

In emulator, you'll probably get a like a "00000..." value. getDeviceId() returns NULL if device ID is not available.

Eckard answered 9/6, 2010 at 19:44 Comment(6)
Is there a way to get the emulator to return an IMEI number?Milliliter
@MikeSchem, emulator does not have a meaningful IMEI string.Handfast
Try don't use: <uses-permission android:name="android.permission.READ_PHONE_STATE" /> this permission is very sensitive, you can get App Rejected from Google Play Team(new security rules added at late of2018). As advice better use Advertising ID.Compute
@Eckard Will it work on Dual sim device? (Need to get First IMEI only)Negotiant
Is there any security concern for using READ_PHONE_STATE permission?Compiler
getDeviceId(); is deprecated use getImei()Sholokhov
D
66

I use the following code to get the IMEI or use Secure.ANDROID_ID as an alternative, when the device doesn't have phone capabilities:

/**
 * 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;
}
Dibranchiate answered 15/4, 2013 at 12:58 Comment(7)
TextUtils.isEmpty() - > if (identifier == null || identifier .length() == 0)Rooker
Hi Pinhassi, Did you have any case when device ID returned by telephony manager was null or empty, but the value read from Secure.ANDROID_ID was non-empty? Thank youMambo
As far as I can recall it was for tablets with no SIM card (but I'm not 100% sure).Dibranchiate
Secure.ANDROID_ID changes if Device is formatted or rom is factory resetJillayne
My Nexus7(1stGen) returns null for the telephony deviceId... Anyone know how to get an IMEI from a tablet?Gaeta
Would ANDROID_ID be FDR-persistent - the ID survives factory reset?Handler
Try don't use: <uses-permission android:name="android.permission.READ_PHONE_STATE" /> this permission is very sensitive, you can get App Rejected from Google Play Team(new security rules added at late of 2018). As advice better use Advertising ID instead IMEICompute
D
43

Or you can use the ANDROID_ID setting from Android.Provider.Settings.System (as described here strazerre.com).

This has the advantage that it doesn't require special permissions but can change if another application has write access and changes it (which is apparently unusual but not impossible).

Just for reference here is the code from the blog:

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

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

Implementation note: if the ID is critical to the system architecture you need to be aware that in practice some of the very low end Android phones & tablets have been found reusing the same ANDROID_ID (9774d56d682e549c was the value showing up in our logs)

Decibel answered 20/10, 2010 at 10:22 Comment(4)
This constant is deprecated. You instead need to use android.provider.Settings.Secure.ANDROID_ID;Stocktonontees
@Stocktonontees when i using android.provider.Settings.Secure.ANDROID_ID for nexus 7 tablet and nexus 4 it return same value 'android_id'Chickie
@meowmeo did the same for me, until I used the code which is now a part of the answer (ish). String androidID = android.provider.Settings.System.getString(this.getContentResolver(), Secure.ANDROID_ID);Uranyl
But wouldn't this get reset to a new ANDROID_ID upon factory reset? What if I need a persistent ANDROID_ID that can survive resets.Handler
P
35

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

The following code helps in obtaining IMEI number of android devices :

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

Permissions required in Android Manifest:

android.permission.READ_PHONE_STATE

NOTE: In case of tablets or devices which can’t act as Mobile Phone IMEI will be null.

Panic answered 28/4, 2012 at 17:32 Comment(4)
this is actual code which i am finding for get IMEILahr
Unfortunately, with Marshmallow forward you now have to ask for this permission at runtime. This permission is not ideal, as it disturbs the user experience, and may make some users suspicious.Handler
Try don't use: <uses-permission android:name="android.permission.READ_PHONE_STATE" /> this permission is very sensitive, you can get App Rejected from Google Play Team(new security rules added at late of 2018). As advice better use Advertising ID instead IMEICompute
what is the solution for android 10?Micturition
P
24

to get IMEI (international mobile equipment identifier)

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

to get device unique id

public String getDeviceUniqueID(Activity activity){
    String device_unique_id = Secure.getString(activity.getContentResolver(),
            Secure.ANDROID_ID);
    return device_unique_id;
}
Pruter answered 24/9, 2014 at 4:17 Comment(1)
Showing the device_unique_id alternative is really helpfulAlvertaalves
M
20

For Android 6.0+ the game has changed so i suggest you use this;

The best way to go is during runtime else you get permission errors.

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

Hope this helps you or someone.

Merriment answered 2/5, 2016 at 2:15 Comment(0)
C
18

As in API 26 getDeviceId() is depreciated so you can use following code to cater API 26 and earlier versions

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

Don't forget to add permission requests for READ_PHONE_STATE to use the above code.

UPDATE: From Android 10 its is restricted for user apps to get non-resettable hardware identifiers like IMEI.

Charmain answered 17/8, 2017 at 11:10 Comment(6)
Mind sharing where can I find reference for the method 'getImei()"?Luxembourg
Sure please use developer.android.com/reference/android/telephony/… for getImei() referenceCharmain
what is the solution for android 10?Micturition
Amin unfortunately in Android 10 due to security reason it is now restricted for third party apps to get Hardware identifiers like IMEI for more info on privacy changes in Android 10 visit developer.android.com/about/versions/10/privacyCharmain
Works on Android Oreo.Lord
You can use "imei = Settings.Secure.getString(MainLogin.this.getContentResolver(), Settings.Secure.ANDROID_ID);" in place of getImei() for Android 10Zagreus
A
17

New Update:

For Android Version 6 And Above, WLAN MAC Address has been deprecated , follow Trevor Johns answer

Update:

For uniquely Identification of devices, You can Use Secure.ANDROID_ID.

Old Answer:

Disadvantages of using IMEI as Unique Device ID:

  • IMEI is dependent on the Simcard slot of the device, so it is not possible to get the IMEI for the devices that do not use Simcard. In Dual sim devices, we get 2 different IMEIs for the same device as it has 2 slots for simcard.

You can Use The WLAN MAC Address string (Not Recommended For Marshmallow and Marshmallow+ as WLAN MAC Address has been deprecated on Marshmallow forward. So you'll get a bogus value)

We can get the Unique ID for android phones using the WLAN MAC address also. The MAC address is unique for all devices and it works for all kinds of devices.

Advantages of using WLAN MAC address as Device ID:

  • It is unique identifier for all type of devices (smart phones and tablets).

  • It remains unique if the application is reinstalled

Disadvantages of using WLAN MAC address as Device ID:

  • Give You a Bogus Value from Marshmallow and above.

  • If device doesn’t have wifi hardware then you get null MAC address, but generally it is seen that most of the Android devices have wifi hardware and there are hardly few devices in the market with no wifi hardware.

SOURCE : technetexperts.com

Addieaddiego answered 7/7, 2016 at 16:31 Comment(6)
"IMEI is dependent on the Simcard"... This is false. You seem to be confusing the IMEI with the IMSI numberNothingness
An International Mobile Station Equipment Identity or IMEI for short is a number that identifies mobile phones that run on a GSM network. I have personally tried it and it gives me null programmitically if there is no wireless carrier on GSM Phone. smartmobilephonesolutions.com/content/…Addieaddiego
You're right, I didn't read carefully. The IMEI is associated to the SIM card transceiver, not to the SIM card. My bad!Nothingness
WLAN MAC Address has been deprecated on Marshmallow forward. So you'll get a bogus value!Handler
android 6 dont return correct WIFI MAC Address with your code. Notice it.Romanov
what is the solution for android 10?Micturition
G
11

The method getDeviceId() of TelephonyManager returns the unique device ID, for example, the IMEI for GSM and the MEID or ESN for CDMA phones. Return null if device ID is not available.

Java Code

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> 

Permission Required READ_PHONE_STATE in manifest file.

Gardening answered 17/6, 2013 at 7:20 Comment(0)
W
5

You can use this TelephonyManager TELEPHONY_SERVICE function to get unique device ID, Requires Permission: READ_PHONE_STATE

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

Example, the IMEI for GSM and the MEID or ESN for CDMA phones.

/**
 * 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();
}

Return null if device ID is not available.

Wilmot answered 4/9, 2017 at 8:19 Comment(2)
and why device Id null? because of rooted device.Datha
what is the solution for android 10?Micturition
N
5

Try this(need to get first IMEI always)

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();
        }
Negotiant answered 1/3, 2019 at 5:6 Comment(1)
what is the solution for android 10? developer.android.com/about/versions/10/privacyMicturition
K
3

Use below code gives you IMEI number:

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
System.out.println("IMEI::" + telephonyManager.getDeviceId());
Kho answered 17/12, 2013 at 7:0 Comment(0)
H
3

The method getDeviceId() is deprecated. There a new method for this getImei(int)

Check here

Hannelorehanner answered 28/6, 2018 at 13:41 Comment(1)
what is the solution for android 10?Micturition
T
2

You'll need the following permission in your AndroidManifest.xml:

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

To get IMEI (international mobile equipment identifier) and if It is above API level 26 then we get telephonyManager.getImei() as null so for that, we use ANDROID_ID as a Unique Identifier.

 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;
    }
Trifle answered 16/1, 2020 at 14:13 Comment(0)
E
2

For Android 10 Following code is working for me.

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

Edris answered 26/5, 2020 at 16:11 Comment(0)
D
2

Restriction on non-resettable device identifiers

Starting in Android 10, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access the device's non-resettable identifiers, which include both IMEI and serial number.

https://developer.android.com/about/versions/10/privacy/changes#non-resettable-device-ids

Durning answered 1/8, 2021 at 16:21 Comment(1)
Caution: Third-party apps installed from the Google Play Store cannot declare privileged permissions developer.android.com/about/versions/10/privacy/…Animalist
R
1

for API Level 11 or above:

case TelephonyManager.PHONE_TYPE_SIP: 
return "SIP";

TelephonyManager tm= (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
textDeviceID.setText(getDeviceID(tm));
Reede answered 24/5, 2013 at 12:39 Comment(0)
C
1

Kotlin Code for getting DeviceId ( IMEI ) with handling permission & comparability check for all android versions :

 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

    }

Also add this permission to AndroidManifest.xml :

<uses-permission android:name="android.permission.READ_PHONE_STATE"/> <!-- IMEI-->
Covenant answered 23/12, 2018 at 12:6 Comment(0)
S
1

use below code:

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

And call onRequestPermissionsResult method following code:

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

Add following permission in your AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Spittle answered 11/2, 2020 at 10:19 Comment(1)
This code will fail on Android 10+ even if you hold the READ_PHONE_STATE permission. If I read correctly exceptions are only made for device-manufacturer or carrier preinstalled apps. Also google says to use getIMEI() instead of getDeviceId for Android 8.Convict
C
1

There is no Way you can get imei number from andorid 10+ or 29+ mobiles here is the alternative function that will be used for creating imei number for devices.

public  static String getDeviceID(){
    String devIDShort = "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

    return  devIDShort;
}
Cockburn answered 13/7, 2021 at 7:19 Comment(2)
I suggest that if using same device types this should turn out to be the same Number for all of them making it non - usable. Clearly most of the things refer to certain hardware types of manufacturer names that should be the same for same device type. I would also suggest that google would not overlook such an easy way of still getting a hardware ID while they state that ALL hardware IDs are protected in Android10+Convict
IMEI Number is unable to get from Android 10Cockburn
E
0

For those looking for a Kotlin version, you can use something like this;

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

NOTE: You must wrap telephonyService() above with a permission check using checkSelfPermission or whatever method you use.

Also add this permission in the manifest file;

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Envision answered 2/12, 2018 at 10:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.