IMEI获取流程源码分析

本文详细分析了Android 6.0.1源码中获取IMEI的流程,包括权限调用和IMEI获取步骤。首先,通过TelephonyManager调用ITelephony接口的getDeviceId()方法,接着探讨了权限判断过程,涉及READ_PHONE_STATE权限的检查。然后,深入到PhoneInterfaceManager和PhoneBase类,揭示了GSMPhone如何获取IMEI。最后,展示了RIL类如何与硬件交互以获取IMEI,并通过IPC通信返回结果。
摘要由CSDN通过智能技术生成

IMEI是设备唯一性的一个重要指标,这篇文章对IMEI获取做一些分析,以达到以下两个目的:

1、梳理Android源码中获取IMEI流程

2、理解获取IMEI时,源码中权限调用流程

备注:以下源码分析,针对的是Android 6.0.1源码

 

在Android代码中,我们需要获取设备的IMEI,只需调用下面方法


TelephonyManager telephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
imei = telephonyMgr.getDeviceId();

接下来就看看源码中是怎样获取IMEI的。


/**
 * 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.
 *
 * <p>Requires Permission:
 *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
 */
public String getDeviceId() {
    try {
        ITelephony telephony = getITelephony();
        if (telephony == null)
            return null;
        return telephony.getDeviceId(mContext.getOpPackageName());
    } catch (RemoteException ex) {
        ......
    }
}

在TelephonyManager中,可以看到是先获取ITelephony对象,然后在通过该Interface的getDeviceid()方法来获取IMEI的。ITelephony是一个aidl的接口,所以接下来我们需要找到实现这个接口的对应实现类

/**
 * Implementation of the ITelephony interface.
 */
public class PhoneInterfaceManager extends ITelephony.Stub {
  
    ......
  
   /**
     * Returns the unique device ID of phone, for example, the IMEI for
     * GSM and the MEID for CDMA phones. Return null if device ID is not available.
     *
     * <p>Requires Permission:
     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
     */
    @Override
    public String getDeviceId(String callingPackage) {
        if (!canReadPhoneState(callingPackage, "getDeviceId")) {
            return null;
        }
 
        final Phone phone = PhoneFactory.getPhone(0);
        if (phone != null) {
            return phone.getDeviceId();
        } else {
            return null;
        }
    }
  
    ......
}

        首先,通过上面类的声明可以看到,PhoneInterfaceManager这个类实现了ITelephony.stub接口,因此就是这个接口的对应的实现类。接下来我们看看对应实现的getDeviceId()方法。

        这个方法首先通过canReadPhoneState()方法来判断权限是否通过,如果没有权限直接就返回null了。权限通过之后才会去获取deviceId。

        我们这次分析的目的,一个是权限流程分析,一个是IMEI获取流程分析,这里我们通过canReadPhoneState()方法看看权限相关的判断流程,然后在接着看IMEI的获取流程。

 

1、权限判断流程

     通过上面canReadPhoneState()函数入口,我们看看具体的实现。

private boolean canReadPhoneState(String callingPackage, String message) {
    try {
        mApp.enforceCallingOrSelfPermission(
                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
 
        // SKIP checking for run-time permission since caller or self has PRIVILEDGED permission
        return true;
    } catch (SecurityException e) {
        mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
                message);
    }
 
    if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
            callingPackage) != AppOpsManager.MODE_ALLOWED) {
        return false;
    }
 
    return true;
}

      该函数中,首先在try代码块中尝试获取READ_PRIVILEGED_PHONE_STATE权限,如果有这个权限就直接默认权限通过了。一般这个私有权限是系统的应用有,第三方应用都是没有的,所以会抛出安全异常,走到catch代码块中。

       在catch代码块,就是真正的去检查应用是否有对应需要的READ_PHONE_STATE权限了。接下来我们需要看看该方法的具体实现

class ContextImpl extends Context {
    ......
  
    @Override
    public void enforceCallingOrSelfPermission(
            String permission, String message) {
        enforce(permission,
                checkCallingOrSelfPermission(permission),
                true,
                Binder.getCallingUid(),
                message);
    }
  
    @Override
    public int checkCallingOrSelfPermission(String permission) {
        if (permission == null) {
            throw new IllegalArgumentException("permission is null");
        }
 
        return checkPermission(permission
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值