本文转载自:http://blog.csdn.net/billpig/article/details/6728573

我们在项目过程中或多或少会使用到设备的唯一识别码,我们希望能够得到一个稳定、可靠的设备唯一识别码。今天我们将介绍几种方式。

1. DEVICE_ID

假设我们确实需要用到真实设备的标识,可能就需要用到DEVICE_ID。在以前,我们的Android设备是手机,这个DEVICE_ID可以同通过 TelephonyManager.getDeviceId()获取,它根据不同的手机设备返回IMEI,MEID或者ESN码,但它在使用的过程中会遇到很多问题:
  • 非手机设备: 如果只带有Wifi的设备或者音乐播放器没有通话的硬件功能的话就没有这个DEVICE_ID
  • 权限: 获取DEVICE_ID需要READ_PHONE_STATE权限,但如果我们只为了获取它,没有用到其他的通话功能,那这个权限有点大才小用
  • bug:在少数的一些手机设备上,该实现有漏洞,会返回垃圾,如:zeros或者asterisks的产品

2. MAC ADDRESS

我们也可以通过手机的Wifi或者蓝牙设备获取MAC ADDRESS作为DEVICE ID,但是并不建议这么做,因为并不是所有的设备都有Wifi,并且,如果Wifi没有打开,那硬件设备无法返回MAC ADDRESS.

3. Serial Number

在Android 2.3可以通过android.os.Build.SERIAL获取,非手机设备可以通过该接口获取。

4. ANDROID_ID

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

ANDROID_ID似乎是获取Device ID的一个好选择,但它也有缺陷:

  • 它在Android <=2.1 or Android >=2.3的版本是可靠、稳定的,但在2.2的版本并不是100%可靠的
  • 在主流厂商生产的设备上,有一个很经常的bug,就是每个设备都会产生相同的ANDROID_ID:9774d56d682e549c

5. Installtion ID : UUID

以上四种方式都有或多或少存在的一定的局限性或者bug,在这里,有另外一种方式解决,就是使用UUID,该方法无需访问设备的资源,也跟设备类型无关。

这种方式是通过在程序安装后第一次运行后生成一个ID实现的,但该方式跟设备唯一标识不一样,它会因为不同的应用程序而产生不同的ID,而不是设备唯一ID。因此经常用来标识在某个应用中的唯一ID(即Installtion ID),或者跟踪应用的安装数量。很幸运的,Google Developer Blog提供了这样的一个框架:

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


总结

综合以上所述,为了实现在设备上更通用的获取设备唯一标识,我们可以实现这样的一个类,为每个设备产生唯一的UUID,以ANDROID_ID为基础,在获取失败时以TelephonyManager.getDeviceId()为备选方法,如果再失败,使用UUID的生成策略。

重申下,以下方法是生成Device ID,在大多数情况下Installtion ID能够满足我们的需求,但是如果确实需要用到Device ID,那可以通过以下方式实现:

import android.content.Context;import android.content.SharedPreferences;import android.provider.Settings.Secure;import android.telephony.TelephonyManager;import java.io.UnsupportedEncodingException;import java.util.UUID;public class DeviceUuidFactory {    protected static final String PREFS_FILE = "device_id.xml";    protected static final String PREFS_DEVICE_ID = "device_id";    protected static UUID uuid;    public DeviceUuidFactory(Context context) {        if( uuid ==null ) {            synchronized (DeviceUuidFactory.class) {                if( uuid == null) {                    final SharedPreferences prefs = context.getSharedPreferences( PREFS_FILE, 0);                    final String id = prefs.getString(PREFS_DEVICE_ID, null );                    if (id != null) {                        // Use the ids previously computed and stored in the prefs file                        uuid = UUID.fromString(id);                    } else {                        final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);                        // Use the Android ID unless it's broken, in which case fallback on deviceId,                        // unless it's not available, then fallback on a random number which we store                        // to a prefs file                        try {                            if (!"9774d56d682e549c".equals(androidId)) {                                uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));                            } else {                                final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();                                uuid = deviceId!=null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID();                            }                        } catch (UnsupportedEncodingException e) {                            throw new RuntimeException(e);                        }                        // Write the value out to the prefs file                        prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();                    }                }            }        }    }    /**     * Returns a unique UUID for the current android device.  As with all UUIDs, this unique ID is "very highly likely"     * to be unique across all Android devices.  Much more so than ANDROID_ID is.     *     * The UUID is generated by using ANDROID_ID as the base key if appropriate, falling back on     * TelephonyManager.getDeviceID() if ANDROID_ID is known to be incorrect, and finally falling back     * on a random UUID that's persisted to SharedPreferences if getDeviceID() does not return a     * usable value.     *     * In some rare circumstances, this ID may change.  In particular, if the device is factory reset a new device ID     * may be generated.  In addition, if a user upgrades their phone from certain buggy implementations of Android 2.2     * to a newer, non-buggy version of Android, the device ID may change.  Or, if a user uninstalls your app on     * a device that has neither a proper Android ID nor a Device ID, this ID may change on reinstallation.     *     * Note that if the code falls back on using TelephonyManager.getDeviceId(), the resulting ID will NOT     * change after a factory reset.  Something to be aware of.     *     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID directly.     *     * @see http://code.google.com/p/android/issues/detail?id=10603     *     * @return a UUID that may be used to uniquely identify your device for most purposes.     */    public UUID getDeviceUuid() {        return uuid;    }}

Reference:

http://android-developers.blogspot.com/2011/03/identifying-app-installations.html

http://stackoverflow.com/questions/5088474/how-can-i-get-the-uuid-of-my-android-phone-in-an-application


版权所有,转载请出明出处!

更多相关文章

  1. Android(安卓)Camera数据流分析全程记录(非overlay方式)
  2. Android创建桌面快捷方式
  3. Android(安卓)ADB 命令
  4. Google Play Store 应用无法安装解决方案
  5. Ubuntu安装Android的SDK
  6. Android开发笔记(一)
  7. Android(安卓)开发简介
  8. Android——蓝牙通信
  9. Android中获取手机支持的硬件解码器类型以及对应的解码器名称

随机推荐

  1. android的TabActivity
  2. android moudle 资源文件重命名
  3. Android(安卓)实现图片圆角
  4. Android 开源项目源码分析第一期正式发布
  5. 【Android(安卓)开发教程】链接Activitie
  6. Flex学习小心得
  7. Android中的onActivityResult和setResult
  8. 如何安装新版Android Studio 3.0
  9. Android(安卓)TextSwitcher(文字交换器)
  10. Android(安卓)ffmpeg支持x264的编译脚本