Android设备获取唯一标识符

概述

有时需要对用户设备进行标识,所以希望能够得到一个稳定可靠并且唯一的识别码。虽然Android系统中提供了这样设备识别码,但是由于Android系统版本、厂商定制系统中的Bug等限制,稳定性和唯一性并不理想。
唯一标识码这东西在网络应用中非常有用,例如检测是否重复注册之类的。下面就来介绍几种标识码:
1.DEVICE_ID;
2.MAC ADDRESS;
3.Sim Serial Number;
4.Serial Number;
5.ANDROID_ID;
6.Installtion ID : UUID;
7.DEVICE_ID:UUID;

DEVICE_ID

概念: 是区别移动设备的标志,储存在移动设备中,可用于监控被窃或无效的移动设备。
关键代码:

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
       String IMEI = tm.getDeviceId(); 

优点:
1.根据不同的手机设备返回IMEI,MEID或者ESN码,唯一性良好 。

不足:
1.非手机:如平板电脑,像这样设备没有通话的硬件功能,系统中也就没有TELEPHONY_SERVICE,自然也就无法获得DEVICE_ID;
2.权限问题:获取DEVICE_ID需要READ_PHONE_STATE权限;
3.厂商定制系统中的Bug:少数手机设备上,由于该实现有漏洞,会返回垃圾,如:00000000或者****

MAC ADDRESS

概念:可以使用手机Wifi或蓝牙的MAC地址作为设备标识。
Wifi Mac关键代码:

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

蓝牙 Mac关键代码:

String bt_mac = BluetoothAdapter.getDefaultAdapter().getAddress();

不足:
1.如果设备没有支持WIFI的硬件,就返回null;
2.如果设备没有支持蓝牙的硬件,就返回null。

Sim Serial Number

概念:SIM卡的序列号。
关键代码:

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        String SimSerialNumber = tm.getSimSerialNumber();

不足:
1.没有装Sim卡时,返回null;
2.对于CDMA设备,返回null。

Serial Number

概念:Android系统2.3版本以上可以获取硬件Serial Number。
关键代码:

String sn = android.os.Build.SERIAL;

优点:非手机设备也可以通过该接口获取ID。

ANDROID_ID

概念:当设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来。
关键代码:

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

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

Installation ID : UUID

概念:该标识符无需访问设备的资源,也跟设备类型无关。这种标识符是通过在程序安装后第一次运行后生成一个ID实现的,但该标识跟设备唯一标识不一样,它会因为不同的应用程序而产生不同的ID,而不是设备唯一ID。
关键代码:


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();
    }

}

不足:
1.当卸载应用后重新安装,返回值与之前的值不同。

DEVICE_ID:UUID

概念:为了实现在设备上更通用的获取设备唯一标识,我们可以实现这样的一个类,为每个设备产生唯一的UUID,以ANDROID_ID为基础,在获取失败时以TelephonyManager.getDeviceId()为备选方法,如果再失败,使用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);
                        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();
                    }
                }
           }
        }
    }

    public UUID getDeviceUuid() {
        return uuid;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值