Using a MAC Address
I believe that the policies say not to use the IMEI because this can be changed and can be unsafe, because "Chinese/pirates" pairs may have IMEI of a non-transpirated apparatus and there is also the possibility to change the IMEI.
Bad guys do it all the time.
In the very link you posted has a solution to your problem, use the bluetooth MAC or the wifi device, as it is a hardware physically attached to the device and is much more unlikely to be changed. In addition to having unique identifiers.
The problem with this approach is that it apparently stopped being available after Android 6.0, but some users seem to have succeeded using Reflection
private static String getBtAddressViaReflection() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Object bluetoothManagerService = new Mirror().on(bluetoothAdapter).get().field("mService");
if (bluetoothManagerService == null) {
Log.w(TAG, "couldn't find bluetoothManagerService");
return null;
}
Object address = new Mirror().on(bluetoothManagerService).invoke().method("getAddress").withoutArgs();
if (address != null && address instanceof String) {
Log.w(TAG, "using reflection to get the BT MAC address: " + address);
return (String) address;
} else {
return null;
}
}
You have more information about this here
Using Android ID
If the MAC solution doesn’t work, there is the possibility to use Android ID, which is a unique identifier for each user, however it can change or return Null after a factory reset.
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),Secure.ANDROID_ID);
There are some problems related to this approach, but it seems that most of the problems have been solved.
Using the phone
Such an approach shall not operate on appliances which have no function
to make calls. Ex: Tablets, Tvs, Watches and Vehicles.
If your solution is phone-facing, you can use Telephonemanager and take the ids/serial and create an identifier:
Add permission to the Manifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Import the libraries:
import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
And the code is...
final Telephonymanager tm = (Telephonymanager) getBaseContext(). getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
This solution should return something like 00000000-54b3-e7c7-0000-000046bffd97
.
For more information see this link
I hope I’ve helped
Get a look at this question: https://stackoverflow.com/questions/2785485/is-there-a-unique-android-device-id
– LMaker
I believe that the policies say not to use the IMEI because this can be changed and can be unsafe, because "Chinese" pirates may have IMEI of a non-transpirated apparatus and there is also the possibility to change the IMEI. Bad guys do that. In the very link you posted has a solution to your problem, use the bluetooth MAC or the wifi device, as it is a hardware physically attached to the device and is much more unlikely to be changed. In addition to having unique identifiers.
– Guilherme Batista
@Guilhermebatista, what breaks me is this part: "from Android M, the MAC addresses of local devices (for example, Wi-Fi and Bluetooth) will not be available via third-party Apis"
– Thiago Luiz Domacoski
Really, I didn’t mean it. This kind of thing is for security reasons not to track user between different networks. (If you know the user’s network you could know the path it goes through). Then you can use the
AndroidID
, but it can change if the user does a factory reset. :private String android_id = Secure.getString(getContext().getContentResolver(),
 Secure.ANDROID_ID);
Do not forget to import the libraryimport android.provider.Settings.Secure;
– Guilherme Batista
Well I was already doing one
– Guilherme Batista