一文搞懂移动设备ID的那些事儿

在移动数字广告领域,设备ID是用来追踪用户行为的最重要的标识。
对于开发者而言,设备ID的稳定性(尤其对于开放的安卓系统来说)以及统计分析和业务应用(变现和追踪等)扮演了非常关键的角色。

作为一个肤浅的产品经理,我们这次主要介绍的设备ID包括:IMEI,MAC,IDFA,Android ID,OAID,UUID,openUDID,GAID,Serial Number等这些无论是国内和海外比较主流的移动设备的唯一标识码或曾扮演重要角色的设备ID。
知道什么是设备ID不是最重要的,重要的是应用的场景,应用目的,以及如何应用,所以这次,我把设备ID分成国外主流和国内主流使用的场景,来分别介绍。

一、什么是设备ID?

设备ID是唯一的匿名标识符,由与单个特定移动设备或用户相对应的数字和字母组成。

全球所有智能手机和平板电脑都有唯一的设备ID,该ID直接存储在移动设备本身上。

设备ID可以通过任何已安装的应用程序检索,并用于准确衡量单个用户采取的操作,即用于统计。

设备ID在用户旅程和体验的所有阶段都发挥着重要作用,包括安装归因,应用内个性化,受众群体细分和整体应用性能。

二、海外的主流设备ID

海外的设备ID比较统一,无论是programmatic advertising市场还是performance advertising市场,无论目的是targeting audience还是tracking user的后续行为和效果,都是这个标准的。
Android – Google广告ID(GAID):Google Advertising ID是由Google Play服务提供的用户可重置的唯一广告ID。

iOS –广告商身份(IDFA):Identifier For Advertising,iOS独有的广告标识符。

要么是传了以上的两种设备ID根据响应的设备类型,要么是不传,也就是为空,再或者,是因为用户选择了don't track而展示的以0填充的设备ID(当然也有可能是假量导致的,各种各样的fraud花样,我们可以有时间再单独聊)。

三、国内设备ID的应用现状

国内的设备ID可以说五花八门,因为媒体传的各式各样,至今也没有一个统一的机构对设备ID进行规范。
总体上,国内的广告主偏向使用硬件地址或者稳定不变且不会被重置的设备ID。我们可以按照设备ID被在线广告市场接受程度(唯一性和稳定性)去对市面上的设备ID排个优先级。
Android:

IMEI:International Mobile Equipment Identity,国际移动设备身份码的缩写。是由15位数字组成的“电子串号”,它与每台手机一一对应,每个IMEI在世界上都是唯一的。

MAC地址:硬件标识符,包括WiFi mac地址和蓝牙mac地址。Android 6.0之后被禁止。被禁止后开发者在APP端收集到的mac是乱码或者02:00:00:00:00类似样式的数据。

当然这个Mac地址可能会被不法分子通过线下收集处在打开WiFi情况下被探针的方式收集,然后匹配数据库里的IMEI甚至手机号等个人信息,所以通过WIFI上网或WIFI AP探针SSID广播都可以获取到MAC地址。

Android ID是每一个新设备系统都会随机的分配一个Andriod_ID,为64位数字。如果将设备恢复出厂设置、刷机,则会生成一个新的ID。通过Settings.Secure.ANDROID_ID获取.

OAID: Open Anonymous Device Identifier, 由中国移动安全联盟(MSA)最近开发,它代替了中国不受支持的Google Advertising ID,并取代了目前为止使用的IMEI / MEID,但还没有被广泛应用,希望可以用OAID取代现有的硬件相关的设备ID,使安卓设备的设备ID可以统一。

与GAID是对应的,所以可以重置OAID甚至完全禁用OAID,这是国内准备迈向隐私保护的第一步。

OAID支持的终端范围:


一文搞懂移动设备ID的那些事儿_第1张图片
微信截图_20200427191413.png

对于不支持的版本,按原有逻辑走。

iOS:

IDFA:Identifier For Advertising,是Apple分配给用户设备的随机设备标识符。因为iOS设备封闭性比较好,无法取得其他硬件标识码,所以这块国内国外都比较统一。

另外,国内有很多做法是将一些获取到的设备ID(IMEI,MAC等)做哈希,以表示我没有获取到用户的隐私,所以衍生出来了IMEI MD5,IMEI SHA-1,MAC MD5,甚至是IDFA MD5,在我看来,就有点内味儿了,你自己感受一下。

其他:

除了上面主流的这些,还有下面这些设备ID,对于我这样付钱的PM来讲,遇到的比较少,不过我也罗列下,以免你碰到不认识。

UDID:原苹果设备的唯一识别ID,它是40个字符组成。在IOS旧版本可以使用,但在IOS7.0以后版本苹果停用了此ID,新版都无法获取。

IDFV :是苹果设备给单个APP自身用于追踪用户的唯一ID,这个IDFV在一个APP内是唯一的,跨APP就不唯一了,因此只能用于单个APP自身用于追踪用户行为。

UUID:Universally Unique Identifier,通用唯一识别码。由于Andriod体系ID的复杂性,所以还有厂商会根据UUID生成标准在APP中生成UUID来使用,听说微软会用这个。

MEID:(Mobile Equipment Identifier) 移动设备识别码是CDMA手机的身份识别码,也是每台CDMA手机或通讯平板唯一的识别码。

Device ID:可以用系统提供的TelephonyManager服务来获取,具有唯一性。其中又包括IMEI 和 MEID/ESN。具有通话功能Android设备才有,平板等设备没有;

Serial Number:设备序列号,通过android.os.Build.SERIAL获得。不稳定的唯一标识,依赖厂商的实现。

注:IMEI是联通、移动手机的标识,MEID是电信手机的标识,但实际上,肤浅的小编并没见过MEID,猜测可能是都传在IMEI哈希过字段里了。

四、如何获取设备ID

上面已经说过,设备ID主要用于统计数据和归因,那么可能我们需要的设备ID需要具有唯一性和稳定性。

讲一下国内外主流的几个设备ID的获取方法:

GAID:

adb shell setprop log.tag v & adb shell stop & adb shell start
2.打开get_gaid.bat文件。内容如下:
adb logcat -s tag GAID
3.打开核心即可获取GAID```

OAID:

OAID的获取其实在MSA的官网上根据官网的指导和邮件对方索取SDK就可以,目前最新的版本是2020年2月6日 miit_mdid_sdk_1.0.13,里面已经非常详细了。

1)下载:

http://www.msa-alliance.cn/col.jsp?id=120

2)安装

把 miit_mdid_x.x.x.aar 拷贝到项的 libs 目录,并设置依赖,其中 x.x.x 代表版本号。

将 supplierconfig.json 拷贝到项目 assets 目录下,并修改里边对应内容,特别是需要设置 appid 的部分。需要设置 appid 的部分需要去对应厂商的应用商店里注册自己的 app。

3)设置依赖。

```implementation files(‘libs/miit_mdid_x.x.x.aar’)```

4)混淆设置。

```-keep class com.bun.miitmdid.core.** {*;}```

5)设置 gradle 编译选项,这块可以根据自己对平台的选择进行合理配置。

```ndk {
        abiFilters 'armeabi-v7a', 'x86', 'arm64-v8a', 'x86_64', 'armeabi'
    }
    packagingOptions {
        doNotStrip "*/armeabi-v7a/*.so"
        doNotStrip "*/x86/*.so"
        doNotStrip "*/arm64-v8a/*.so"
        doNotStrip "*/x86_64/*.so"
        doNotStrip "armeabi.so"
    }```
5)初始化。

```public class APP extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        JLibrary.InitEntry(base);
    }
}```
6)设置回调
```public interface AppIdsUpdater {
        void OnValidId(@NonNull JSONObject ids);
    }```
7)设置调用类
 ```public class MiIdHelper implements IIdentifierListener {
    private boolean isSupport;
    private String oaid, vaid, aaid;

    public JSONObject getDeviceIds(Context cxt) {
        long startTime = System.currentTimeMillis();
        int code = CallFromReflect(cxt);
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("description", descriptionCode(code));
            jsonObject.put("code", code);
            jsonObject.put("time", time);
            jsonObject.put("isSupport", isSupport);
            jsonObject.put("oaid", oaid);
            jsonObject.put("vaid", vaid);
            jsonObject.put("aaid", aaid);
        } catch (Exception e) {
            e.printStackTrace();
        }
         return jsonObject;
    }

    private int CallFromReflect(Context cxt) {
        return MdidSdkHelper.InitSdk(cxt, true, this);
    }


    @Override
    public void OnSupport(boolean isSupport, IdSupplier _supplier) {
        this.isSupport = isSupport;
        if (_supplier != null) {
            this.oaid = _supplier.getOAID();
            this.vaid = _supplier.getVAID();
            this.aaid = _supplier.getAAID();
            _supplier.shutDown();
        }
    }

    private String descriptionCode(int code) {
        switch (code) {
            case ErrorCode.INIT_ERROR_DEVICE_NOSUPPORT:
                return "DEVICE_NOSUPPORT";
            case ErrorCode.INIT_ERROR_LOAD_CONFIGFILE:
                return "LOAD_CONFIGFILE";
            case ErrorCode.INIT_ERROR_MANUFACTURER_NOSUPPORT:
                return "MANUFACTURER_NOSUPPORT";
            case ErrorCode.INIT_ERROR_RESULT_DELAY:
                return "RESULT_DELAY";
            case ErrorCode.INIT_HELPER_CALL_ERROR:
                return "HELPER_CALL_ERROR";
            default:
                return "SUCCESS";
        }
    }
}```

8)获取OAID

```  MiIdHelper miIdHelper = new MiIdHelper();
    JSONObject result=miIdHelper.getDeviceIds(getApplicationContext());```
9)效果展示

```{
    "description":"SUCCESS",
    "code":0,
    "time":49,
    "isSupport":true,
    "oaid":"cf8cc008bb5adf96",
    "vaid":"f8239c19f92836f1",
    "aaid":"0115d997-c845-4e86-8fed-58c4fb246827"

}```
>来源:https://juejin.im/post/5df854745188251280061d3f

idfa:
``` #include 
#include 
#include 
#import 

- (NSString *)zx_idfaString
{
    NSBundle *adSupportBundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/AdSupport.framework"];
    [adSupportBundle load];
    
    if (adSupportBundle == nil)
    {
        return @"";
    }
    else
    {
        Class asIdentifierMClass = NSClassFromString(@"ASIdentifierManager");
        
        if(asIdentifierMClass == nil){
            return @"";
        }
        else
        {
            ASIdentifierManager *asIM = [[asIdentifierMClass alloc] init];
            
            if (asIM == nil) {
                return @"";
            }
            else{
                
                if(asIM.advertisingTrackingEnabled)
                {
                    return [asIM.advertisingIdentifier UUIDString];
                }
            }
        }
    }
}```
>来源:https://juejin.im/post/5bdbb926f265da391e58fa92


##总结:

国内设备ID统一任重而道远;

国外用户隐私倒是越来越严。

无论是前些年实施的欧盟的'GDPR',还是加州的'CCPA','COPPA',以及今年google逐步实施的三方cookie,可以说都对对应地区和用户的用户的隐私更加严格和个性化的保护,反过来对在线广告行业却是一个挑战,行业需要升级,所以总会找到两者兼顾的方面去做改进。

也希望国内的在线广告的设备ID,包括OTT在内,逐渐走向在变现路上兼顾用户隐私的正轨。
![image](https://upload-images.jianshu.io/upload_images/13766341-8ee60d86f2d6b265?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

你可能感兴趣的:(一文搞懂移动设备ID的那些事儿)