创建全球唯一的Android标识符



当谈到唯一的Android ID时,我相信每个人都看到了这一点,但我也在努力想出一个解决方案来唯一识别任何Android设备。我很乐意使用公开发布的类,但我还没有找到。

在我的情况下,要求是能够唯一地识别任何具有某种形式的互联网连接(如GPRS或Wi-Fi)并在API 8级(v2.2 Froyo)上运行的设备。我不知道有什么设备没有Wi-Fi或SIM卡,所以如果有,请告诉我!

我们通过使用Wi-Fi mac地址的哈希在iOS中解决了这个问题,因为所有iOS设备都应该具有此功能。然而,对于Android,技术(例如上面提到的SO帖子的答案)指的是TelephonyManager类,它可以返回null(例如当设备没有SIM连接时,比如Nexus 7)或getContext().getContentResolver(), Secure.ANDROID_ID,根据这里的说法,它在Froyo之前的版本上不是100%可靠的(这对我来说很幸运)。然而,它没有说明任何问题后Froyo,所以再次,如果有任何问题,请告诉我!我也读过这个可以返回null。根据这里的说法,它可以在工厂重置时发生变化,但这不是一个主要问题。

所以我把这些放在一起,生成一个希望唯一的GUID:[此方法不完整!]

public static String GetDeviceId(Context context)
{
    // Custom String Hash 1
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append("someRandomData"); // Not really needed, but means the stringBuilders value won't ever be null
    // TM Device String
    final TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    String tmDeviceId = tm.getDeviceId(); // Could well be set to null!
    LogMsg.Tmp("TM Device String [" + tmDeviceId + "]");
    // Custom String Hash 2
    stringBuilder.append(tmDeviceId);
    int customHash = stringBuilder.toString().hashCode();
    LogMsg.Tmp("Custom String hash [" + customHash + "]");
    // Device ID String
    String androidIDString = android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
    LogMsg.Tmp("Device ID String [" + androidIDString + "]");
    // Combined hashes as GUID
    UUID deviceUuid = new UUID(androidIDString.hashCode(), ((long)customHash << 32));
    LogMsg.Tmp("Combined hashes as GUID [" + deviceUuid.toString() + "]");
    return deviceUuid.toString();
}

因此,您可能会发现tmDeviceId被设置为null,在这种情况下,无论设备如何,customHash都是相同的,但这与androidIDString的组合应该是全局唯一的。我想。显然,我需要弄清楚tmDeviceIdandroidIDString是否不可用,并在那里抛出异常。

所以。。。这太夸张了吗?如果是,只使用context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID是否安全?

为什么不像在iOS中那样获取设备的MAC地址?这也可以在Android设备中执行。

我将给出一个获取设备mac地址的代码片段。。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class HardwareUtil {
    public static String getMacAddress()
    {
        try{
            Process process = Runtime.getRuntime().exec("cat /sys/class/net/eth0/address");
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            int read;
            char[] buffer = new char[4096];
            StringBuffer output = new StringBuffer();
            while ((read = reader.read(buffer)) > 0){
                output.append(buffer, 0, read);
            }
            reader.close();
            process.waitFor();
            String hwaddr = output.toString();
            return hwaddr;
        }catch (IOException e) {
            e.printstacktrace();
        }catch (InterruptedException e){
            e.printstacktrace();
        }
    }
}

HardwareUtil.getMacAddress()将返回设备的mac地址。

编辑:如果mac地址不适合您的情况。以下内容可能很有用

public static String getDeviceId(Context context) {
    final String deviceId = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
    if (deviceId != null) {
        return deviceId;
    } else {
        return android.os.Build.SERIAL;
    }
}

如果您使用getDeviceId方法,请不要忘记将以下权限添加到您的AndoridManifest.xml文件中。

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

最新更新