问题
Our client's app main feature is heavily relaying on tracking their clients' devices, they offer products that are bound to the specific phone(not its owner). This was possible using the device imei, but with the privacy changes in Android 10, they made it unreachable. (https://developer.android.com/about/versions/10/privacy/changes).
Android has a documentation about what identifier to use on specific user cases, but non matches our case since we need it to be unique, constant and bound to the device(or at least difficult to change). https://developer.android.com/training/articles/user-data-ids. I'm considering Android ID to be a possible solution, or using the mac address knowing they aren't 100% reliable.
Any thoughts? recommendations? experiences? at this point anything could be an option
回答1:
I advice you to read the official blog of the best practice of google to see what the use case match with your specification : https://developer.android.com/training/articles/user-data-ids.html
For me i occcured the same problem about the unicity of android identifiers and i found the only solution is to use the MediaDrm API ( https://android.googlesource.com/platform/frameworks/base/+/android-cts-4.4_r1/media/java/android/media/MediaDrm.java#539 ) which contains a unique device id and can survive even on the factory reset and doesn't need any additional permission on your manifest file.
Here is the couple of code how can we retreive the unique identifier on 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:
- You can access android device id by gms service. see the given example below,
private DeviceInfoProvider mDeviceInfo = new DeviceInfoProvider(Context)
String mDeviceId = DeviceInfoProvider.getDeviceId(Context);
Log.d("DEVICE_ID" , mDeviceId);
- On a device first boot, a random value is generated and stored. This value is available via Settings.Secure.ANDROID_ID. It’s a 64-bit number that should remain constant for the lifetime of a device. ANDROID_ID seems a good choice for a unique device identifier because it’s available for smartphones and tablets. To retrieve the value, you can use the following code,
String androidId = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ANDROID_ID);
However, the value may change if a factory reset is performed on the device. There is also a known bug with a popular handset from a manufacturer where every instance has the same ANDROID_ID. Clearly, the solution is not 100% reliable.
- Use UUID. As the requirement for most of the applications is to identify a particular installation and not a physical device, a good solution to get the unique id for a user if to use UUID class. The following solution has been presented by Reto Meier from Google in a Google I/O presentation,
SharedPreferences sharedPrefs = context.getSharedPreferences(
PREF_UNIQUE_ID, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
来源:https://stackoverflow.com/questions/58103580/android-10-imei-no-longer-available-on-api-29-looking-for-alternatives