一、获取各种单一的设备标识方式
1、DEVICE_ID
概念:是区别移动设备的标志,储存在移动设备中,可用于监控被窃或无效的移动设备。
优点:根据不同的手机设备返回IMEI,MEID或者ESN码,唯一性良好
缺点:由于获取该唯一值,需要android.peimision.READ_PHONE_STATE,如果设备没有通话功能就返回为null
关键代码:
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imei = tm.getDeviceId();
测试结果:小米HM note Android4.4.4 能正常获取该ID
华为H60-L03 Android4.4.2 能正常获取该ID
三星Galaxy S5 Android5.0 能正常获取该ID

2、WIFI MAC
概念:获取手机wifi的Mac地址作为唯一标识
优点:
缺点:如果设备没有支持WIFI的硬件,就返回null
关键代码:
    WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    WifiInfo info = wifi.getConnectionInfo().getMacAddress();
    String wifiMac = info.getMacAddress();
测试结果:小米HM note Android4.4.4 能正常获取该ID
          华为H60-L03 Android4.4.2 能正常获取该ID
          三星Galaxy S5 Android5.0 能正常获取该ID

3、BlueTooth MAC
概念:获取手机的蓝牙Mac地址作为唯一设备标识
优点:
缺点:如果设备没有支持蓝牙的硬件,就返回null
关键代码:
    BluetoothAdapter btAdapter = null; //本地蓝牙适配器
    btAdapter = BluetoothAdapter.getDefaultAdapter();
    String btMacAddress = btAdapter.getAddress();
测试结果:小米HM note Android4.4.4 能正常获取该ID
          华为H60-L03 Android4.4.2 能正常获取该ID
          三星Galaxy S5 Android5.0 能正常获取该ID

4、SIM Serial Number
概念:SIM卡的序列号
优点:
缺点:没有SIM卡就返回null
      对于CDMA设备,返回null
关键代码:
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
String sn = tm.getSimSerialNumber();
测试结果:小米HM note Android4.4.4 有装SIM卡 能正常获取该ID
          华为H60-L03 Android4.4.2 没有SIM卡 返回ID为null
          三星Galaxy S5 Android5.0 没有SIM卡 返回ID为null

5、利用设备各个硬件拼接出一个ID
概念:设备内的每个硬件都有一个名称,利用名称的长度的个位数组合成一个设备标识ID
优点:非手机设备也可以通过该接口获取ID
缺点:统一型号的设备出现相同ID的可能性比较大
关键代码:
    String DevIDShort = "35" + //头部加上"35",这样这个ID看起来就和15位IMEI一样了     
    Build.BOARD.length() % 10 +
    Build.BRAND.length() % 10 +
    Build.CPU_ABI.length() % 10 +
    Build.DEVICE.length() % 10 +
    Build.DISPLAY.length() % 10 +
    Build.HOST.length() % 10 +
    Build.ID.length() % 10 +
    Build.MANUFACTURER.length() % 10 +
    Build.MODEL.length() % 10 +
    Build.PRODUCT.length() % 10 +
    Build.TAGS.length() % 10 +
    Build.TYPE.length() % 10 +
    Build.USER.length() % 10;
测试结果:小米HM note Android4.4.4 能正常获取该ID
          华为H60-L03 Android4.4.2 能正常获取该ID
          三星Galaxy S5 Android5.0 能正常获取该ID

6、Android_ID
概念:当设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来
优点:
缺点:由于厂商定制的Bug,不同的设备可能会产生相同的ANDROID_ID或返回值为null
      Andorid手机被Root过的话,这个ID也可以被任意改变
关键代码:
    String androidID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
测试结果:小米HM note Android4.4.4 能正常获取该ID
          华为H60-L03 Android4.4.2 能正常获取该ID
          三星Galaxy S5 Android5.0 能正常获取该ID

7、Serial Number
概念:Android系统2.3版本以上可以获取硬件Serial Number
优点:非手机设备也可以通过该接口获取ID
缺点:
关键代码:
    String sn = android.os.Build.SERIAL;
测试结果:小米HM note Android4.4.4 能正常获取该ID
          华为H60-L03 Android4.4.2 能正常获取该ID
          三星Galaxy S5 Android5.0 能正常获取该ID

二、自定义一个设备标识ID
问题分析:由于Android并没有一个统一靠谱的设备标识,所以我就参考腾讯的做法,自定义一个设备标识ID。
算法逻辑:利用上面获取的各个方式的标识ID,拼接成一个字符串,再利用消息摘要,生成MD5值作为设备标识ID
关键代码:

public static String encryptMD5(byte[] data) throws NoSuchAlgorithmException{ 
 MessageDigest md5 = MessageDigest.getInstance(“MD5”); 
 md5.update(data); 
 byte[] resultBytes = md5.digest(); 
 return resultBytes.toString(); 
 }

 获取开源项目GitHub:http://github.com/littleRich/