欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

解决Android10 imei不能获取的问题(适配Android 10)

程序员文章站 2022-03-11 23:21:13
为什么获取IMEI?在android10之前imei唯一标识一个设备,我们用这个值做业务逻辑上的处理。方案:Android 10+取消了获取IMEI的API,这就直接导致我们的程序相关功能不能再Android10设备上的使用,经过查找资料以及官方的建议,打算获取UUID来代替IMEI,通过IO读取存储在手机硬盘中,用来代表唯一设备。String uuid = new Date().getTime() + "_AndroidQ_" + UUID.randomUUID().toString()...

为什么获取IMEI?

在android10之前imei唯一标识一个设备,我们用这个值做业务逻辑上的处理。

方案:

Android 10+取消了获取IMEI的API,这就直接导致我们的程序相关功能不能再Android10设备上的使用,经过查找资料以及官方的建议,打算获取UUID来代替IMEI,通过IO读取存储在手机硬盘中,用来代表唯一设备。

String uuid = new Date().getTime() + "_AndroidQ_" + UUID.randomUUID().toString();

以上代码获取UUID,这里我拼接了写入时的时间毫秒数、标志位(随意,有的人还加了设备信息等等),UUID的组合,降低重复性。

/**
     * 保存文件到SD卡(写入SD卡需要权限,在AndroidManifest.xml中设置android.permission.WRITE_EXTERNAL_STORAGE)
     */
    public String writeSD(String content) {
        //文件输出流
        FileOutputStream out = null;
        //设置文件路径
        File file = new File(Environment.getExternalStorageDirectory(), UUID_FILE_NAME);
        try {
            out = new FileOutputStream(file);
            out.write(content.getBytes());
            return content;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

以上代码为文件写入,这里没什么好说的,注意6.0+需动态获取权限,注意文件路径(文件名建议使用警示语,例如重要文件勿动之类的,降低用户手动删除的风险)

/**
     * 从SD卡中读取文件(读取SD卡需要权限,在AndroidManifest.xml中设置android.permission.READ_EXTERNAL_STORAGE)
     */
    public String readSD() {
        //文件输入流
        FileInputStream in = null;
        //设置文件路径
        File file = new File(Environment.getExternalStorageDirectory(), UUID_FILE_NAME);
        try {
            in = new FileInputStream(file);
            //使用缓冲来读
            byte[] buf = new byte[1024];//每1024字节读一次
            StringBuilder builder = new StringBuilder();
            while (in.read(buf) != -1) {
                builder.append(new String(buf).trim());
            }
            return builder.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

以上代码为读取文件方法

/**
     * 适配安卓10(Q)(API29)及以上
     *
     * @return
     */
    protected String getImeiNew() {
        if (Build.VERSION.SDK_INT >= 29) {
            String UUIDStr = readSD();
            if (UUIDStr == null || UUIDStr.isEmpty()) {//如果为空或者空字符串就生成UUID创建文件并写入UUID
                String uuid = new Date().getTime() + "_AndroidQ_" + UUID.randomUUID().toString();
                String s = writeSD(uuid);
                return s;
            } else {
                return UUIDStr;
            }
        } else {
            @SuppressLint("MissingPermission")
            String deviceId = ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).getDeviceId();
            return deviceId;
        }
    }

这里为调用方法,建议在BaseActivity中编写,首先判断API等级,如果大于安卓10,则直接读取,如果没读取到说明没有相关文件,这里则新建UUID并写入文件,如果有内容则直接返回;API等级如果小于android10,则直接调用getDeveceId获取IMEI,这里同时需要注意动态权限的获取(我直接压制了,便于阅读代码)。

本文地址:https://blog.csdn.net/zqd1984309864/article/details/107410758