I am getting IMEI null in Android Q?

AndroidImei

Android Problem Overview


I am getting the IMEI ID null from the telephonymanager. What to do?

is there any workaround for that?

Android Solutions


Solution 1 - Android

Android Q has restricted to access for both IMEI and serial no. It is available only for platform and apps with special carrier permission. Also the permission READ_PRIVILEGED_PHONE_STATE is not available for non platform apps.

If you try to access it throws below exception

java.lang.SecurityException: getImeiForSlot: The user 10180 does not meet the requirements to access device identifiers.

Please refer documentation: https://developer.android.com/preview/privacy/data-identifiers#device-ids

Also refer Issue

Solution 2 - Android

I am late to post answer. I still believe my answer will help someone. Android 10 Restricted developer to Access IMEI number.

You can have a alternate solution by get Software ID. You can use software id as a unique id. Please find below code as i use in Application.

public static String getDeviceId(Context context) {

 String deviceId;

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        deviceId = Settings.Secure.getString(
                context.getContentResolver(),
                Settings.Secure.ANDROID_ID);
    } else {
        final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephony.getDeviceId() != null) {
            deviceId = mTelephony.getDeviceId();
        } else {
            deviceId = Settings.Secure.getString(
                    context.getContentResolver(),
                    Settings.Secure.ANDROID_ID);
        }
    }

    return deviceId;
}

Solution 3 - Android

This just would not work as of Android Q. Third party apps can not use IMEI nor the serial number of a phone and other non-resettable device identifiers.

The only permissions that are able to use those is READ_PRIVILEGED_PHONE_STATE and that cannot be used by any third party apps - Manufacture and Software Applications. If you use that method you will get an error Security exception or get null .

You can still try to get a unique id by using:

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),Secure.ANDROID_ID);
 

Solution 4 - Android

The best way to get the IMEI number is as follows:

    public static String getIMEIDeviceId(Context context) {

        String deviceId;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
        {
            deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
        } else {
            final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (context.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                    return "";
                }
            }
            assert mTelephony != null;
            if (mTelephony.getDeviceId() != null)
            {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                {
                    deviceId = mTelephony.getImei();
                }else {
                    deviceId = mTelephony.getDeviceId();
                }
            } else {
                deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            }
        }
        Log.d("deviceId", deviceId);
        return deviceId;
    }

Just copy the method and use it. It will definitely. However, you might know you can't get IMEI in android Q (version 10). In this code, you can get a unique identifier (alternative id) through any device or any API level. It works 100% Thank You!! And Enjoy Coding :)

Solution 5 - Android

As the best practices suggest. " you can avoid using hardware identifiers, such as SSAID (Android ID) and IMEI, without limiting required functionality."

Rather go for an instance ID such as String uniqueID = UUID.randomUUID().toString(); or FirebaseInstanceId.getInstance().getId();

Solution 6 - Android

Not sure about IMEI number, but you can get the simSerialNumber and other carrier info this way.

getSimSerialNumber() needs privileged permissions from Android 10 onwards, and third party apps can't register this permission.

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

A possible solution is to use the TELEPHONY_SUBSCRIPTION_SERVICE from Android 5.1, to retrieve the sim serial number. Steps below:

  • Check for READ_PHONE_STATE permission.

  • Get Active subscription list.( Returns the list of all active sim cards)

  • Retrieve the sim details from Subscription Object.

       if ( isPermissionGranted(READ_PHONE_STATE) ) {
    
            String simSerialNo="";
            
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
            
                SubscriptionManager subsManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 
    
                List<SubscriptionInfo> subsList = subsManager.getActiveSubscriptionInfoList();
    
                if (subsList!=null) {
                    for (SubscriptionInfo subsInfo : subsList) {
                        if (subsInfo != null) {
                            simSerialNo  = subsInfo.getIccId();
                        }
                    }
                }
            } else {
                TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                simSerialNo = tMgr.getSimSerialNumber();
            }
        }
    

Check if this helps

Solution 7 - Android

you can change other way, i use uuid to replace devices id.

 String uniquePseudoID = "35" +
            Build.BOARD.length() % 10 +
            Build.BRAND.length() % 10 +
            Build.DEVICE.length() % 10 +
            Build.DISPLAY.length() % 10 +
            Build.HOST.length() % 10 +
            Build.ID.length() % 10 +
            Build.MANUFACTURER.length() % 10 +
            Build.MODEL.length() % 10 +
            Build.PRODUCT.length() % 10 +
            Build.TAGS.length() % 10 +
            Build.TYPE.length() % 10 +
            Build.USER.length() % 10;
    String serial = Build.getRadioVersion();
    String uuid = new UUID(uniquePseudoID.hashCode(), serial.hashCode()).toString();
    AppLog.d("Device ID",uuid);

Solution 8 - Android

If your app targets Android 10 or higher, a SecurityException occurs.

Following modules are affected...

Build
    getSerial()
TelephonyManager
    getImei()
    getDeviceId()
    getMeid()
    getSimSerialNumber()
    getSubscriberId()

So you cant get IMEI no for android 10 , You have to used another unique identifier for this like Android ID

It unique 64 bit hex no for device

private String android_id = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);

Solution 9 - Android

According to google docs.

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.

> Caution: Third-party apps installed from the Google Play Store cannot > declare privileged permissions.

So, Instead of imei you can get Android unique ID.

        String imei = "";
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
                if (telephonyManager != null) {
                    try {
                        imei = telephonyManager.getImei();
                    } catch (Exception e) {
                        e.printStackTrace();
                        imei = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
                    }
                }
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
            }
        } else {
            if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
                if (telephonyManager != null) {
                    imei = telephonyManager.getDeviceId();
                }
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
            }
        }

Solution 10 - Android

Targeting Android Q, third party apps can't access IMEI at all. Android Q doc is misleading while stating > Starting in Android Q, 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/preview/privacy/data-identifiers#device-ids

But when I actually tried to implement it, I am receiving this exception:

java.lang.SecurityException: getDeviceId: The user 10132 does not meet the requirements to access device identifiers.

Someone had reported this on google's issue tracker where a Googler said that this is intended behaviour and IMEI on Q+ is only available for system level apps.

> Status: Won't Fix (Intended Behavior) This is Working As Intended. > IMEI is a personal identifier and this is not given out to apps as a > matter of policy. There is no workaround.

https://issuetracker.google.com/issues/129583175#comment10

Solution 11 - Android

They mentioned: If your app is the device or profile owner app, you need only the READ_PHONE_STATE permission to access non-resettable device identifiers, even if your app targets Android 10 or higher.

I tried deploying via EMM as device owner app but not success.

Solution 12 - Android

If you needed, you can try to install a work profile in to the mobile phone and include your app in the same package or vice versa.

I tried and it works, it's simple if yo follow this repo: https://github.com/googlesamples/android-testdpc

When you install the Work Profile your app is installed in this profile and you will have acces to the IMEI.

And now there is another example fixed yesterday to Android 10: https://github.com/android/enterprise-samples/pull/29

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAman VermaView Question on Stackoverflow
Solution 1 - AndroidtakharshView Answer on Stackoverflow
Solution 2 - AndroidSatishView Answer on Stackoverflow
Solution 3 - AndroidAditya BhawsarView Answer on Stackoverflow
Solution 4 - AndroidTechnical RivalView Answer on Stackoverflow
Solution 5 - AndroidJoe MalebeView Answer on Stackoverflow
Solution 6 - AndroidAdarsh ChithranView Answer on Stackoverflow
Solution 7 - AndroidVen RenView Answer on Stackoverflow
Solution 8 - AndroidrawhostView Answer on Stackoverflow
Solution 9 - AndroidAhsanView Answer on Stackoverflow
Solution 10 - AndroidYousuf SohailView Answer on Stackoverflow
Solution 11 - AndroidSy Nguyen DinhView Answer on Stackoverflow
Solution 12 - AndroidJoel GarciaView Answer on Stackoverflow