很多情况下,需要将APP和设备进行绑定,以保证用户不会无限制的注册或发送请求。然而,Android设备并没有绝对的唯一标识。
Android提供了多种方法来获取所谓的唯一标识。常用的有六种。

(1)Android ID

确实有一个叫做Android ID的东西,但通常被认为不可信,因为它有时会为NULL。而且,在ROOT后,该值可以被修改。

String sAndroidID= Secure.getString(getContentResolver(), Secure.ANDROID_ID);

(2)WLAN MAC

首先,需要说明的是,获取该值需要添加权限。

android.permission.ACCESS_WIFI_STATE

其次,需要指出的是,获取该值无须打开WIFI。
最后,需要强调的是,该值不是真实地址,可以被伪造。

由于android系统对获取方法进行了升级。
android 6.0之前的版本,获取方法如下:

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

若无法获取该值,或值为02:00:00:00:00:00,则说明系统为Android 6.0或以上,需要使用以下方法获取。

public static String getMacAddr() {    try {        List all = Collections.list(NetworkInterface.getNetworkInterfaces());        for (NetworkInterface nif : all) {            if (!nif.getName().equalsIgnoreCase("wlan0")) continue;            byte[] macBytes = nif.getHardwareAddress();            if (macBytes == null) {                return "";            }            StringBuilder res1 = new StringBuilder();            for (byte b : macBytes) {                res1.append(String.format("%02X:",b));            }            if (res1.length() > 0) {                res1.deleteCharAt(res1.length() - 1);            }            return res1.toString();        }    } catch (Exception ex) {    }    return "02:00:00:00:00:00";}

注:该方法也无须打开WIFI。

(3)Blue Tooth MAC

与WLAN MAC类似,获取该值需要添加权限。

android.permission.BLUETOOTH 

同样,获取方法也以Android 6.0作为分界点。
Android 6.0以下,使用如下方法获取

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

Android 6.0及以上,获取方法可参见Stackoverflow,该方法需要到入mirror包。(为取个唯一标识,至于吗?这里不再详述)

同样, 蓝牙没有必要打开,也能读取该值。

注:此前,某些帖子说添加ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION 权限后,可以获取蓝牙或WIFI的MAC,也是瞎扯。仅添加两项权限,不能获取MAC值。若不添加两项权限,也可以获取MAC值。因此,该两项不是必要条件。

(4)IMEI

IMEI,即International Mobile Equipment Identity,是国际移动设备身份码的缩写,国际移动装备辨识码,是由15位数字组成的”电子串号”。
获取该值,需要添加权限

android.permission.READ_PHONE_STATE

获取方法如下:

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

该值与SIM卡有关,但不是所有Android设备都有SIM卡。
且需要考虑双卡双待情况。

(5)Pseudo Device ID

方法2至方法4,都尝试以某种硬件的信息作为Android的唯一标识,但无法保证该值得唯一性和有效性。很自然可以想到,使用多硬件信息组合作为唯一标识。例如取出ROM版本、CPU型号、以及其他硬件信息进行组合。获取这些信息,需要用到Build类。大多数的Build成员都是字符串形式的,但网上流传比较广的使用方法,是使用各成员的长度,进行字符串组合。

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 ; 

当然,我们也可以只使用其中某几个成员,获取其字符串值进行组合,再辅助于某种运算(SHA, MD5,HASH等)来生成自定义的唯一标识。

(6)APP UUID

还有一种方法,使用了Android UUID类,实现了APP与设备的绑定。
在通过APP第一次获取设备唯一标识时,创建文件,并使用UUID类向文件中写入一个随机字符串,作为唯一标识。下次获取时,若文件存在,则直接读取随机字符串。当卸载APP时,删除该文件。因此,一次安装APP,对应一个唯一标识。

public synchronized static String getUUID(Context context, String fileName) {        if (sID == null) {            File UUIDFile= new File(context.getFilesDir(), fileName);            try {                if (!UUIDFile.exists())                    writeInstallationFile(UUIDFile);                sID = readInstallationFile(UUIDFile);            } catch (Exception e){                throw new RuntimeException(e);            }        }        return sID;    }
    private static String readInstallationFile(File file) throws IOException {        RandomAccessFile f = new RandomAccessFile(file, "r");        byte[] bytes = new byte[(int) f.length()];        f.readFully(bytes);        f.close();        return new String(bytes);    }
    private static void writeInstallationFile(File file) throws IOException {        FileOutputStream out = new FileOutputStream(file);        String id = UUID.randomUUID().toString();        out.write(id.getBytes());        out.close();    }

APP UUID值例如:

7a2c6658-1d61-42f5-99b1-c7d309c60d50

综上,设备的唯一标识,不是绝对的。我们可以选择一种或多种进行组合,最大可能的实现其唯一性。

更多相关文章

  1. android设备连接到pc进行应用程序调试
  2. Android—TextView的XML属性和方法
  3. Android来电铃声默认设置的实现方法与怎么设置语音来电的默认铃
  4. NDK开发历程(一):android native code的调试方法
  5. Android ListView拖动时背景变黑的解决方法
  6. android ------ AAPT2 error: check logs for details解决方法
  7. android下的定时器在关闭屏幕后会自己停掉解决方法
  8. Android自定义属性时TypedArray的使用方法

随机推荐

  1. Android移动开发-添加手势以及识别用户手
  2. Android(安卓)物联网socket通信采坑
  3. android 系统核心机制binder(02)binder驱动
  4. Android(安卓)报错 - 无法解析类型 java.
  5. Android(安卓)4 通过 USB 连接扫描枪 获
  6. 对学Android的几点建议(磨砺营马剑威Andro
  7. Android常用名令集锦(图文并茂)(转:来自网
  8. 深入Android(安卓)【五】 ―― 任务和进
  9. Android(安卓)系统的裁剪
  10. Android文件命名规范初版