Android 获取 唯一UUID ,替换 IMEI (兼容 Android 10+获取IMEI问题)
背景
谷歌在Android 10(API 级别 29)对不可重置的标识符(包括 IMEI 和序列号)添加了限制,导致我们无法获取到对应的IMEI值,不过给了我们其他方法就是获取GUID来作为唯一表示:
关于
最近项目上需求需要在用户登录的时候获取手机设备唯一标识,原来的代码里面有获取的方法:
手机调试版本 OPPO Android 11
/**
* 获取系统sn
*
* @return
*/
public static String getSn(Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return "";
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return Build.getSerial();
//也有用到ANDROID_ID,但是因为会变所以不合适,如果不是特别要求的话你们可以使用下面这个,这样就不用继续往下看去适配了
//Settings.System.getString( App.getInstance().getContentResolver(), Settings.Secure.ANDROID_ID);
} else {
String sn = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
sn = (String) get.invoke(c, "ro.serialno");
} catch (Exception e) {
e.printStackTrace();
}
return sn;
}
}
上面那段代码不会奔溃报错,但是返回的sn值在Android Q(10)+为null,即我们获取不到值,在谷歌开发者平台上给了我们适配方法,就是通过获取32位GUID来作为唯一表示,因为GUID在当前时间点是唯一的,所以可以作为标记设备唯一:
就是通过String u = UUID.randomUUID().toString();
来获取,当然了获取之后才是重点,因为这个UUID是根据一些时间等逻辑进行实时生成的,所以我们需要对它进行保存,以便作为唯一标识。
保存GUID方案
- 第一种,使用SharedPreferemces存储(缺点会随着app卸载移除)
- 第二种.使用android自带sqlite数据库存储(这里我用的郭老师的litepal存储,但是后面发现也会随着app卸载移除)
- 第三种,以外部存储方式存储文件(不存在app私有目录下)(缺点文件删除,UUID随之移除)
第一种,SharedPreferemces存储
存储uuid
// 通过判断isFirst的值来进行第一次uuid的存储,后续再打开app都不会刷新这个存储的uuid的值,app卸载或者重新安装会被重置
boolean isFirst;
SharedPreferences sharedPref = App.getInstance().getSharedPreferences(
"myuuid", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
isFirst = sharedPref.getBoolean("isFirst",true);
if