android 设备id问题汇总 - bei1999/work GitHub Wiki
前言
经常听到某某需求提要获取设备唯一id,用途就多了,要跟踪设备,做个收藏了(看完全文你就知道这个需求并不完美实现)
IMEI
这个算是最常见的了
android 中获取imei 代码如下
/**
* 获取手机IMEI号
*
* 需要动态权限: android.permission.READ_PHONE_STATE
*/
public static String getIMEI(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
String imei = telephonyManager.getDeviceId();
return imei;
}
缺点:
- 需求电话包下面权限,android 6.0后需要授权(授权相关讲解可以参阅我的其android 6.0 权限管理) 用户拒绝的情况下就获取不到。
- android 设备很多,山寨机可能是重复的或者直接取不到。
- 获取的是电话包下的,也就是说需要有电话包或者说有电话功能的设备,pad没戏。
下面的系统源码说明了一切
**
* 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) {
return null;
} catch (NullPointerException ex) {
return null;
}
}
Serial Number
android.os.Build.SERIAL
/** A hardware serial number, if available. Alphanumeric only, case-insensitive. */
public static final String SERIAL = getString("ro.serialno");
缺点:
- android 2.3以上,据说有些设备获取有问题
SimSerialNumber
android.telephony.TelephonyManager tm = (android.telephony.TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String simSerialNum = tm.getSimSerialNumber();
缺点:
- 需求电话包下面权限,android 6.0后需要授权(授权相关讲解可以参阅我的其android 6.0 权限管理) 用户拒绝的情况下就获取不到。
- 需要正常可用的sim卡,没卡的设备或者pad 不能获取。
- 跟sim卡相关,号码唯一性不能完全放心
MacAddress
android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String macAddress = wifi.getConnectionInfo().getMacAddress();
缺点:
- 需要 ACCESS_WIFI_STATE 权限,android 6.0后需要授权(授权相关讲解可以参阅我的其android 6.0 权限管理) 用户拒绝的情况下就获取不到。
- Android 6.0 使用存在风险,google service 会提示有害程序。
ANDROID_ID
String androidId = android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
缺点
- 设备第一次启动的时候生成并保存,并且可能会在恢复出厂设置后重置该值。理论上是大部分是重置的。
- 跟操作系统相关,多个用户帐号,获取不同。
- android 设备很多,山寨机可能是重复的或者直接取不到。
总结
上面列出了一些获取到的系统id,使用还是要根据自己的情况使用,若允许用户授权操作,imei可以考虑,若不希望打扰用户,不在乎刷机等问题,可以使用android_id,极端情况可以考虑服务器产生id,下发的方式,比如做登录系统oauth 2.0等