获取设备唯一编号替代IMEI新方案

前言

1、IMEI 等设备标识符已经被认定为用户隐私的一部分,在非必要的场景获取甚至频繁获取 IMEI,会被认定为违规获取用户信息的行为;

2、 Android 10 开始,应用无法获取 IMEI、MAC 等设备唯一标识(申请 READ_PRIVILEGED_PHONE_STATE 权限后也可以获取,但这个权限只有系统应用能够获取)。如果应用强行获取,则会获取到 null 信息或发生 SecurityException(取决于 targetSdkVersion);

3、为了解决这个问题,国家相关部委成立了移动安全联盟 MSA,制定了一套《移动智能终端补充设备标识体系》。因为其中最重要的一个标识符是 OAID 匿名设备标识符,因此也有人把这个体系简称为 OAID。

关键词介绍

  • UUID 设备唯一标识符 是不依赖于这个体系的,它们在设备出厂时就固化到硬件信息上了,即使恢复出厂设置也不会重置;

  • OAID 匿名设备标识 是 UUID 的替代品,在终端首次启动时生成。同一设备的 OAID 相同,因此可以在多个应用之间共享,恢复出厂设置会重置 OAID;

  • VAID 开发者匿名设备标识符 是开发者维度的 ID,在应用安装时生成。同一设备上且同一开发者的所有应用 VAID 相同,其他情况 VAID 不同,重新安装应用会重置 VAID;

  • AAID 应用匿名设备标识符 是应用沙盘维度的 ID,在应用安装时生成。即使是同一设备且同一个开发者的应用,AAID 也不同,重新安装、清除用户数据会重置 AAID。

支持厂商

想要实现设备唯一,必须是由厂商支持,所以移动安全联盟的成员和专注于中国市场的厂商会率先支持(我使用的一加截止2020.5.6没有支持),华为、小米、OPPO、vivo、中兴、努比亚、魅族、联想、三星等设备厂商均将逐步支持(一些老的设备且没有经过系统更新的不支持)

OAID使用

    走正常流程是根据 MSA 的要求,下载 SDK 和集成文档前需要注册一个企业账户,这一步按照指引提交相关信息和资料即可,一般 1~2 个工作日就可以审核通过。审核通过还得去商城申请APP的信息才能使用,下面说一种省去这些麻烦步骤,通过反射的方法 直接使用他们sdk生成唯一编号的方法,下面是代码。

如需获取sdk 关注公众号后 回复关键词  OAID 即可。

1、下载sdk之后配置到项目里

获取设备唯一编号替代IMEI新方案_第1张图片

supplierconfig.json里只需给一个空结构就行,无需添加APP信息。

supplierconfig.json文件
{
  "supplier":{
    "vivo":{
    },
    "xiaomi":{
    },
    "huawei":{
    },
    "oppo":{
    }
  }
}

2、调用代码

public static boolean getID(Context context) {
        try {
            Class refCus = Class.forName("com.bun.miitmdid.core.MdidSdkHelper");
            Class callback;
            try {
                // 1.0.10 版本
                callback = Class.forName("com.bun.miitmdid.core.IIdentifierListener");
            } catch (ClassNotFoundException e) {
                // 1.0.23 版本
                callback = Class.forName("com.bun.miitmdid.interfaces.IIdentifierListener");
            }
            final InnerIdSupplier mh = new InnerIdSupplier(context);
            Object mObj = Proxy.newProxyInstance(context.getClassLoader(), new Class[]{callback}, mh);
            Method initSdk = refCus.getDeclaredMethod("InitSdk", Context.class, boolean.class, callback);
            int result = (int) initSdk.invoke(null, context, true, mObj);
            return result == 0;
        } catch (Throwable e) {
            return false;
        }
    }


    private static class InnerIdSupplier implements InvocationHandler {
        Context context;
        public InnerIdSupplier(Context context) {
            this.context=context;
        }


        @Override
        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
            try {
                if ("OnSupport".equals(method.getName())) {
                    boolean isSupport = (boolean) objects[0];
                    if (isSupport) {
                        Object idSupplier = objects[1];
                        String oaid = (String) idSupplier.getClass().getDeclaredMethod("getOAID").invoke(idSupplier);
                        Log.e("唯一id",oaid+"");
                       Looper.prepare();
                        Toast.makeText(context,oaid,Toast.LENGTH_LONG).show();
                        Looper.loop();


                        //                        SpUtils.setString(Utils.getContext(), OAIDHelper.OAID, oaid);
                    }
                    return null;
                }
                return method.invoke(o, objects);
            } catch (Throwable e) {
                return null;
            }
        }
    }

 3、使用

在项目初始化的时候调用getID(this)方法,会在InnerIdSupplier 里边生成唯一id保存起来使用即可。

如需获取sdk 关注公众号后 回复关键词  OAID 即可。

关注我获取更多知识或者投稿

获取设备唯一编号替代IMEI新方案_第2张图片

f4c48febe20a53ae1d3fc42ad4cd1072.png

你可能感兴趣的:(android,java,安卓,移动开发,mac)