最新消息:欢迎访问Android开发中文站!商务联系微信:loading_in

Android 获取设备唯一标识

热点资讯 loading 834浏览 0评论

一. 先简单总结一下比较常见的几个解决方案的弊端:

1. IMEI

Android 10 中官方明确说明第三方应用无法获取到IMEI码Android 10 中的隐私权变更

Android 10 以下的版本,需要申请READ_PHONE_STATE权限。

2. Android ID

Android ID 不具有真正的唯一性

ROOT、刷机、恢复出厂设置、不同签名的应用等都会导致获取的 Android ID 发生改变,

并且不同厂商定制的系统的BUG会导致不同的设备可能会产生相同的 Android ID。

3. MAC地址

Android 10 中 MAC地址具有随机化的特征Android 10 中的隐私权变更—MAC地址

虽然目前大部分手机还不支持这个特性,但是随着厂商的跟进,这个方案就会逐渐作废

在上面这些设备自带的标识不够满足需求时,我们就要采用另外的方法了。

二. uuid + 本地文件,实现一个通用解决方案

1. 思路

启动APP时,检查并读取根目录下保存有uuid的文件,若没有该文件,则视为一台新设备,创建文件并写入uuid。

并且要确保卸载应用时,该文件不会被系统携带着删除(这也是为什么要在根目录下创建的原因)。

2. 解决手机访问SDK权限问题

Android 6 以下,添加权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Android 6 及其以上,则需要在此基础上申请动态权限。

Android 10 及其以上,文件存储机制修改成了沙盒模式,即应用只能访问自己沙盒下的文件和公共媒体文件。

“得益”于沙盒机制,应用创建的文件属于自己的沙盒,那么当应用卸载时,也会随之删除。

目前可以添加以下一行代码解决沙盒问题:

<application
    ...
    android:requestLegacyExternalStorage="true">

这样我们就能在“根目录”创建自己文件了。

3. Flutter 代码实践

import 'dart:io';
import 'package:uuid/uuid.dart';

// 本地持久化存储uuid代码实践
class Storage {
  static File file;

  // 入口
  static Future<String> init() async {
    bool boolCreateFile = await createFile();
    if (boolCreateFile) {
      String uuid = await readData();
      return uuid;
    } else {
      await writeData();
      String uuid = await readData();
      return uuid;
    }
  }

  // 创建文件
  static Future<bool> createFile() async {
    file = File('/storage/emulated/0/uuid.ini'); // 指向根目录下的文件uuid
    bool exists = await file.exists();
    return exists;
  }

  // 写入数据
  static writeData() async {
    // 如果文件存在,会将原来的内容覆盖, 如果不存在,则创建文件
    String uuid = await getUuid();
    file.writeAsString('$uuid');
  }

  // 读取文件
  static Future<String> readData() async {
    try {
      String uuid = await file.readAsString();
      return uuid;
    } catch (e) {
      return null;
    }
  }

  // 获取uuid,采用的插件:uuid
  static Future<String> getUuid() async {
    Uuid uuidObj = Uuid();
    String uuid = uuidObj.v1();
    return uuid;
  }
}

三. 最后

不要吝啬各位手里的赞啊!

End.

转载请注明:Android开发中文站 » Android 获取设备唯一标识

您必须 登录 才能发表评论!