Android获取Imei新版本和老版本兼容性

Android中获取设备的唯一标志,一般都是获取Imei,需要读取手机状态的权限如下

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

那么现在Android已经到9.0了,好多API都需要去兼容,包括获取Imei的API,一般我们获取Imei都会用getDeviceId这个方法,或者是getDeviceId带参数的这个方法,如下

 /**
     * 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.
     *
     * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
     * MEID for CDMA.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public String getDeviceId() {
        try {
            ITelephony telephony = getITelephony();
            if (telephony == null)
                return null;
            return telephony.getDeviceId(mContext.getOpPackageName());
        } catch (RemoteException ex) {
            return null;
        } catch (NullPointerException ex) {
            return null;
        }
    }

    /**
     * Returns the unique device ID of a subscription, for example, the IMEI for
     * GSM and the MEID for CDMA phones. Return null if device ID is not available.
     *
     * @param slotIndex of which deviceID is returned
     *
     * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
     * MEID for CDMA.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public String getDeviceId(int slotIndex) {
        // FIXME this assumes phoneId == slotIndex
        try {
            IPhoneSubInfo info = getSubscriberInfo();
            if (info == null)
                return null;
            return info.getDeviceIdForPhone(slotIndex, mContext.getOpPackageName());
        } catch (RemoteException ex) {
            return null;
        } catch (NullPointerException ex) {
            return null;
        }
    }

代码是从Android的TelephoenyManager.java中取的源码,我们能看到@Deprecated这个词,意味着这些接口在现在已经被废弃了,当然废弃是针对现在新的系统。

在Android 8.0以下的版本中用上边贴出来的方法还是可以获取设备标志的,但如果在8.0以上包含8.0的系统用上面的方式是取不出来的。我们需要用心的API方法来获取如下:

 /**
     * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
     * available.
     */
    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public String getImei() {
        return getImei(getSlotIndex());
    }

    /**
     * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
     * available.
     *
     * @param slotIndex of which IMEI is returned
     */
    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
    public String getImei(int slotIndex) {
        ITelephony telephony = getITelephony();
        if (telephony == null) return null;

        try {
            return telephony.getImeiForSlot(slotIndex, getOpPackageName());
        } catch (RemoteException ex) {
            return null;
        } catch (NullPointerException ex) {
            return null;
        }
    }

当然写的时候需要兼容新设备以及老设备,需要分不同设备的系统版本来调用不同的接口来获取

可以像下面这样判断版本

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
       //这里用心的API, 就是getImei
 } else {
      //这里用老的API,就是getDeviceId
 }

整体代码可以像这样

TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
     String imei;
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            imei = telephonyManager.getImei();
      }
      else {
            imei = telephonyManager.getDeviceId();
      }
       return imei;
}
0 0 vote
Article Rating
Subscribe
提醒
guest
0 评论
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x