问题介绍
我们如果在项目之中调用了TelephonyManager 对象,获取手机设备的唯一标识。就可能会出现上面的权限不足问题。
不管是获取imei
还是deviceId
。都会出现SecurityException错误。
错误日志通常如下:
java.lang.SecurityException
getDeviceId: The user 10251 does not meet the requirements to access device identifiers.
android.os.Parcel.createExceptionOrNull(Parcel.java:2376)
android.os.Parcel.createException(Parcel.java:2360)
android.os.Parcel.readException(Parcel.java:2343)
android.os.Parcel.readException(Parcel.java:2285) com.android.internal.telephony.ITelephony$Stub$Proxy.getDeviceIdWithFeature(ITelephony.java:11481)
6 android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java:1939)
The user 10251 does not meet the requirements to access device identifiers.
用户10251不符合访问设备标识符的要求。
原因
因为Android 10开始(API 29)。我们普通应用开发者就不能调用TelephonyManager 获取设备的唯一标识信息。
总的来说,就是Android 从10开始不允许我们随意调用设备信息了。除非你是属于系统应用,或者特殊许可才能访问。否则就会出现。
但是有些小伙伴就会说了。我原先也可以啊,原先在android 11设备上都不会崩溃。或者我打包后在很多android 11手机上都能使用啊,就是小米不能用并崩溃了啊。
解释
1.如果原先能够用现在不能用了,那么你需要注意一下是不是targetSdkVersion
调整为29了。
2.为啥同样都是Android 11,华为不崩溃小米部分型号崩溃了?例如小米M2012K11AC
官方说了这样写会给你SecurityException错误,但是有些系统并没有报错,而是给你返回了null。然后有些就执行了这个错误。所以,只是当初没有暴发而已。
解决方法
1.在build.gradle 文档中降低targetSdkVersion
调整为28。
2.废弃使用getDeviceId 或者imei的方法。针对这种情况Android 官方也有相关的推荐方案。建议我们使用广告ID,实例ID,GUID等等
最简单的使用方法:
Java 写法
String uniqueID = UUID.randomUUID().toString();
kotlin 写法
var uniqueID = UUID.randomUUID().toString()
或者我们自己根据信息,初始化一个唯一标识。
减少使用系统上的标识。
同时不建议使用mac地址, 因为较大可能获取不到mac地址。或者返回个null
如果你觉得上面的示例满足不了你的需求,可以参考:
评论区