Creating a Globally Unique Android Identifier

情到浓时终转凉″ 提交于 2019-12-21 13:36:09

问题


When talking about unique Android ID's, I'm sure everyone has seen this, however I too am trying to come up with a solution to uniquely identify any android device. I would be happy to use a publicly released class but I am yet to find one.

In my situation, the requirement is to be able to uniquely identify any devices that have some form of an internet connection (such as GPRS or Wi-Fi) and run on API level 8 (v2.2 Froyo). I'm not aware of any devices that doesn't have Wi-Fi or a SIM so let me know if there is any!

We solved this problem in iOS by using a hash of the Wi-Fi mac address as all iOS devices should have this. However for Android, techniques (such as the answers to the SO post referenced above) refer to the TelephonyManager class which can return null (such as when the device doesn't have a SIM connection, like with the Nexus 7) or getContext().getContentResolver(), Secure.ANDROID_ID which according to here isn't 100% reliable on versions prior to Froyo (which is fortunate for me). It doesn't however state of any issues post-Froyo so again, if there are any, let me know! I've also read this can return null. According to here it can change on a factory reset, but that isn't a major concern.

So I put together this to generate a hopefully-unique-GUID: [This method is not complete!]

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();
}

So you may find tmDeviceId being set to null, in this case the the customHash will be the same regardless of the device but then this combined with androidIDString should be globally unique. I think. Obviously I will need to work out if tmDeviceId AND androidIDString aren't available and throw an exception there.

So... is this overkill? If so, is it safe to just use context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID?


回答1:


Why don't you get MAC address of the device as you've done in iOS? This can be performed in Android devices as well.

I'll give a code snippet that obtains mac address of the device..

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() will return mac address of the device.

EDIT: If mac address is not appropriate for your situation. Following can be useful!

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;
    }
}

Don't forget to add following permission to your AndoridManifest.xml file if you use getDeviceId method.

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


来源:https://stackoverflow.com/questions/14879608/creating-a-globally-unique-android-identifier

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!