有很多场景和需求你需要用到手机设备的唯一标识符。

在Android中,有以下几种方法获取这样的ID。

1. The IMEI: 仅仅只对Android手机有效:

12
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); String szImei = TelephonyMgr.getDeviceId(); 

采用此种方法,需要在AndroidManifest.xml中加入一个许可:android.permission.READ_PHONE_STATE,并且用户应当允许安装此应用。作为手机来讲,IMEI是唯一的,它应该类似于 359881030314356(除非你有一个没有量产的手机(水货)它可能有无效的IMEI,如:0000000000000)。

2. Pseudo-Unique ID, 这个在任何Android手机中都有效
有一些特殊的情况,一些如平板电脑的设置没有通话功能,或者你不愿加入READ_PHONE_STATE许可。而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现这一点。这样计算出来的ID不是唯一的(因为如果两个手机应用了同样的硬件以及Rom 镜像)。但应当明白的是,出现类似情况的可能性基本可以忽略。要实现这一点,你可以使用Build类:

 1 2 3 4 5 6 7 8 9101112131415
String m_szDevIDShort = "35" + //we make this look like a valid 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 ; //13 digits

大多数的Build成员都是字符串形式的,我们只取他们的长度信息。我们取到13个数字,并在前面加上“35”。这样这个ID看起来就和15位IMEI一样了。

3. The Android ID
通常被认为不可信,因为它有时为null。开发文档中说明了:这个ID会改变如果进行了出厂设置。并且,如果某个Andorid手机被Root过的话,这个ID也可以被任意改变。

1
String m_szAndroidID = Secure.getString(getContentResolver(), Secure.ANDROID_ID);

Returns: 9774d56d682e549c . 无需任何许可。

4. The WLAN MAC Address string
是另一个唯一ID。但是你需要为你的工程加入android.permission.ACCESS_WIFI_STATE 权限,否则这个地址会为null。

12
WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE); String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();

Returns: 00:11:22:33:44:55 (这不是一个真实的地址。而且这个地址能轻易地被伪造。).WLan不必打开,就可读取些值。

5. The BT MAC Address string
只在有蓝牙的设备上运行。并且要加入android.permission.BLUETOOTH 权限.

123
BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter      m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();      String m_szBTMAC = m_BluetoothAdapter.getAddress();

Returns: 43:25:78:50:93:38 . 蓝牙没有必要打开,也能读取。

Combined Device ID
综上所述,我们一共有五种方式取得设备的唯一标识。它们中的一些可能会返回null,或者由于硬件缺失、权限问题等获取失败。
但你总能获得至少一个能用。所以,最好的方法就是通过拼接,或者拼接后的计算出的MD5值来产生一个结果。

 1 2 3 4 5 6 7 8 91011121314151617181920212223
String m_szLongID = m_szImei + m_szDevIDShort     + m_szAndroidID+ m_szWLANMAC + m_szBTMAC;      // compute md5      MessageDigest m = null;   try { m = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace();   }    m.update(m_szLongID.getBytes(),0,m_szLongID.length());   // get md5 bytes   byte p_md5Data[] = m.digest();   // create a hex string   String m_szUniqueID = new String();   for (int i=0;i<p_md5Data.length;i++) {        int b =  (0xFF & p_md5Data[i]);    // if it is a single digit, make sure it have 0 in front (proper padding)        if (b <= 0xF)         m_szUniqueID+="0";    // add number to string        m_szUniqueID+=Integer.toHexString(b);    }   // hex string to uppercase   m_szUniqueID = m_szUniqueID.toUpperCase();

方法封装:

public static String getIMEI(Context context)    {        TelephonyManager TelephonyMgr = (TelephonyManager)context.getSystemService(TELEPHONY_SERVICE);        String szImei = TelephonyMgr.getDeviceId();        String m_szDevIDShort = "35" + //we make this look like a valid 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 ; //13 digits        String m_szAndroidID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);        WifiManager wm = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);        String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();        BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();; // Local Bluetooth adapter        String m_szBTMAC = m_BluetoothAdapter.getAddress();        String m_szLongID = szImei + m_szDevIDShort + m_szAndroidID+ m_szWLANMAC + m_szBTMAC;        // compute md5        MessageDigest m = null;        try {            m = MessageDigest.getInstance("MD5");        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        }        m.update(m_szLongID.getBytes(),0,m_szLongID.length());        // get md5 bytes        byte p_md5Data[] = m.digest();        // create a hex string        String m_szUniqueID = new String();        for (int i=0;i<p_md5Data.length;i++) {            int b =  (0xFF & p_md5Data[i]);            // if it is a single digit, make sure it have 0 in front (proper padding)            if (b <= 0xF)                m_szUniqueID+="0";            // add number to string            m_szUniqueID+=Integer.toHexString(b);        }   // hex string to uppercase        m_szUniqueID = m_szUniqueID.toUpperCase();        return m_szUniqueID;    }


通过以上算法,可产生32位的16进制数据:
9DDDF85AFF0A87974CE4541BD94D5F55
现在你就可以对其引入你的应用了。

更多相关文章

  1. Android Telephony —— 手机信号实时变化源码分析过程记录
  2. [Android] 备份手机上的超级终端、VIM
  3. Android 之 监控手机电量
  4. android之检测手机电池
  5. android如何调用Web Service手机归属地练习
  6. Android WIFI,蓝牙,电池,背光,SD卡,摄像头,按键,MIC,重力感应等)功能的简
  7. Android 获取手机屏幕大小两种方法
  8. Android 蓝牙自动配对连接

随机推荐

  1. php实现JWT验证的实例教程
  2. PHP快速导出百万级数据到CSV或者EXCEL文
  3. 函数参数与返回值 、模板字面量及模板函
  4. 留言板及自动客服回复功能的实例演示
  5. 详解React的组件通讯
  6. 留言板实践代码
  7. 访问器属性原理及应用场景、获取DOM元素
  8. 详解jquery方法属性
  9. 常用函数类型和数据类型
  10. 常用函数类型与数据类型