public class

TelephonyManagerCompat

extends java.lang.Object

 java.lang.Object

↳androidx.core.telephony.TelephonyManagerCompat

Gradle dependencies

compile group: 'androidx.core', name: 'core', version: '1.9.0-alpha04'

  • groupId: androidx.core
  • artifactId: core
  • version: 1.9.0-alpha04

Artifact androidx.core:core:1.9.0-alpha04 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.core:core com.android.support:support-compat

Overview

Helper for accessing features in .

Summary

Methods
public static java.lang.StringgetImei(TelephonyManager telephonyManager)

Returns the IMEI (International Mobile Equipment Identity) associated with the subscription id of the given TelephonyManager, or null if not available.

public static intgetSubscriptionId(TelephonyManager telephonyManager)

Return the subscription ID the TelephonyManager was created with (via ) if applicable, and otherwise the default subscription ID.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Methods

public static java.lang.String getImei(TelephonyManager telephonyManager)

Returns the IMEI (International Mobile Equipment Identity) associated with the subscription id of the given TelephonyManager, or null if not available.

Below Android 10, this API requires any of:

  • the caller holds the READ_PHONE_STATE permission
  • the caller has carrier privileges (see )

On Android 10 and above, this API requires any of:

  • the caller holds the READ_PRIVILEGED_PHONE_STATE permission
  • the caller is the device or profile owner and holds the READ_PHONE_STATE permission
  • the caller has carrier privileges (see )
  • the caller is the default SMS role holder (see )
  • the caller holds the USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER permission

public static int getSubscriptionId(TelephonyManager telephonyManager)

Return the subscription ID the TelephonyManager was created with (via ) if applicable, and otherwise the default subscription ID.

Source

/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.core.telephony;

import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;

import android.annotation.SuppressLint;
import android.os.Build.VERSION;
import android.telephony.TelephonyManager;

import androidx.annotation.DoNotInline;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.RequiresPermission;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Helper for accessing features in {@link TelephonyManager}.
 */
public class TelephonyManagerCompat {

    private static Method sGetDeviceIdMethod;
    private static Method sGetSubIdMethod;

    /**
     * Returns the IMEI (International Mobile Equipment Identity) associated with the
     * subscription id of the given TelephonyManager, or null if not available.
     *
     * <p>Below Android 10, this API requires any of:
     * <ul>
     *     <li>the caller holds the READ_PHONE_STATE permission</li>
     *     <li>the caller has carrier privileges (see
     *     {@link TelephonyManager#hasCarrierPrivileges()})</li>
     * </ul>
     *
     * <p>On Android 10 and above, this API requires any of:
     * <ul>
     *     <li>the caller holds the READ_PRIVILEGED_PHONE_STATE permission</li>
     *     <li>the caller is the device or profile owner and holds the READ_PHONE_STATE
     *     permission</li>
     *     <li>the caller has carrier privileges (see
     *     {@link TelephonyManager#hasCarrierPrivileges()})</li>
     *     <li>the caller is the default SMS role holder (see
     *     {@link android.app.role.RoleManager#isRoleHeld(String)})</li>
     *     <li>the caller holds the USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER permission</li>
     * </ul>
     */
    @SuppressLint("MissingPermission")
    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    @Nullable
    public static String getImei(@NonNull TelephonyManager telephonyManager) {
        if (VERSION.SDK_INT >= 26) {
            return Api26Impl.getImei(telephonyManager);
        } else if (VERSION.SDK_INT >= 22) {
            // below Android O the telephony manager has a severe bug (b/137114239) where many
            // methods do not properly respect the subscription id and always use the default
            // subscription id. so if we have a non-default subscription id, we need to do the work
            // ourselves...
            int subId = getSubscriptionId(telephonyManager);
            if (subId != DEFAULT_SUBSCRIPTION_ID && subId != INVALID_SUBSCRIPTION_ID) {
                int slotIndex = SubscriptionManagerCompat.getSlotIndex(subId);
                if (VERSION.SDK_INT >= 23) {
                    return Api23Impl.getDeviceId(telephonyManager, slotIndex);
                } else {
                    try {
                        if (sGetDeviceIdMethod == null) {
                            sGetDeviceIdMethod = TelephonyManager.class.getDeclaredMethod(
                                    "getDeviceId",
                                    int.class);
                            sGetDeviceIdMethod.setAccessible(true);
                        }

                        return (String) sGetDeviceIdMethod.invoke(telephonyManager, slotIndex);
                    } catch (NoSuchMethodException ignored) {
                    } catch (IllegalAccessException ignored) {
                    } catch (InvocationTargetException ignored) {
                    }

                    return null;
                }
            }
        }

        return telephonyManager.getDeviceId();
    }

    /**
     * Return the subscription ID the TelephonyManager was created with (via
     * {@link TelephonyManager#createForSubscriptionId(int)}) if applicable, and otherwise the
     * default subscription ID.
     */
    @SuppressLint("SoonBlockedPrivateApi")
    public static int getSubscriptionId(@NonNull TelephonyManager telephonyManager) {
        if (VERSION.SDK_INT >= 30) {
            return Api30Impl.getSubscriptionId(telephonyManager);
        } else if (VERSION.SDK_INT >= 22) {
            try {
                if (sGetSubIdMethod == null) {
                    sGetSubIdMethod = TelephonyManager.class.getDeclaredMethod("getSubId");
                    sGetSubIdMethod.setAccessible(true);
                }

                Integer subId = (Integer) sGetSubIdMethod.invoke(telephonyManager);
                if (subId != null && subId != INVALID_SUBSCRIPTION_ID) {
                    return subId;
                }
            } catch (InvocationTargetException ignored) {
            } catch (IllegalAccessException ignored) {
            } catch (NoSuchMethodException ignored) {
            }
        }

        return DEFAULT_SUBSCRIPTION_ID;
    }

    private TelephonyManagerCompat() {}

    @RequiresApi(30)
    private static class Api30Impl {
        private Api30Impl() {}

        @DoNotInline
        static int getSubscriptionId(TelephonyManager telephonyManager) {
            return telephonyManager.getSubscriptionId();
        }
    }

    @RequiresApi(26)
    private static class Api26Impl {
        private Api26Impl() {}

        @SuppressLint("MissingPermission")
        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
        @DoNotInline
        @Nullable
        static String getImei(TelephonyManager telephonyManager) {
            return telephonyManager.getImei();
        }
    }

    @RequiresApi(23)
    private static class Api23Impl {
        private Api23Impl() {}

        @SuppressLint("MissingPermission")
        @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
        @DoNotInline
        @Nullable
        static String getDeviceId(TelephonyManager telephonyManager, int slotIndex) {
            return telephonyManager.getDeviceId(slotIndex);
        }
    }
}