Saturday, July 7, 2012

whoami

Quite often you application must generate unique identifier for current instance of application to create server account linked with current device. Ideally, this identifier should persists on application reinstallation, so even after application being deleted and installed again the same account will be used for application on current device.

The simplest (and, probably, the most correct) approach is to use TelephonyManager#getDeviceId.
 mDeviceId = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()  
Unfortunately, deviceId may be null for devices w.o. GSM or CDMA module. Another way is to use Serial Number. This identifier is available via Build#SERIAL from android api 9. So, to cover older os versions let's use reflection:
 Class<?> c = Class.forName("android.os.SystemProperties");  
 Class<?>[] paramTypes= new Class[1];  
 paramTypes[0]= String.class;  
 Method get = c.getMethod("get", paramTypes);  
 Object[] params= new Object[1];  
 params[0]= new String("ro.serialno");  
 mDeviceId = (String) get.invoke(c, params);  
Serial identifier is quite 'unpredictable' and may be absent on Samsung devices, so we have to have more options to cover much more devices. Next step will be Secure#ANDROID_ID - randomly generated 64-bit number on the device's first boot:
 mDeviceId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);  
But even this value sometimes is null (unfortunately, I don't remember devices on which this problem can be reproduced). Furthermore, this values will be changed upon factory reset.
It is also possible to use wi-fi mac address as identifier for application instance:
 mDeviceId = ((WifiManager)context.getSystemService(Context.WIFI_SERVICE)).getConnectionInfo().getMacAddress();  
But not all devices have wi-fi. Also, if the wi-fi is not turned on, the hardware may not report the Mac address (null will be returned). As a last resort identifier can be generated using UUID#randomUUID. This is mutable value, but it can be stored somewhere on sdcard to persist it's value after reinstallation. Probably, it's all available options to get unique id. Hopefully, order of presentation provides correct 'brute-force' algorithm of searching identifier.