我们客户的应用程序主要功能是大量跟踪客户的设备,他们提供绑定到特定手机(而不是其所有者)的产品。使用设备imei可以做到这一点,但是随着Android 10中隐私权的更改,他们使其无法访问。 (https://developer.android.com/about/versions/10/privacy/changes)。
Android上有关于在特定用户情况下使用什么标识符的文档,但与我们的情况不符,因为我们需要它是唯一的,恒定的并绑定到设备(或至少很难更改)。 https://developer.android.com/training/articles/user-data-ids。 我正在考虑使用Android ID作为可能的解决方案,或者使用知道不可靠的Mac地址。
有什么想法吗?建议?经验?在这一点上,任何事情都可以作为选择
答案 0 :(得分:13)
对于对@Sofien解决方案感兴趣的Java用户,我有:
@Nullable
String getUniqueID() {
UUID wideVineUuid = new UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L);
try {
MediaDrm wvDrm = new MediaDrm(wideVineUuid);
byte[] wideVineId = wvDrm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID);
return Arrays.toString(wideVineId);
} catch (Exception e) {
// Inspect exception
return null;
}
// Close resources with close() or release() depending on platform API
// Use ARM on Android P platform or higher, where MediaDrm has the close() method
}
有两个主要区别@Sophien的代码。
MessageDigest
,因此代码更简单。此外,MessageDigest.update()
方法将SHA-256
哈希函数应用于其参数,这导致丢失UUID唯一性的可能性极低。不对UUID进行散列的唯一缺点是您没有固定长度的UUID,而我在应用程序中对此并不关心。toHexString
,而不是Kotlin函数Arrays.toString
(Java中没有单行对应的函数)。此选择是安全的,因为(A)它不会抛出Exception
,并且(B)它会保留wideVineId
及其String
表示形式之间一一对应的关系。如果您希望坚持十六进制转换,则Apache Commons Codec库提供了单行解决方案,请参见this answer。当然,这些更改会导致产生不同的UUID,不必说其他选择也是可能的。还要注意,用Arrays.toString
生成的UUID的格式为
[92, -72, 76, -100, 26, -86, 121, -57, 81, -83, -81, -26, -26, 3, -49, 97, -24, -86, 17, -106, 25, 102, 55, 37, 47, -5, 33, -78, 34, 121, -58, 109]
因此,如果您不想在UUID中使用特殊字符,则可以使用String.replaceAll()
将其删除。
我已经测试了UUID的持久性
在以下设备/操作系统组合上:
在所有测试中,targetSdkVersion
是29。欢迎进行更多测试(尤其是在API 29上)。
答案 1 :(得分:2)
我建议您阅读google最佳实践的官方博客,以了解用例与您的规范相符的情况:https://developer.android.com/training/articles/user-data-ids.html
对我来说,我在android标识符的唯一性方面也遇到了同样的问题,我发现唯一的解决方案是使用MediaDrm API(https://android.googlesource.com/platform/frameworks/base/+/android-cts-4.4_r1/media/java/android/media/MediaDrm.java#539) 其中包含唯一的设备ID,即使在恢复出厂设置后也可以保留,并且无需对清单文件进行任何其他权限。
以下是几段代码,我们如何检索Android 10上的唯一标识符:
import android.media.MediaDrm
import java.security.MessageDigest
import java.util.*
object UniqueDeviceID {
/**
* UUID for the Widevine DRM scheme.
* <p>
* Widevine is supported on Android devices running Android 4.3 (API Level 18) and up.
*/
fun getUniqueId(): String? {
val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
var wvDrm: MediaDrm? = null
try {
wvDrm = MediaDrm(WIDEVINE_UUID)
val widevineId = wvDrm.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)
val md = MessageDigest.getInstance("SHA-256")
md.update(widevineId)
return md.digest().toHexString()
} catch (e: Exception) {
//WIDEVINE is not available
return null
} finally {
if (AndroidPlatformUtils.isAndroidTargetPieAndHigher()) {
wvDrm?.close()
} else {
wvDrm?.release()
}
}
}
fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }
}
答案 2 :(得分:1)
> rep(k, each = 5)
[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4
private DeviceInfoProvider mDeviceInfo = new DeviceInfoProvider(Context)
String mDeviceId = DeviceInfoProvider.getDeviceId(Context);
Log.d("DEVICE_ID" , mDeviceId);
但是,如果在设备上执行了出厂重置,则该值可能会更改。制造商的流行手机中也存在一个已知错误,该错误中每个实例都具有相同的 ANDROID_ID 。显然,该解决方案并非100%可靠。
String androidId = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ANDROID_ID);
答案 3 :(得分:-5)
我已经在诺基亚手机中对其进行了测试,“在出厂重置时重置手机时,标识符已更改”。您是否在恢复出厂设置时对其进行了测试?