Android - 获取移动端设备ID标识,分情况

目前需求:未登录的用户(游客)需要与客服实时通讯,要怎么区分用户消息?
思路:获取游客的设备ID,以此为标识传给服务器来查询/发送信息,一设备为一用户。

那设备ID是什么?怎么获取呢?

设备ID,就是一串符号(或者数字),映射现实中硬件设备。如果这些符号和设备是一一对应的,可称之为“唯一设备ID"。
不幸的是,Android平台没有稳定的API可以让开发者获取到这样的设备ID。

需要保证设备ID的唯一性和稳定性:
唯一性:两台不同的设备获取到相同的设备ID不相同;
稳定性:同一台设备在不同的时间, 获取到设备ID相同。

一、获取设备ID的API

1. IMEI 国际移动设备识别码(规则构造)

具备唯一性,存在主板内存中,恢复出厂设置不会变化(真正的设备相关)
获取IMEI需要 READ_PHONE_STATE 权限,6.0以后要动态申请,用户必须同意权限。10.0禁止第三方应用获取设备的IMEI,为null。
格式: 15~17位十进制,前8位(TAC)是型号核准号码(早期为6位),是区分手机品牌和型号的编码。接着2位(FAC)是最后装配号(仅在早期机型中存在),代表最终装配地代码。后6位(SNR)是串号,代表生产顺序号

// 注册
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

// 判断有无权限 READ_PHONE_STATE,无则申请
if(requestDeviceInfoPermission()){
	TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
	if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
		szImei = TelephonyMgr.getImei(); //8.0及以上
	}else{
		szImei = TelephonyMgr.getDeviceId();//8.0以下
	}
	if(TextUtils.isEmpty(szImei)){//拿不到设备id}
}else{
	ActivityCompat.requestPermissions(this,new String[]{READ_PHONE_STATE},REQUEST_READ_PHONE_STATE);
}

private boolean requestDeviceInfoPermission(){
        int hasPermission = ContextCompat.checkSelfPermission(this,READ_PHONE_STATE);
        if (hasPermission != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
        return true;
    }

双卡双待的手机有两个IMEI号。

2. ANDROID_ID

Android系统第一次启动时产生的一个64bit数,不需要任何权限,唯一性算是很好的了。
刷机、root、恢复出厂设置等会使得 Android ID 改变。
拿不到设备的IMEI的可以拿android_id,但是!部分机型android_id返回null。
格式: 8.0以前由系统生成随机数与应用签名经过算法生成,8.0以后随机。
8.0之后,Android ID的规则发生了变化:
1)如果用户安装在8.0以下,在8.0以上重装回应用此时id不一致。
2)不同签名的APP,获取到的Android ID不一样。

szImei = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
if(TextUtils.isEmpty(szImei)){//android id为空}
3. UUID 通用唯一识别码(随机算法)

由随机算法得到的伪唯一识别码(重复概率为170亿分之一),每次获取都会改变。
格式:一长串"-"分隔开的16进制字符。
可以第一次获取后存本地,只要用户不清理缓存数据也能唯一标识设备。
android_id为空时自己生成识别码

//生成自己的UUID,分隔符分隔只要最后一串。  
String[] uuidSplit = UUID.randomUUID().toString().split("-");
szImei = uuidSplit[uuidSplit.length-1];

// 将16进制转为10进制
szImei = new BigInteger(szImei,16).toString();
// 作为用户id传给服务器...存在应用内...
...

(需求前提,当天的信息处理完就会清空,设备id不够严谨无大碍)

了解一下其他:

IMSI 国际移动用户识别码

用于蜂窝网络中唯一确定一个用户,存在SIM卡,双卡手机只返回一个IMSI,用户换手机、换卡不换号,都不变。
格式: 最大15位十进制。 由移动国家代码、 移动网络代码和移动订户识别代码依次连接而成。


参考文章:
https://www.jianshu.com/u/11d3f06afbcd
https://www.jianshu.com/p/f888390e37d5

你可能感兴趣的:(Android日常笔记,android)