问题原因
- 今日在 APP 登录中,一直登录不上,提示序列号异常(内部提醒),一直很奇怪,代码几乎没动过任何代码;逛了一圈代码,最后才发现是自己的设备升级到了
Android 8.0 (Android O)
以上,导致获取不到序列号; - 本文章进行总结下从
Android 4.4 - Android 9.0
版本中适配获取序列号(SN) 的方法
因为 APP 会针对序列号进行限制设备使用(方便辨识)
代码变更
现写法
/**
* 获取序列号
*
* @time 2020/8/5 15:17
*/
public static String setSerialNumber(Context context) {
String serial = null;
try {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// // 9.0 +
// serial = Build.getSerial();
// } else
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
// 8.0 +
if (ActivityCompat.checkSelfPermission( context, Manifest.permission.READ_PHONE_STATE ) != PackageManager.PERMISSION_GRANTED) {
return "没有权限";
}
serial = Build.getSerial();
} else {
// 8.0 -
Class<?> c = Class.forName( "android.os.SystemProperties" );
Method get = c.getMethod( "get", String.class );
serial = (String) get.invoke( c, "ro.serialno" );
}
} catch (Exception e) {
e.printStackTrace();
Log.e( "setSerialNumber", "获取设备序列号失败" );
}
return serial;
}
- 如果你在 Android 8.0 以上的版本运行,它会一直报
Access denied finding property "ro.serialno"
这个错,原因是Android O
为了更好的管理用户的隐私做了一些调整,通过Build.SERIAL
来进行获取序列号,很便捷;
改进后
知识补充
- 为了与访问 IMEI 所需的运行时权限保持一致,对于针对 Android O 或更新版本的应用,现已弃用 android.os.Build.SERIAL。它们可以改为使用新的 Android O API,即Build.getSerial(),只要调用方拥有 PHONE 权限,该函数将返回实际序列号。在未来版本的 Android 中,针对 Android O 的应用所查询到的 Build.SERIAL 将显示为“UNKNOWN”。为避免中断旧版应用的正常工作,针对以前版本 Android 的应用所查询到的设备序列号仍和以前一样。
意思也就是,在
Android O
版本上也可以通过Build.getSerial()
进行获取序列号;
- 通过
Build.getSerial()
的调用获取需要调用方拥有PHONE
权限
<uses-permission android:那么="android.permission.READ_PHONE_STATE" />
最后
- 因个人
APP
的版本使用的,使用的api
版本较低,所以在P 和 O
版本中获取序列号进行了区别; - 各位可直接使用
Build.getSerial()
进行获取,避免后续版本的更新导致获取为 “UNKNOWN” 的情况