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();
    }
目录
相关文章
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
703 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
12月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
1020 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
12月前
|
缓存 Unix Android开发
Android安卓项目调试之Gradle 与 Gradle Wrapper的概念以及常用gradle命令深度详解-优雅草卓伊凡
Android安卓项目调试之Gradle 与 Gradle Wrapper的概念以及常用gradle命令深度详解-优雅草卓伊凡
1327 8
|
存储 机器学习/深度学习 API
Android API Level 到底是什么?和安卓什么关系?应用发布如何知道自己的版本?优雅草卓伊凡
Android API Level 到底是什么?和安卓什么关系?应用发布如何知道自己的版本?优雅草卓伊凡
1861 31
Android API Level 到底是什么?和安卓什么关系?应用发布如何知道自己的版本?优雅草卓伊凡
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
561 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
741 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
795 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
2302 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
Android开发
Android利用资源名称获取其ID(二)--->反射
MainActivity如下: package cn.testreflect; import java.lang.reflect.Field; import android.
1052 0
|
Android开发 数据格式 XML
Android利用资源名称获取其ID(一)--->getIdentifier()
MainActivity如下:package cc.wy; import android.app.Activity; import android.
1137 0

热门文章

最新文章