最近这3天,一直在做获取手机的,imei1,imei2,meid,sn等手机系统信息的小app,在做的过程中,遇到了很多问题,发现网络上对这块的技术帖子,并不多,关键是还不详细,有的帖子三言两语,几句话,其实说的还是4.0版本的获取,获取了imei 获取不到meid,有的帖子贴了一堆代码,其实也并没有什么卵用,有的帖子一长串反射代码,也是无关痛痒, 所以今天我想把我这3天的心得,分享出来,也想让广大开发者,提供点个人的帮助!开始之前,这是方法getDeviceId()的源码,这串英文 我就不翻译了,自己看,网上大部分帖子都是说用这个,其实这个只是4.0的时候拿的。但是4.0的手机也有双卡手机,所以这就有坑了市面上的安卓手机,有很多种,系统也有各种各样,有的4.0左右系统,有的5.0左右系统,有的6.0左右系统,有单卡槽的,有双卡槽的,有全网通的,有卡槽一个是uim一个是 Sim的,有双SIM的现在我讲图文并茂展示下,我手上测试机,测试后的情况
1.魅族PRO 6手机 双卡双待 ,卡1卡2均为SIM卡,系统是基于安卓5.0的 有自己的SIM下面的图,是我自己写的安卓代码得到的下面图。是关于设置里面查找的这是运行的GIF动态图
2.手机是魅族 pro6 plus双卡手机,它是没有MEID 的,手机系统是5.0+
3.手机是最老的 魅族not 系统是4.0+,双卡手机 卡1是UIM 卡2是SIM
总结以上:基于安卓系统。4.0 5.0 6.0的系统4.0的系统如果想获取MEID/IMEI1/IMEI2 ----其实是很难做到的。 因为你只能只用getDeviceId() 这个方法5.0的系统如果想获取MEID/IMEI1/IMEI2 ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取meid、imei1、imei2(5.0的时候如果想要获取,必须使用反射方法,去拿,下面慢慢看。我会把代码贴出来)6.0的系统如果想获取MEID/IMEI1/IMEI2 ---- 直接获取系统api getDeviceId(int slotId) //指定slotId的deviceId getDeviceId(0) getDeviceId(1) 但是全网通手机Phone在初始化时只创建了GSMPhone,并没有创建CDMAPhone,此时是无法获取到meid。只有插入CDMA卡才会通过PhoneProxy的deleteAndCreatePhone方法,将其中一个phone删除,重新创建CDMALTEPhone。但是,由于支持盲插功能,我们并不知道用户会将cdma卡插入哪个卡槽,CDMALTEPhone有可能是卡1,也有可能是卡2。因此使用google原生接口获取deviceId会出现如下三种情况:
1、不插卡(或两张卡都是GSM卡) getDeviceId() 返回 imei1 getDeviceId(0) 返回 imei1 getDeviceId(1) 返回 imei2
2、卡1插CDMA卡,卡2不插卡(或卡2插GSM卡) getDeviceId() 返回 meid getDeviceId(0) 返回 meid getDeviceId(1) 返回 imei2
3、卡2插CDMA卡,卡1不插卡(或卡1插GSM卡) getDeviceId() 返回 imei1 getDeviceId(0) 返回 imei1 getDeviceId(1) 返回 meid好吧,上面罗里吧嗦的说了一堆, 我就直接上代码了
if (Build.VERSION.SDK_INT < 21) {
//如果获取系统的IMEI/MEID,14位代表meid 15位是imei
if (GetSystemInfoUtil.getNumber(getActivity()) == 14) {
mTvPhoneMeid.setText(GetSystemInfoUtil.getImeiOrMeid(getActivity()));//meid
} else if (GetSystemInfoUtil.getNumber(getActivity()) == 15) {
mTvPhoneImei.setText(GetSystemInfoUtil.getImeiOrMeid(getActivity()));//imei1
}
// 21版本是5.0,判断是否是5.0以上的系统 5.0系统直接获取IMEI1,IMEI2,MEID
} else if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT<23) {
mTvPhoneImei.setText(GetSystemInfoUtil.getImei1());//imei1
mTvPhoneOtherImei.setText(GetSystemInfoUtil.getImei2());//imei2
mTvPhoneMeid.setText(GetSystemInfoUtil.getMeid());//meid
}
else if(Build.VERSION.SDK_INT>=23){
final TelephonyManager tm = (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
String imei1 = tm.getDeviceId(0);
String imei2 = tm.getDeviceId(1);
mTvPhoneImei.setText(imei1);//imei1
mTvPhoneOtherImei.setText(imei2);//imei2
mTvPhoneMeid.setText(GetSystemInfoUtil.getMeid());//meid
}
/**
* 获取SN
*
* @return
*/
public static String getSn(Context ctx) {
// if (android.os.Build.SERIAL.equals("unknown")) {
//MX3手机会出现这个
String serial = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
} catch (Exception ignored) {
}
return serial;
// } else {
// return android.os.Build.SERIAL;
// }
}
/**
* 系统4.0的时候
* 获取手机IMEI 或者Meid
*
* @return 手机IMEI
*/
public static String getImeiOrMeid(Context ctx) {
TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
if (tm != null) {
return tm.getDeviceId();
}
return null;
}
/**
* 获取IMEI IMEI2 MEID
* @param ctx
* @return
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public static Map getImeiAndMeid(Context ctx) {
Map<String, String> map = new HashMap<String, String>();
TelephonyManager mTelephonyManager = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
Class<?> clazz = null;
Method method = null;//(int slotId)
try {
clazz = Class.forName("android.os.SystemProperties");
method = clazz.getMethod("get", String.class, String.class);
String gsm = (String) method.invoke(null, "ril.gsm.imei", "");
String meid = (String) method.invoke(null, "ril.cdma.meid", "");
map.put("meid", meid);
if (!TextUtils.isEmpty(gsm)) {
//the value of gsm like:xxxxxx,xxxxxx
String imeiArray[] = gsm.split(",");
if (imeiArray != null && imeiArray.length > 0) {
map.put("imei1", imeiArray[0]);
if (imeiArray.length > 1) {
map.put("imei2", imeiArray[1]);
} else {
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} else {
map.put("imei1", mTelephonyManager.getDeviceId(0));
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} else {
map.put("imei1", mTelephonyManager.getDeviceId(0));
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return map;
}
/**
* 获取手机系统内部信息工具类
* Created by yangbin on 3/2/2017.
*/
public class GetSystemInfoUtil {
/**
* 获取当前手机系统版本号
*
* @return 系统版本号
*/
public static String getSystemVersion() {
return Build.DISPLAY;
//return android.os.Build.VERSION.RELEASE;
}
/**
* 获取手机型号
*
* @return 手机型号
*/
public static String getSystemModel() {
return Build.MODEL;
}
/**
* 获取手机厂商
*
* @return 手机厂商
*/
public static String getDeviceBrand() {
return Build.BRAND;
}
/**
* 获取SN
*
* @return
*/
public static String getSn(Context ctx) {
String serial = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
} catch (Exception ignored) {
}
return serial;
}
/**
* 系统4.0的时候
* 获取手机IMEI 或者Meid
*
* @return 手机IMEI
*/
public static String getImeiOrMeid(Context ctx) {
TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
if (tm != null) {
return tm.getDeviceId();
}
return null;
}
/**
* 拿到imei或者meid后判断是有多少位数
*
* @param ctx
* @return
*/
public static int getNumber(Context ctx) {
int count = 0;
long number = Long.parseLong(getImeiOrMeid(ctx).trim());
while (number > 0) {
number = number / 10;
count++;
}
return count;
}
/**
* Flyme 说 5.0 6.0统一使用这个获取IMEI IMEI2 MEID
* @param ctx
* @return
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public static Map getImeiAndMeid(Context ctx) {
Map<String, String> map = new HashMap<String, String>();
TelephonyManager mTelephonyManager = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
Class<?> clazz = null;
Method method = null;//(int slotId)
try {
clazz = Class.forName("android.os.SystemProperties");
method = clazz.getMethod("get", String.class, String.class);
String gsm = (String) method.invoke(null, "ril.gsm.imei", "");
String meid = (String) method.invoke(null, "ril.cdma.meid", "");
map.put("meid", meid);
if (!TextUtils.isEmpty(gsm)) {
//the value of gsm like:xxxxxx,xxxxxx
String imeiArray[] = gsm.split(",");
if (imeiArray != null && imeiArray.length > 0) {
map.put("imei1", imeiArray[0]);
if (imeiArray.length > 1) {
map.put("imei2", imeiArray[1]);
} else {
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} else {
map.put("imei1", mTelephonyManager.getDeviceId(0));
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} else {
map.put("imei1", mTelephonyManager.getDeviceId(0));
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return map;
}
}
下面贴出我的整个工具类
/**
* 获取手机系统内部信息工具类
* Created by yangbin on 3/2/2017.
*/
public class GetSystemInfoUtil {
/**
* 获取当前手机系统版本号
*
* @return 系统版本号
*/
public static String getSystemVersion() {
return Build.DISPLAY;
//return android.os.Build.VERSION.RELEASE;
}
/**
* 获取手机型号
*
* @return 手机型号
*/
public static String getSystemModel() {
return Build.MODEL;
}
/**
* 获取手机厂商
*
* @return 手机厂商
*/
public static String getDeviceBrand() {
return Build.BRAND;
}
/**
* 获取SN
*
* @return
*/
public static String getSn(Context ctx) {
String serial = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
} catch (Exception ignored) {
}
return serial;
}
/**
* 系统4.0的时候
* 获取手机IMEI 或者Meid
*
* @return 手机IMEI
*/
public static String getImeiOrMeid(Context ctx) {
TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
if (tm != null) {
return tm.getDeviceId();
}
return null;
}
/**
* 拿到imei或者meid后判断是有多少位数
*
* @param ctx
* @return
*/
public static int getNumber(Context ctx) {
int count = 0;
long number = Long.parseLong(getImeiOrMeid(ctx).trim());
while (number > 0) {
number = number / 10;
count++;
}
return count;
}
/**
* Flyme 说 5.0 6.0统一使用这个获取IMEI IMEI2 MEID
* @param ctx
* @return
*/
@RequiresApi(api = Build.VERSION_CODES.M)
public static Map getImeiAndMeid(Context ctx) {
Map<String, String> map = new HashMap<String, String>();
TelephonyManager mTelephonyManager = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
Class<?> clazz = null;
Method method = null;//(int slotId)
try {
clazz = Class.forName("android.os.SystemProperties");
method = clazz.getMethod("get", String.class, String.class);
String gsm = (String) method.invoke(null, "ril.gsm.imei", "");
String meid = (String) method.invoke(null, "ril.cdma.meid", "");
map.put("meid", meid);
if (!TextUtils.isEmpty(gsm)) {
//the value of gsm like:xxxxxx,xxxxxx
String imeiArray[] = gsm.split(",");
if (imeiArray != null && imeiArray.length > 0) {
map.put("imei1", imeiArray[0]);
if (imeiArray.length > 1) {
map.put("imei2", imeiArray[1]);
} else {
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} else {
map.put("imei1", mTelephonyManager.getDeviceId(0));
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} else {
map.put("imei1", mTelephonyManager.getDeviceId(0));
map.put("imei2", mTelephonyManager.getDeviceId(1));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return map;
}
}
Activity调用
if (Build.VERSION.SDK_INT < 21) {
//如果获取系统的IMEI/MEID,14位代表meid 15位是imei
if (GetSystemInfoUtil.getNumber(getActivity()) == 14) {
mTvPhoneMeid.setText(GetSystemInfoUtil.getImeiOrMeid(getActivity()));//meid
} else if (GetSystemInfoUtil.getNumber(getActivity()) == 15) {
mTvPhoneImei.setText(GetSystemInfoUtil.getImeiOrMeid(getActivity()));//imei1
}
// 21版本是5.0,判断是否是5.0以上的系统 5.0系统直接获取IMEI1,IMEI2,MEID
} else if (Build.VERSION.SDK_INT >= 21) {
Map<String, String> map = GetSystemInfoUtil.getImeiAndMeid(getActivity());
mTvPhoneImei.setText(map.get("imei1"));//imei1
mTvPhoneOtherImei.setText(map.get("imei2"));//imei2
mTvPhoneMeid.setText(map.get("meid"));//meid
}
mTvPhoneSn.setText(GetSystemInfoUtil.getSn(getActivity()));//SN
mTvPhoneModels.setText(GetSystemInfoUtil.getSystemModel());//手机型号 PRO6
mTvVersionNumber.setText(GetSystemInfoUtil.getSystemVersion());//软件版本号 FLYME 6.02
}