You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设备恢复出厂设置时Android Device ID变更,需始终唯一的设备标识

Android 刷机/恢复出厂后获取永久唯一标识的可行方案

当设备执行恢复出厂设置或刷机后,Android Device ID这类软件级标识会被重置,想要获取不受操作影响的唯一标识,只能依赖硬件级别的固有信息,以下是几种可行方案:

1. IMEI/MEID(仅适用于带蜂窝网络的设备)

IMEI是手机基带芯片固化的国际移动设备识别码,MEID是CDMA设备的对应标识,这类信息不受刷机、恢复出厂操作影响。

代码实现

import android.content.Context;
import android.telephony.TelephonyManager;

public String getIMEI(Context context) {
    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        return telephonyManager.getImei();
    } else {
        // 适配Android 8.0以下版本
        return telephonyManager.getDeviceId();
    }
}

注意事项

  • 仅支持手机等带蜂窝模块的设备,WiFi版平板、智能手表等设备无法获取。
  • Android 10及以上版本需要申请READ_PHONE_STATE权限,且用户有权拒绝授权;授权后也可能被用户随时撤销。

2. 设备序列号(Serial Number)

设备出厂时写入硬件存储的序列号,绝大多数设备的序列号不会因刷机、恢复出厂改变。

代码实现

import android.os.Build;

public String getSerialNumber() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        return Build.getSerial();
    } else {
        // 适配Android 8.0以下版本
        return Build.SERIAL;
    }
}

注意事项

  • 部分小众设备可能存在序列号为空的情况。
  • Android 8.0及以上版本需要READ_PHONE_STATE权限,低版本无需权限,但部分厂商可能限制读取。

3. WiFi MAC地址(仅root/系统级应用可用)

WiFi模块的硬件MAC地址是固化的,但Android 6.0+系统默认对普通应用返回随机MAC,只有root权限或系统签名的应用才能读取真实的硬件MAC。

代码实现(仅root/系统应用)

import java.io.BufferedReader;
import java.io.InputStreamReader;

public String getRealMacAddress() {
    try {
        // 读取WiFi硬件地址文件
        Process process = Runtime.getRuntime().exec("cat /sys/class/net/wlan0/address");
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String mac = reader.readLine().trim();
        reader.close();
        return mac;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

4. 多标识组合哈希方案

如果单一硬件标识不可靠(比如平板没有IMEI),可以将多个可用的硬件标识(如序列号、主板ID等)拼接后做哈希运算,生成唯一字符串。

代码实现

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public String generateUniqueId(String... identifiers) {
    StringBuilder sb = new StringBuilder();
    // 拼接所有非空的硬件标识
    for (String id : identifiers) {
        if (id != null && !id.isEmpty()) {
            sb.append(id);
        }
    }
    try {
        // 使用SHA-256生成哈希值
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] hashBytes = md.digest(sb.toString().getBytes());
        StringBuilder hexStr = new StringBuilder();
        for (byte b : hashBytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexStr.append('0');
            hexStr.append(hex);
        }
        return hexStr.toString();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return null;
    }
}

使用示例

// 传入序列号和IMEI(如果有)生成唯一标识
String uniqueId = generateUniqueId(getSerialNumber(), getIMEI(context));

关键注意点

  • 所有硬件标识的读取都可能受系统权限限制,Android 10+对隐私权限管控更严格,普通应用无法保证100%获取到所需信息。
  • 绝对不要依赖Android ID、广告ID这类软件级标识,它们会在恢复出厂或刷机后被重置。
  • 没有任何方案能覆盖所有设备,不同厂商的硬件设计和系统限制可能导致部分标识无法读取,建议同时兼容多种方案。

内容的提问来源于stack exchange,提问作者Gprakash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:24:33