Android 获取OAID

news2024/11/8 11:00:50

获取OAID

老规矩,直接上:


    implementation 'com.huawei.hms:opendevice:6.11.0.300' // 要获取华为vaid 和aaid,还需添加opendevice 依赖
    implementation(name: 'oaid_sdk_2.5.0', ext: 'aar')


import android.content.Context;
import android.util.Log;

import com.bun.miitmdid.core.InfoCode;
import com.bun.miitmdid.core.MdidSdkHelper;
import com.bun.miitmdid.interfaces.IIdentifierListener;
import com.bun.miitmdid.interfaces.IdSupplier;
import com.bun.miitmdid.pojo.IdSupplierImpl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * MiitHelper.Init(this, new MiitHelper.AppIdsUpdater(){
 *             @Override
 *             public void onIdsValid(String oaid){
 *                 AppActivity.oaid = oaid;
 *             }
 *         });
 */
public class MyMiitHelper implements IIdentifierListener {
    public static final String TAG = "MiitHelper";
    public static final int HELPER_VERSION_CODE = 20210928; // DemoHelper版本号
    private AppIdsUpdater appIdsUpdater;
    private boolean isCertInit = false;
    private static MyMiitHelper instance;

    public final boolean isSDKLogOn = true;                           // 1)设置 是否开启sdk日志
    public static String ASSET_FILE_NAME_CERT = "";             // 2)设置 asset证书文件名


    public static MyMiitHelper getInstance(Context context) {
        if(instance == null) {
            synchronized(MyMiitHelper.class) {
                if(instance == null) {
                    instance = new MyMiitHelper(context);
                }
            }
        }
        return instance;
    }

    public MyMiitHelper(Context context){
        ASSET_FILE_NAME_CERT = context.getPackageName()+".cert.pem";
        Log.e(TAG,ASSET_FILE_NAME_CERT);

//        System.loadLibrary("nllvm1632808251147706677");  // 加固版本在调用前必须载入SDK安全库
        // TODO (3)加固版本在调用前必须载入SDK安全库,因为加载有延迟,推荐在application中调用loadLibrary方法
         System.loadLibrary("msaoaidsec");
        if(MdidSdkHelper.SDK_VERSION_CODE != HELPER_VERSION_CODE){
            Log.w(TAG,"SDK version not match.");
            throw new RuntimeException("SDK version not match.");
        }

        // 获取设备号
        getDeviceIds(context);
    }

    public AppIdsUpdater getAppIdsUpdater() {
        return appIdsUpdater;
    }

    public void setAppIdsUpdater(AppIdsUpdater appIdsUpdater) {
        this.appIdsUpdater = appIdsUpdater;
    }

    /**
     * 获取OAID
     * @param cxt
     */
    public void getDeviceIds(Context cxt){
        // TODO (4)初始化SDK证书
        if(!isCertInit){ // 证书只需初始化一次
            // 证书为PEM文件中的所有文本内容(包括首尾行、换行符)
            isCertInit = MdidSdkHelper.InitCert(cxt, loadPemFromAssetFile(cxt, ASSET_FILE_NAME_CERT));
            if(!isCertInit){
                Log.w(TAG, "getDeviceIds: cert init failed");
            }
        }

        //(可选)设置InitSDK接口回调超时时间(仅适用于接口为异步),默认值为5000ms.
        // 注:请在调用前设置一次后就不再更改,否则可能导致回调丢失、重复等问题
        MdidSdkHelper.setGlobalTimeout(5000);

        // TODO (5)调用SDK获取ID
        int code = MdidSdkHelper.InitSdk(cxt, isSDKLogOn, this);

        // TODO (6)根据SDK返回的code进行不同处理
        IdSupplierImpl unsupportedIdSupplier = new IdSupplierImpl();
        if(code == InfoCode.INIT_ERROR_CERT_ERROR){                         // 证书未初始化或证书无效,SDK内部不会回调onSupport
            // APP自定义逻辑
            Log.w(TAG,"cert not init or check not pass");
            onSupport(unsupportedIdSupplier);
        }else if(code == InfoCode.INIT_ERROR_DEVICE_NOSUPPORT){             // 不支持的设备, SDK内部不会回调onSupport
            // APP自定义逻辑
            Log.w(TAG,"device not supported");
            onSupport(unsupportedIdSupplier);
        }else if( code == InfoCode.INIT_ERROR_LOAD_CONFIGFILE){            // 加载配置文件出错, SDK内部不会回调onSupport
            // APP自定义逻辑
            Log.w(TAG,"failed to load config file");
            onSupport(unsupportedIdSupplier);
        }else if(code == InfoCode.INIT_ERROR_MANUFACTURER_NOSUPPORT){      // 不支持的设备厂商, SDK内部不会回调onSupport
            // APP自定义逻辑
            Log.w(TAG,"manufacturer not supported");
            onSupport(unsupportedIdSupplier);
        }else if(code == InfoCode.INIT_ERROR_SDK_CALL_ERROR){             // sdk调用出错, SSDK内部不会回调onSupport
            // APP自定义逻辑
            Log.w(TAG,"sdk call error");
            onSupport(unsupportedIdSupplier);
        } else if(code == InfoCode.INIT_INFO_RESULT_DELAY) {             // 获取接口是异步的,SDK内部会回调onSupport
            Log.i(TAG, "result delay (async)");
        }else if(code == InfoCode.INIT_INFO_RESULT_OK){                  // 获取接口是同步的,SDK内部会回调onSupport
            Log.i(TAG, "result ok (sync)");
        }else {
            // sdk版本高于DemoHelper代码版本可能出现的情况,无法确定是否调用onSupport
            // 不影响成功的OAID获取
            Log.w(TAG,"getDeviceIds: unknown code: " + code);
        }
    }

    /**
     * APP自定义的getDeviceIds(Context cxt)的接口回调
     * @param supplier
     */
    @Override
    public void onSupport(IdSupplier supplier) {
        if(supplier==null) {
            Log.w(TAG, "onSupport: supplier is null");
            return;
        }
        if(appIdsUpdater ==null) {
            Log.w(TAG, "onSupport: callbackListener is null");
            return;
        }
        // 获取Id信息
        // 注:IdSupplier中的内容为本次调用MdidSdkHelper.InitSdk()的结果,不会实时更新。 如需更新,需调用MdidSdkHelper.InitSdk()
        boolean isSupported = supplier.isSupported();
        boolean isLimited  = supplier.isLimited();
        String oaid=supplier.getOAID();
        String vaid=supplier.getVAID();
        String aaid=supplier.getAAID();

        //TODO (7) 自定义后续流程,以下显示到UI的示例
        String idsText= "support: " + (isSupported ? "true" : "false") +
                "\nlimit: " + (isLimited ? "true" : "false") +
                "\nOAID: " + oaid +
                "\nVAID: " + vaid +
                "\nAAID: " + aaid + "\n";
        Log.d(TAG, "onSupport: ids: \n" + idsText);
        appIdsUpdater.onIdsValid(oaid);
    }

    public interface AppIdsUpdater {
        void onIdsValid(String oaid);
    }

    /**
     * 从asset文件读取证书内容
     * @param context
     * @param assetFileName
     * @return 证书字符串
     */
    public static String loadPemFromAssetFile(Context context, String assetFileName){
        try {
            InputStream is = context.getAssets().open(assetFileName);
            BufferedReader in = new BufferedReader(new InputStreamReader(is));
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null){
                builder.append(line);
                builder.append('\n');
            }
            return builder.toString();
        } catch (IOException e) {
            Log.e(TAG, "loadPemFromAssetFile failed");
            return "";
        }
    }
}

oaid_sdk_2.5.0.aar在资源里

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于微信小程序的公务员考试信息查询系统+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

【Android】Kotlin教程(4)

文章目录 1.field2.计算属性3.主构造函数4.次构造函数5.默认参数6.初始化块7.初始化顺序7.延迟初始化lateinit8.惰性初始化 1.field field 关键字通常与属性的自定义 getter 和 setter 一起使用。当你需要为一个属性提供自定义的行为时,可以使用 field 来访问或设置…

可以在线制作的PS网页版来了!

在当今数字化的创意时代,设计领域不断发展与变革,设计师们对于工具的需求也日益多样化和高效化。随着互联网技术的飞速进步,一种全新的设计工具模式应运而生——在线制作的 PS 网页版。它以其独特的优势和便捷性,逐渐成为众多设计…

高德地图如何添加自己店铺的位置信息?

众所周知,创业开店时,地理位置的选择至关重要。一个优越的地理位置不仅能显著提升店铺的可见度,还能有效吸引更多潜在顾客的光顾。而且,为了将店铺的客流量最大化,商家还需在地图平台上准确标注自己的位置信息&#xf…

【黄豆颗粒数据集】黄豆识别 机器视觉 深度学习(含数据集)

一、背景意义 随着全球农业生产的现代化,黄豆(大豆)作为一种重要的经济作物,广泛用于食品、饲料和工业原料的生产。准确识别和分类黄豆颗粒对于农业生产的管理、质量控制和市场分析具有重要意义。然而,传统的人工分类方…

JavaEE-多线程上

文章目录 线程概述进程/线程多线程的作用JVM关于线程资源的规范关于Java程序的运行原理 并发与并行并发(concurrency)并行(parallellism)并发编程与并行编程 线程的调度策略分时调度模型抢占式调度模型 创建线程线程类分析入门实现线程的第一种方式实现线程的第二种方式 线程的…

论文阅读:三星-TinyClick

《Single-Turn Agent for Empowering GUI Automation》 赋能GUI自动化的单轮代理 摘要 我们介绍了一个用于图形用户界面(GUI)交互任务的单轮代理,使用了视觉语言模型Florence-2-Base。该代理的主要任务是识别与用户指令相对应的UI元素的屏幕…

Tomcat servlet response关于中文乱码的经验

前言 最近修改老项目项目,使用zuul网关返回的中文内容乱码了,如果使用GBK或者GB2312编码确正常显示,稍微实验了一下,发现里面很多细节,毕竟Springboot对我们做了很多事情,而且当我们使用不同的模式会出现很…

服务器的免密登录和文件传输

在天文学研究中,通常会采用ssh登录服务器,把复杂的计算交给服务器,但是如果你没有进行额外的配置,那么登录服务器,以及和服务器进行文件传输,每次都要输入账号和密码,比较不方便,Win…

Windows Server NTFS磁盘变RAM的处理过程

问题描述 客户服务器的磁盘数据爆满,需要将磁盘进行扩容,因为是虚拟机所以先在虚拟化平台上将原来的磁盘空间改大,再进入系统,在磁盘管理器上将需要扩容的磁盘进行扩展。扩展完后系统报文件系统有问题,扩容的磁盘容量…

No.23 笔记 | WEB安全 - 任意文件漏洞 part 5

本文全面且深入地探讨了文件上传漏洞相关知识。从基础概念出发,清晰地阐述了文件上传漏洞的定义及其产生的本质原因,同时列出了该漏洞成立的必要条件。详细说明了文件上传漏洞可能对服务器控制权、网站安全以及业务运营带来的严重危害。 文中还深入解析了…

[mysql]子查询的概述和分类及单行子查询

子查询引入 查询的基本结构已经给大家了,子查询里面也是有一些新的内容,子查询其实就是在查询中嵌套另一个查询,叫嵌套查询可能大家更容易理解一点..,类似与FOR循环和FOR循环的嵌套,这一章是我们查询的最难的部分,大家 难度是查询的顶峰,多表查询和子查询是非常重要,SQL优化里…

EDA --软件开发之路

之前一直在一家做数据处理的公司,从事c开发,公司业务稳定,项目有忙有闲,时而看下c,数据库,linux相关书籍,后面跳槽到了家eda公司,开始了一段eda开发之路。 eda 是 electric design …

【移动应用开发】使用多媒体--通知/播放音频/视频

目录 一、具体步骤 二、运行截图 1. 开启通知权限 2. 播放音乐 3. 播放视频 三、源代码 1. activity_main.xml 2. activity_video_player.xml 3. activity_notification.xml 4. 一些配置 5. MainActivity 6. VideoPlayerActivity 7. NotificationActivity 8. And…

代码备份管理 —— Git实用操作

目 录 Git那些事版本控制系统git环境搭建运行bashbash命令行git账号全局设置本地仓库的存在远程仓库的存在git管理基本流程git仓库的文件夹常用git命令工作区变为git仓库add命令使用branch命令使用checkout命令使用commit命令使用仓库状态查询代码变更后提交删除或恢复文件管理…

windows下安装及使用labelme

1.进入Anaconda Prompt对话窗口 输入:conda create --namelabelme python3.6 # 创建一个叫labelme的环境 conda create --namelabelme python3.6 2.激活新建的环境,进入 输入:activate labelme #激活环境 activate labelme 3.安装pyqt5 …

集群渲染是一台节点输出吗?它是云渲染农场吗

集群渲染并非单一节点的输出,而是一种分布式计算技术,它通过多台计算机协同工作来加速3D渲染过程。这种技术常被视作云渲染农场的前身,两者在提高渲染效率方面有着相似之处。接下来,让我们深入了解集群渲染与云渲染农场之间的联系…

建筑行业内部知识库的重要性与实施策略

在当今瞬息万变的建筑行业中,企业面临着前所未有的竞争挑战。为了在市场中保持竞争力,建筑企业不仅需要拥有先进的技术和设备,还必须具备高效的知识管理能力。内部知识库,作为知识管理的核心工具,正逐渐成为建筑企业提…

【Fastjson反序列化漏洞:深入了解与防范】

一、Fastjson反序列化漏洞概述 Fastjson是一款高性能的Java语言JSON处理库,广泛应用于Web开发、数据交换等领域。然而,由于fastjson在解析JSON数据时存在安全漏洞,攻击者可以利用该漏洞执行任意代码,导致严重的安全威胁。 二、F…

数据结构 —— AVL树

目录 1. AVL的概念 2.AVL树的结构 3.AVL树的插入 3.1 平衡因子更新 4. 旋转 4.1 旋转的原则 4.2 右单旋 4.2.1 右单旋代码实现 4.3 左单旋 4.3.1 左单旋代码实现 4.4 左右双旋 4.4.1 左右双旋代码实现 4.5 右左双旋 ​编辑 4.5.1 右左双旋代码实现 5. AVL树的判断…