记得很久之前在一场笔试上有一道题目就是:“如何唯一的标识一台Android设备?”。当时只知道IMEI可以是用来标识一台手机的,所以就随便填了上去,然后...就没有然后了...今天刚好在工作中重新遇到,就拿出来说说看。

首先说结论我们到底能不能唯一的标识一台Android设备?很遗憾,暂时没有一个很完美的方法能够解决这个问题。Android开发者博客的原文是:

Suppose you feel that for the needs of your application, you need an actual hardware device identifier. This turns out to be a tricky problem.

既然这样,我们就来谈谈那些不太完美的方法。在这之前我们需要先知道几个概念:

UUID : (Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得)。

IMEI : (International Mobile Equipment Identity) 是国际移动设备身份码的缩写,国际移动装备辨识码,是由15位数字组成的"电子串号",它与每台手机一一对应,而且该码是全世界唯一的。

MEID :( Mobile Equipment IDentifier )是全球唯一的56bit CDMA制式移动终端标识号。标识号会被烧入终端里,并且不能被修改。可用来对CDMA制式移动式设备进行身份识别和跟踪。

两者的区别在于:IMEI是手机的身份证,MEID是CDMA制式(电信运营的)的专用身份证;IMEI是15位,MEID是14位。

DEVICE_ID

根据不同的手机设备返回IMEI,MEID或者ESN码,可以根据以下代码获得:

Device_Id

非手机设备:最开始搭载Android系统都手机设备,而现在也出现了非手机设备:如平板电脑、电视、音乐播放器等。这些设备没有通话的硬件功能,系统中也就没有TELEPHONY_SERVICE,自然也就无法通过上面的方法获得DEVICE_ID。

权限问题:获取DEVICE_ID需要READ_PHONE_STATE权限,在Android 6.0上使用运行时动态授予权限的机制,一旦用户不给予授权,将获取不到DEVICE_ID。 

厂商定制系统中的Bug:少数手机设备上,由于该实现有漏洞,会返回垃圾(这是开发者博客的原话,没有实践过)。

MAC ADDRESS

MAC_Address

可以使用手机WiFi或蓝牙的MAC地址作为设备标识,但是并不推荐这么做,原因有以下两点:

硬件限制:并不是所有的设备都有WiFi和蓝牙硬件,硬件不存在自然也就得不到这一信息。

获取的限制:如果WiFi没有打开过,是无法获取其Mac地址的;而蓝牙是只有在打开的时候才能获取到其Mac地址。

Serial Number

硬件序列,在Android 2.2 以上可以通过 android.os.Build.SERIAL 获得序列号。在一些没有电话功能的设备会提供,某些手机上也可能提供(所以就是经常会返回Unknown)

ANDROID_ID

ANDROID_ID是设备第一次启动时产生和存储的64bit的一个数,当设备被wipe后该数重置。

Android_Id

ANDROID_ID似乎是获取Device ID的一个好选择,但它也有缺陷:在主流厂商生产的设备上,有一个很经常的bug,就是每个设备都会产生相同的ANDROID_ID:9774d56d682e549c 。同时刷机,或者重置ANDROID_ID的值都会变化。

接下来就来看看实际的标识方法:

第一种:Installtion ID

在程序安装后第一次运行时生成一个ID,该方式和设备唯一标识不一样,不同的应用程序会产生不同的ID,同一个程序重新安装也会不同。所以这不是设备的唯一ID,但是可以保证每个用户的ID是不同的。 可以说是用来标识每一份应用程序的唯一ID(即Installtion ID),可以用来跟踪应用的安装数量等(其实就是UUID)。

Installtion Id 获取方法

第二种:UniquePsuedoID

通过读取设备的ROM版本号、厂商名、CPU型号和其他硬件信息来组合出一串15位的号码和设备硬件序列号作为种子生成UUID。一串15位的号码(批量生产的设备每项信息基本相同,所以这一段相同的可能性特别高);硬件序列,在一些没有电话功能的设备会提供,某些手机上也可能提供(Devices without telephony are required to report a unique device ID here; some phones may do so also.),所以就是经常会返回Unknown。

UniquePsuedoID  获取方法

第三种:Universal ID

首先通过读取Android_id,作为UUID的种子。若得到Android_Id等于9774d56d682e549c或者 发生错误则random一个UUID作为备用方案,最后把得到的UUID同时存入内部存储和外部存储。下次使用UUID的时候优先从外部存储读取,再从背部存储读取,最后在重新生成,尽可能的保证其不变性。

Universal_id获取方法

参考文档:http://android-developers.blogspot.jp/2011/03/identifying-app-installations.html

文中代码下载链接:http://download.csdn.net/detail/a496263987/9494949

更多相关文章

  1. android 机器人
  2. Android音频系统之USB设备通路(Android(安卓)5.1)
  3. Android(安卓)adb 我的常用调试命令记录(持续更新中...)
  4. MIT开发应用为Android手机增添超级计算能力
  5. Android(安卓)页面回调跳转(startActivityForResult)
  6. Android(安卓)adb shell 命
  7. Android(安卓)手机卡了怎么办
  8. [002] Android系统简介
  9. android设备常用的adb命令

随机推荐

  1. Android资源文件mk的格式
  2. Android(安卓)使用IPC和后台Service通信
  3. android C++ 和 jni,根据JNIEnv的FindClas
  4. Android(安卓)控件界面转成Bitmap
  5. android断点续传实现方案之三
  6. android:程序中安装APK方法
  7. AndFire防火墙1.2版本发布
  8. Android中各种onTouch事件
  9. android之simpleAdaper应用
  10. Android跳转到系统Wifi界面的方式