How do I get information about a phone's IMEI

2020-02-13 05:37发布

问题:

Before Android 10, I was using the TelephonyManager API to retrieve that info, but it's no longer working in Android 10.

回答1:

From the Android Developers Documentation Website

Starting in Android 10, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access the device's non-resettable identifiers, which include both IMEI and serial number.

Third-party apps installed from the Google Play Store cannot declare privileged permissions.

If your app doesn't have the permission and you try asking for information about non-resettable identifiers anyway, the platform's response varies based on target SDK version:

  • If your app targets Android 10 or higher, a SecurityException occurs.
  • If your app targets Android 9 (API level 28) or lower, the method returns null or placeholder data if the app has the READ_PHONE_STATE permission. Otherwise, a SecurityException occurs.

If you try to access it, it throws the below exception: java.lang.SecurityException: getImeiForSlot: The user 10180 does not meet the requirements to access device identifiers.



回答2:

I'm facing the same problem, but, in my case, I have a kind of "backup" code that returns a UUID. Here is a code that you could use:

String uniqueID = UUID.randomUUID().toString();

This code is usefull if you want a "instalation unique identifier" but, doesn't works as a device unique identifier because if the user unistall and re install your app, the UUID returned will be different than the last one.

In my case, I use the UUID.nameUUIDFromBytes to generated a UUID by a given "name" and I'm using the Settings.Secure.ANDROID_ID as the "name" for the UUID. Using this method you "grantee" the returned UUID will be the same, UNLESS the user do a factory reset.

Here is the code:

   String androidId = Settings.Secure.getString(context.getContentResolver(),
            Settings.Secure.ANDROID_ID);

   UUID androidId_UUID = UUID
            .nameUUIDFromBytes(androidId.getBytes("utf8"));

   String unique_id = androidId_UUID.toString();

Until here, everything seens ok, but the problem is: since Android 10 was released, Google doesn't recommend the uses of any kind of "hardware indentifier" and this includes the Settings.Secure.ANDROID_ID. This actually is my concern, because in the company that I work for, we use the IMEI or this UUID to identify our customers users and define if an user is trying to log in more than one device, which is not allowed by our rules, and to build some statics. If the UUID isn't unique for the same device we'll have to review all of our user access control.

Here is the Android Developers link about unique identifiers good pratices. https://developer.android.com/training/articles/user-data-ids

And here is the same link, but with an anchor where Google describes some use cases and the best option of unique identifier for each one. https://developer.android.com/training/articles/user-data-ids#common-use-cases

None of use cases fit with mine, so I'm still loking for a better solution.

I hope this could help someone.