Android Q(安卓10)获取唯一ID(最优解)

简介: Android Q(安卓10)获取唯一ID

安卓Q中google彻底禁止了第三发应用获取imei,并且mac地址返回的地址也变成了02:00:00:00:00:00。

这是官方给出的解决方案:

https://developer.android.com/training/articles/user-data-ids

这是官网的截图:

20191011142159452.png

方法一:

既然这两个都没法获取了,所以想到获取ANDROID_ID:

public static String getAndroidId (Context context) {
        String ANDROID_ID = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
        return ANDROID_ID;
    }

但是发现不同应用的正式包在相同设备上得到的ANDROID_ID结果不同,因此显然该方案不可行。


方法二:


按照google官方意见,是在安装应用时,生成UUID,保存到本地,如果本地已经存在UUID,则不在保存,这样就可以将UUID作为唯一标识符。下面是官方推荐截图:

20191011142307566.png

好的,那么就使用UUID:

String uuidStr = UUID.randomUUID().toString();

将UUID以文件的形式保存在多媒体文件目录下,这样一来各个不同的应用间都能采用同一个UUID。生成UUID。其中 saveFileName 为存放uuid数据的文件名:


/**
     * 在媒体文件中 生成fileName文件
     * 向Mediastore添加内容
     *
     * @param saveFileName 保存文件的名称
     */
    private void creatUUIDFile(String saveFileName) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DISPLAY_NAME, saveFileName);
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/*");
        // TODO: 2019-10-11 IS_PENDING = 1表示对应的item还没准备好
        values.put(MediaStore.Images.Media.IS_PENDING, 1);
        ContentResolver resolver = this.getContentResolver();
        Uri collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
        Uri uri = resolver.insert(collection, values);
        try {
            //访问 对于单个媒体文件,请使用 openFileDescriptor()。
            ParcelFileDescriptor fielDescriptor = resolver.openFileDescriptor(uri, "w", null);
            FileOutputStream outputStream = new FileOutputStream(fielDescriptor.getFileDescriptor());
            try {
                //讲UUID写入到文件中
                String uuidStr = UUID.randomUUID().toString();
                outputStream.write(uuidStr.getBytes());
                outputStream.close();
                Log.d(TAG, "写入 uuidStr:" + uuidStr);
            } catch (IOException e) {
                e.printStackTrace();
            }
            values.clear();
            values.put(MediaStore.Images.Media.IS_PENDING, 0);          //设置为0
            resolver.update(uri, values, null, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


如果需要判断是否已经存在存放uuid的文件,则用下面的方法:


/**
     * 检查文件是否存在
     *
     * @param saveFileName 保存文件的名称
     * @return true 为存在   false为不存在
     */
    private boolean checkUUIDFileByUri(String saveFileName) {
        Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        String[] projection = {
                MediaStore.Images.Media.DISPLAY_NAME,
                MediaStore.Images.Media._ID
        };
        //查询
        ContentResolver contentResolver = this.getContentResolver();
        // 添加筛选条件
        String selection = MediaStore.Images.Media.DISPLAY_NAME + "=" + "'" + saveFileName + "'";
        Cursor mCursor = contentResolver.query(mImageUri, projection, selection, null, null);
        String getSaveContent = "";
        if (mCursor != null) {
            while (mCursor.moveToNext()) {
                int fileIdIndex = mCursor.getColumnIndex(MediaStore.Images.Media._ID);
                String thumbPath = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon()
                        .appendPath(String.valueOf(mCursor.getInt(fileIdIndex))).build().toString();
                Uri fileUri = Uri.parse(thumbPath);
                try {
                    ParcelFileDescriptor fielDescriptor = contentResolver.openFileDescriptor(fileUri, "r", null);
                    FileInputStream inputStream = new FileInputStream(fielDescriptor.getFileDescriptor());
                    getSaveContent = inputStreamToString(inputStream);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                //只有在得到的唯一标识符不为空的情况下才结束循环,否则一直循环
                if (!TextUtils.isEmpty(getSaveContent)) {
                    break;
                }
            }
            mCursor.close();
        }
        return !getSaveContent.equals("");
    }


上面代码中的inputStreamToString()方法为流转字符串,代码如下:


/**
     * 流转为字符串
     *
     * @param is 流
     * @return 转换完成的字符串
     */
    public String inputStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("/n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
目录
相关文章
|
5月前
|
数据管理 API 数据库
探索Android Jetpack:现代安卓开发的利器
Android Jetpack是谷歌为简化和优化安卓应用开发而推出的一套高级组件库。本文深入探讨了Jetpack的主要构成及其在应用开发中的实际运用,展示了如何通过使用这些工具来提升开发效率和应用性能。
|
3月前
|
Android开发
我的Android进阶修炼:安卓启动流程之init(1)
本文深入分析了Android系统中的init进程,包括其源码结构、主要功能以及启动流程的详细注解,旨在帮助读者理解init作为用户空间的1号进程在Android启动过程中的关键作用。
63 1
|
3月前
|
Java 网络安全 开发工具
UNITY与安卓⭐一、Android Studio初始设置
UNITY与安卓⭐一、Android Studio初始设置
|
3月前
|
Java 开发工具 Android开发
Android Studio利用Build.gradle导入Git commit ID、Git Branch、User等版本信息
本文介绍了在Android Studio项目中通过修改`build.gradle`脚本来自动获取并添加Git的commit ID、branch名称和用户信息到BuildConfig类中,从而实现在编译时将这些版本信息加入到APK中的方法。
71 0
|
5月前
|
Android开发
Android studio 出现Plugin [id: ‘com.android.application‘, version: ‘8.1.0‘, apply: false] 问题解决办法
Android studio 出现Plugin [id: ‘com.android.application‘, version: ‘8.1.0‘, apply: false] 问题解决办法
1254 1
|
5月前
|
人工智能 安全 物联网
【Android】安卓开发的前景
【Android】安卓开发的前景
112 1
|
6月前
|
Android开发 异构计算 前端开发
Android显示原理,安卓自定义view面试
Android显示原理,安卓自定义view面试
|
5月前
|
存储 API 开发工具
kotlin安卓开发,如何获取设备的唯一id, 有哪些开源库
在Kotlin的Android开发中,获取设备唯一ID的方法包括不稳定的ANDROID_ID、需要权限的IMEI、使用UUID与SharedPreference结合,以及考虑隐私的Firebase Installations ID和Advertising ID。由于隐私问题和Google Play政策,IMEI和ANDROID_ID不推荐作为长期唯一标识。推荐使用UUID(首次安装时生成并存储),或在涉及广告时使用Advertising ID(需用户同意),而Firebase Installations ID则提供了一种合规的设备标识选项。在选择方法时,必须遵守隐私指南和政策。
|
6月前
|
传感器 监控 Android开发
构建高效安卓应用:深入理解Android Profiler
【5月更文挑战第28天】在移动开发领域,应用性能优化是一个永恒的话题。随着Android设备的多样化,确保应用在不同设备上都能流畅运行成为了开发者的一项重要任务。Android Profiler是Android Studio提供的一个集成工具,它能够帮助开发者监控应用的CPU、内存、网络和电池使用情况。本文将深入探讨如何使用Android Profiler来分析并优化应用性能,使开发者能够构建出更高效的安卓应用。
78 0
|
6月前
|
存储 Android开发
Android插件化-Broadcast篇,2024年最新安卓面试自我介绍
Android插件化-Broadcast篇,2024年最新安卓面试自我介绍