Android设备获取OAID调研和实现

什么是OAID、AAID、VAID

OAID

OAID是"Android ID"(安卓ID)的一种替代方案,其全称为"Open Anonymous Identifier"(开放匿名标识符)。
因传统的移动终端设备标识如国际移动设备识别码(IMEI)等已被部分国家认定为用户隐私的一部分,并存在被篡改和冒用的风险,所以在Android 10及后续版本中非厂商系统应用将无法获取IMEI、MAC等设备信息。无法获取IMEI会在用户行为统计过程中对设备识别产生一定影响。
移动安全联盟针对该问题联合国内手机厂商推出补充设备标准体系方案,选择OAID字段作为IMEI等的替代字段。OAID字段是由中国信通院联合华为、小米、OPPO、VIVO等厂商共同推出的设备识别字段,具有一定的权威性,可满足用户行为统计的使用场景。

区别

设备唯一标识符(UDID):设备唯一硬件标识,设备生产时根据特定的硬件 信息生成,可用于设备的生产环境及合法性校验。不对第三方应用提供获取接 口,无法通过 SDK 获取。
匿名设备标识符(OAID):可以连接所有应用数据的标识符,移动智能终端 系统首次启动后立即生成,可用于广告业务。可以通过 SDK 获取到接口状态(重 置、关闭)、ID 值。
开发者匿名设备标识符(VAID):用于开放给开发者的设备标识符,可在应用安装时产生,可用于同一开发者不同应用之间的推荐。可以通过 SDK 获取到 ID 值。
应用匿名设备标识符(AAID):第三方应用获取的匿名设备标识,可在应用安装时产生,可用于用户统计等。可以通过 SDK 获取到 ID值。

如何获取

官方SDK接入

SDK获取

移动安全联盟官网:http://www.msa-alliance.cn/
注意:但是注册需要企业账号,个人开发者无法注册使用,所以测试的时候在网上找了其他人提供的已经下载好的官方SDK。
百度云盘地址:https://pan.baidu.com/s/1sVzBD_3mTXD_oqyu5I2VtQ 提取码:we54
官方文档:
见附件。

配置和调用

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

  2. 将 supplierconfig.json 拷贝到项目 assets 目录下
    appid 需要移动互联网应用开发者根据应用使用需求到不同终端厂商的应用 商城申请,具体需咨询相关厂商,不需要填写其他第三方应用商店的 appid。 appid 只与 VAID 的获取有关,用于判断是否为同一开发者,如不需获取 vaid 可 不填写。目前只需设置 vivo 的 appid。(我们本次只需要获取OAID,所以不需要上架,也不需要appid)
    配置文件中部分设备如果不配置厂商会无法获取,部分设备如小米即使配置文件中没有,也不影响获取,所以我们对接的时候,为了保险起见,配置文件中尽可能全一些。【 官方文档中说配置文件不用修改,只需填写对应 appid,并放到 assets 目录下即可 】

  3. 设置依赖

  4. 设置gradle编译选项,开发者可以根据自己对平台的选择进行合理配置(测试的时候不配置也没什么问题)
    ndk { abiFilters ‘armeabi-v7a’,‘x86’,‘arm64-v8a’,‘x86_64’,‘armeabi’ }

代码实现

public class MainActivity extends AppCompatActivity implements IIdentifierListener{
    private TextView tvContent;
    String oaid;
    String vaid;
    String aaid;
    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvContent = findViewById(R.id.tv);
        MdidSdkHelper.InitSdk(getApplicationContext(), true, this);
        //结果是异步返回的,使用时为空的话可以先休眠几秒
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("OAID: "+oaid);
        System.out.println("VAID: "+vaid);
        System.out.println("AAID: "+aaid);
    }

    @Override
    public void OnSupport(boolean b, IdSupplier idSupplier) {
        if(idSupplier==null) {
            return;
        }
        oaid=idSupplier.getOAID();
        vaid=idSupplier.getVAID();
        aaid=idSupplier.getAAID();

        StringBuilder builder=new StringBuilder();
        builder.append("support: ").append(idSupplier.isSupported()?"true":"false").append("\n");
        builder.append("OAID: ").append(oaid).append("\n");
        builder.append("VAID: ").append(vaid).append("\n");
        builder.append("AAID: ").append(aaid).append("\n");

        String idstext=builder.toString();
        Log.d("SdkDemo: ", idstext);
        onIdsAvalid(idstext);
    }
    public void onIdsAvalid(@NonNull final String ids) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                tvContent.setText(ids);
            }
        });
    }
}

效果

官方sdk获取结果

三方实现接入

接入指引

github地址:https://github.com/gzu-liyujiang/Android_CN_OAID
文档已经写的特别详细了,但是还是有一些地方需要注意一下:

dependencies {
implementation('com.github.gzu-liyujiang:Android_CN_OAID:最新版本号') {
// 如果使用了移动安全联盟SDK,共存的话需排除掉本项目依赖的华为/荣耀官方广告标识服务SDK,因为移动安全联盟SDK也依赖了华为/荣耀的SDK
// 如果华为官方广告标识服务SDK下载失败或编译报错的话,可考虑在 build.gradle 中增加以下配置:
// repositories { maven { url 'https://developer.huawei.com/repo' } }
// runtimeOnly "com.huawei.hms:ads-identifier:3.4.62.300"
exclude group: 'com.huawei.hms', module: 'ads-identifier' 
// 荣耀官方广告标识服务SDK同理:      
// repositories { maven { url 'https://developer.hihonor.com/repo' } }
// runtimeOnly "com.hihonor.mcs:ads-identifier:1.0.2.301"
exclude group: 'com.hihonor.mcs', module: 'ads-identifier'
}
}

在这里,如果在kotlin的dsl中应该这么写exclude group:

implementation ("com.github.gzu-liyujiang:Android_CN_OAID:4.2.9"){
exclude(group = "com.huawei.hms', module: 'ads-identifier")
exclude(group = "'com.hihonor.mcs', module: 'ads-identifier")
}

代码实现

publicclassMainActivityextendsAppCompatActivity{
privateTextViewtextViewOAID;
@SuppressLint("MissingInflatedId")
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewOAID=findViewById(R.id.textViewOAID);
//DeviceIdentifier.register(this.getApplication());
//获取IMEI,只支持Android10之前的系统,需要READ_PHONE_STATE权限,可能为空
DeviceIdentifier.getIMEI(this);
//获取安卓ID,可能为空
DeviceIdentifier.getAndroidID(this);
//获取数字版权管理ID,可能为空。很鸡肋,在某些手机上还可能造成卡死或闪退,自4.2.7版本后已弃用
DeviceIdentifier.getWidevineID();
//获取伪造ID,根据硬件信息生成,不会为空,有大概率会重复
DeviceIdentifier.getPseudoID();
//获取GUID,随机生成,不会为空
DeviceIdentifier.getGUID(this);
//是否支持OAID/AAID
DeviceID.supportedOAID(this);
//获取OAID/AAID,同步调用
DeviceIdentifier.getOAID(this);
//获取OAID/AAID,异步回调
DeviceID.getOAID(this,newIGetter(){
@Override
publicvoidonOAIDGetComplete(Stringresult){
//不同厂商的OAID/AAID格式是不一样的,可进行MD5、SHA1之类的哈希运算统一
Log.d("oaiddemo","获取成功:"+result);
textViewOAID.setText("OAIDValue:"+result);//更新TextView文本
}

@Override
publicvoidonOAIDGetError(Exceptionerror){
//获取OAID/AAID失败
Log.d("oaiddemo","获取失败:");
textViewOAID.setText("OAID获取失败");//更新TextView文本,表示获取失败
}
});
}
}

效果

三方获取结果
对比官方和三方的结果,获取到的OAID,同一台设备是一致的。

写在最后

感谢参考的几篇文档:
https://blog.csdn.net/Myfittinglife/article/details/121520111
https://blog.csdn.net/mingtiannihao0522/article/details/104630967
https://juejin.cn/post/6924191966146068493

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/662739.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

免费,Python蓝桥杯等级考试真题--第17级(含答案解析和代码)

Python蓝桥杯等级考试真题–第17级 一、 选择题 答案:B 解析:(x-y)%25%21,故答案为B。 答案:B 解析:x16,所以i的值为range(1,16),取值为1-15&…

Dinky MySQLCDC 整库同步到 MySQL jar包冲突问题解决

资源:flink 1.17.0、dinky 1.0.2 问题:对于kafka相关的包内类找不到的情况 解决:使用 flink-sql-connector- 胖包即可,去掉 flink-connector- 相关瘦包,解决胖瘦包冲突 source使用 flink-sql-connector- 胖包&#…

【数据库】通过一个实例来认识数据流图DFD

导读:通过一个实例(数据中台)说明数据流图DFD的作用、介绍了常见的数据流图元素及其标准符号以及如何画数据流图。数据流图主要被分析师、系统设计师、流程优化专家、系统管理员以及与系统开发和维护相关的人员查看和使用。对于刚考完2024年5…

Altium Designer软件下载安装「专业PCB设计软件」Altium Designer安装包获取!

Altium Designer,这款软件凭借其全面的设计流程覆盖,从概念到实现,都能为电子工程师提供强大的支持。 在硬件设计方面,Altium Designer提供了丰富的元件库和灵活的布局选项,使得工程师能够轻松地进行电路设计&#xff…

反射机制大揭秘-进阶Java技巧,直击核心!

反射在Java中扮演着重要的角色,掌握了反射,就等于掌握了框架设计的钥匙。本文将为您逐步讲解反射的基本概念、获取Class对象的三种方式、使用反射实例化对象并操作属性和方法,还有解析包的相关内容。跟随我一起探索反射的奥秘,提升…

学习Java的日子 Day48 函数,DOM

Day48 1.流程控制语句 if else for for-in(遍历数组时,跟Java是否一样) While do while break 语句用于跳出循环 continue 用于跳过循环中的一个迭代 2.函数 2.1 JavaScript 函数语法 函数就是包裹在花括号中的代码块,前面使用了关键词 function funct…

数据分析必备:一步步教你如何用Pandas做数据分析(11)

1、Pandas 自定义选项 Pandas 自定义选项操作实例 Pandas因为提供了API来自定义行为,所以被广泛使用。 自定义API中有五个相关功如下: get_option() set_option() reset_option() describe_option() option_context() 下面我们一起了解下这些方法。 1.…

【移动云】主机ECS搭建项目——具体步骤教程

目录 一、什么是移动云 二、移动云有什么优势 三、移动云使用 1.注册账号 2.云主机ECS创建 3.管理云主机 4.连接配置云主机 5.搭建服务器提示与建议 四、使用感受 一、什么是移动云 移动云是中国领先的云服务品牌之一,它以强大的资源优势、技术实力和品牌价…

母婴商城购物网站,基于 SpringBoot+Vue+MySQL 开发的前后端分离的母婴商城购物网站设计实现

目录 一. 前言 二. 功能模块 2.1. 前台功能 2.2. 用户信息管理 2.3. 商品分类管理 2.4. 商品信息管理 2.5. 商品资讯管理 三. 部分代码实现 四. 源码下载 一. 前言 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储&a…

Compose第一弹 可组合函数+Text

目标: 1.Compose是什么?有什么特征? 2.Compose的文本控件 一、Compose是什么? Jetpack Compose 是用于构建原生 Android 界面的新工具包。 Compose特征: 1)声明式UI:使用声明性的函数构建一…

File name ‘xxxx‘ differs from already included file name ‘xxxx‘ only in casing.

一、报错信息 VSCode报错如下: File name ‘d:/object/oral-data-management/src/components/VisitLogPopup/Info.vue’ differs from already included file name ‘d:/object/oral-data-management/src/components/VisitLogPopup/INfo.vue’ only in casing. The…

树莓派4B 学习笔记1:TF卡系统盘烧录_初次启动_远程端连接配置

今日开始学习树莓派4B 4G:(Raspberry Pi,简称RPi或RasPi) TF卡系统盘烧录_初次启动_远程端连接配置 目录 格式化SD卡: 烧录系统Win32DiskImager: Raspberry Pi Imager镜像烧写: 树莓派官网资料…

fyne widget小部件1

fyne widget小部件1 label标签 Label 小部件是其中最简单的——它向用户呈现文本。不像canvas.Text它可以处理一些简单的格式(例如\n)。 package mainimport ("fyne.io/fyne/v2/app""fyne.io/fyne/v2/widget" )func main() {myApp : app.New…

【因果推断python】1_因果关系初步1

目录 为什么需要关心因果关系? 回答不同类型的问题 当关联确实是因果时 为什么需要关心因果关系? 首先,您可能想知道:它对我有什么好处?下面的文字就将围绕“它”展开: 回答不同类型的问题 机器学习目…

MOS管开关电路简单笔记

没错&#xff0c;这一篇还是备忘录&#xff0c;复杂的东西一律不讨论。主要讨论增强型的PMOS与NMOS。 PMOS 首先上场的是PMOS,它的导通条件&#xff1a;Vg-Vs<0且|Vg-Vs>Vgsth|&#xff0c;PMOS的电流流向是S->D,D端接负载&#xff0c;S端接受控电源。MOS管一般无法…

opencascade 笔记

opencascade 画一个无限大的面 在 OpenCascade 中&#xff0c;要绘制一个无限大的面&#xff0c;你可以使用 gp_Pln 类来定义一个平面&#xff0c;然后将其绘制出来。这里是一个示例代码&#xff0c;演示如何在 OpenCascade 中绘制一个无限大的平面&#xff1a; #include <…

STM32-12-OLED模块

STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 文章目录 1. OLED显示屏介绍2. OLED驱动原理3. OLED驱动芯片简介4…

pytorch笔记:torch.nn.Flatten()

1 介绍 torch.nn.Flatten(start_dim1, end_dim-1) 将一个连续的维度范围扁平化为一个张量 start_dim (int)要开始扁平化的第一个维度&#xff08;默认值 1&#xff09;end_dim (int)要结束扁平化的最后一个维度&#xff08;默认值 -1&#xff09; 2 举例 input torch.ra…

过去的六年,教会了我很多事

目录 过去六年的风风雨雨android缘起爱情缘灭顿悟收拾心情&#xff0c;再次启航面试阿里大起大落 如今时光&#xff0c;刺激且美好未来展望 过去六年的风风雨雨 android缘起 2018年&#xff0c;我从北京联合大学毕业&#xff0c;跟随着学长一起创业&#xff0c;从此开始了我的…

DeFi的历程与未来:探寻去中心化金融的前行路

随着区块链技术的不断演进和加密货币市场的持续繁荣&#xff0c;DeFi&#xff08;去中心化金融&#xff09;作为一种新兴领域正迅速崛起&#xff0c;其发展历史和未来前景备受关注。 过去&#xff1a;DeFi 的发展历史 DeFi 并非一夜之间出现&#xff0c;而是经历了一系列的发展…