如何找到Android设备的序列号?


115

我需要为Android应用程序使用唯一的ID,我认为该设备的序列号将是不错的选择。如何在我的应用程序中检索Android设备的序列号?


2
不要忘记在清单中添加android:name =“ android.permission.READ_PHONE_STATE”
Michael SIlveus 2010年


如果要获得没有任何权限的唯一ID,则可以使用该库为每个设备生成具有Identity.getDeviceId(context)的唯一ID,或者通过Identity.getInstallationId(context)为应用程序安装生成标识符。
Caw

Answers:


105
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

getSystemService是Activity类中的方法。getDeviceID()将返回设备的MDN或MEID,具体取决于电话使用的无线电(GSM或CDMA)。

每个设备都必须在此返回唯一值(假设它是一部电话)。这适用于任何带有SIM卡插槽或CDMA无线电的Android设备。您可以独自依靠Android供电的微波炉;-)


@Hasemam这对我不起作用,出现“强制关闭”错误
Paresh Mayani 2010年

23
@Hasemam在androidManifest.xml文件中添加<uses-permission android:name =“ android.permission.READ_PHONE_STATE”> </ uses-permission>权限后,现在可以正常运行。
Paresh Mayani 2010年

23
有一个关于使用该标识在官方Android开发者博客一些建议:android-developers.blogspot.com/2011/03/...
大卫Snabel-Caunt

8
除了Android微波炉之外,Android平板电脑又如何?:)
ajacian81

21
应避免使用此方法,该方法适用于电话,但不适用于没有电话芯片的设备(平板电脑就是一个例子)。从2.3开始,您可以使用android.os.Build.SERIAL,但请查看@DavidCaunt建议的开发人员博客。
约翰·米切尔

71

正如Dave Webb所提到的,Android开发者博客上有一篇文章对此进行了介绍。

我与Google的某人交谈,以进一步澄清一些问题。这是我发现的上述博客文章中未提及的内容:

  • ANDROID_ID是首选解决方案。ANDROID_ID在Android <= 2.1或> = 2.3的版本上完全可靠。只有2.2具有帖子中提到的问题。
  • 一些制造商的一些设备受2.2中ANDROID_ID错误的影响。
  • 据我所能确定的,所有受影响的设备都具有相同的ANDROID_ID,即9774d56d682e549c。这也是仿真器btw报告的相同设备ID。
  • Google相信OEM已为其许多或大多数设备修复了该问题,但我能够验证,至少从2011年4月开始,找到具有ANDROID_ID损坏的设备还是很容易的。

根据Google的建议,我实现了一个类,该类将为每个设备生成一个唯一的UUID,并在适当情况下使用ANDROID_ID作为种子,并根据需要依赖TelephonyManager.getDeviceId(),如果失败,则采用随机生成的唯一UUID在重新启动应用程序(但不重新安装应用程序)中保持不变。

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

public class DeviceUuidFactory {

    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";
    protected static volatile UUID uuid;

    public DeviceUuidFactory(Context context) {
        if (uuid == null) {
            synchronized (DeviceUuidFactory.class) {
                if (uuid == null) {
                    final SharedPreferences prefs = context
                            .getSharedPreferences(PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null);
                    if (id != null) {
                        // Use the ids previously computed and stored in the
                        // prefs file
                        uuid = UUID.fromString(id);
                    } else {
                        final String androidId = Secure.getString(
                            context.getContentResolver(), Secure.ANDROID_ID);
                        // Use the Android ID unless it's broken, in which case
                        // fallback on deviceId,
                        // unless it's not available, then fallback on a random
                        // number which we store to a prefs file
                        try {
                            if (!"9774d56d682e549c".equals(androidId)) {
                                uuid = UUID.nameUUIDFromBytes(androidId
                                        .getBytes("utf8"));
                            } else {
                                final String deviceId = ((TelephonyManager) 
                                        context.getSystemService(
                                            Context.TELEPHONY_SERVICE))
                                            .getDeviceId();
                                uuid = deviceId != null ? UUID
                                        .nameUUIDFromBytes(deviceId
                                                .getBytes("utf8")) : UUID
                                        .randomUUID();
                            }
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }
                        // Write the value out to the prefs file
                        prefs.edit()
                                .putString(PREFS_DEVICE_ID, uuid.toString())
                                .commit();
                    }
                }
            }
        }
    }

    /**
     * Returns a unique UUID for the current android device. As with all UUIDs,
     * this unique ID is "very highly likely" to be unique across all Android
     * devices. Much more so than ANDROID_ID is.
     * 
     * The UUID is generated by using ANDROID_ID as the base key if appropriate,
     * falling back on TelephonyManager.getDeviceID() if ANDROID_ID is known to
     * be incorrect, and finally falling back on a random UUID that's persisted
     * to SharedPreferences if getDeviceID() does not return a usable value.
     * 
     * In some rare circumstances, this ID may change. In particular, if the
     * device is factory reset a new device ID may be generated. In addition, if
     * a user upgrades their phone from certain buggy implementations of Android
     * 2.2 to a newer, non-buggy version of Android, the device ID may change.
     * Or, if a user uninstalls your app on a device that has neither a proper
     * Android ID nor a Device ID, this ID may change on reinstallation.
     * 
     * Note that if the code falls back on using TelephonyManager.getDeviceId(),
     * the resulting ID will NOT change after a factory reset. Something to be
     * aware of.
     * 
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID
     * directly.
     * 
     * @see http://code.google.com/p/android/issues/detail?id=10603
     * 
     * @return a UUID that may be used to uniquely identify your device for most
     *         purposes.
     */
    public UUID getDeviceUuid() {
        return uuid;
    }
}

1
应用程序使用此权限需要什么权限?
Dave L.

1
<uses-permission android:name =“ android.permission.READ_PHONE_STATE”> </ uses-permission>
Gabrielle

1
@ ef2011,它是双重检查的锁定模式:en.wikipedia.org/wiki/Double-checked_locking
emmby 2012年

3
感谢您的发布。但是,如何阻止拥有根电话的人简单地编辑device_id.xml来放置他们选择的新UUID?(即绕过“免费试用”检查)如果类必须使用随机ID方法,则仅将值存储在首选项文件中会更好吗?否则,无需在应用程序运行之间保留它。重新生成更安全。
卡洛斯·P

1
““ ANDROID_ID”是首选解决方案”。请注意,ANDROID_ID不再唯一地标识设备:stackoverflow.com/a/13465373/150016
Tom

32
String serial = null; 

try {
    Class<?> c = Class.forName("android.os.SystemProperties");
    Method get = c.getMethod("get", String.class);
    serial = (String) get.invoke(c, "ro.serialno");
} catch (Exception ignored) {
}

此代码使用隐藏的Android API返回设备序列号。


7
这给了我与android.os.Build.SERIAL相同的价值
josephus 2012年

我是否弄错了,或者该序列号在具有特定自定义rom的所有设备中都相同?对于具有自定义rom的电话,我的设备序列号(在Eclipse设备启动器中)显示01234567890ABC。
Peterdk

在我的设备上使用cyanogen-9的@Peterdk两种方法(答案中为andy-9之前的版本,andy-9中更容易使用的一种)报告正确的s / n(与制造商标签上的相同)。不过,这可能取决于特定的自定义rom版本。您正在使用什么rom /版本?
morgwai

16
String deviceId = Settings.System.getString(getContentResolver(),
                                Settings.System.ANDROID_ID);

虽然,并不能保证Android ID将是唯一标识符。


@Paresh Mayani,不看代码就很难说出问题所在。我唯一的假设getContentResolver就是回来了null。但是,打开一个问题并发布您的代码可能值得。
安东尼·弗洛尼

4
该ID来自与手机关联的Google帐户。模拟器通常没有一个。一部真实的电话也可能没有一部。而且,它被记录为“可以在恢复出厂设置时更改”,并且可以在有根电话上随时进行任意更改。使用风险自负。没有很好的选择-其他暂定设备ID要么不是通用的,要么不是唯一的,或者两者都不是。有关此悲伤故事的其余部分,请参见其他答案。
塞瓦·阿列克谢耶夫

14

Android开发者博客上一篇很棒的文章讨论了这一点

建议您不要使用TelephonyManager.getDeviceId()它,因为它不适用于非手机(如平板电脑)的Android设备,需要获得READ_PHONE_STATE许可,并且不能在所有手机上可靠运行。

相反,您可以使用以下之一:

  • MAC地址
  • 序列号
  • ANDROID_ID

这篇文章讨论了每种方法的优缺点,值得一读,因此您可以算出哪种最适合您。


+1,嗨,达芙,thanx进行了澄清,因为现在我正在为平板电脑开发一个应用程序,在这里我需要具有Android设备的唯一ID,那么我应该使用什么来获得Unique Android平板电脑设备?
Paresh Mayani

12

对于设备唯一且在生命周期内不变的简单数字(除非恢复出厂设置或入侵),请使用Settings.Secure.ANDROID_ID

String id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);

要使用设备序列号(“系统设置/关于/状态”中显示的序列号)(如果可用)并使用Android ID:

String serialNumber = Build.SERIAL != Build.UNKNOWN ? Build.SERIAL : Secure.getString(getContentResolver(), Secure.ANDROID_ID);

简单的答案!
faris faris

Build.SERİAL弃用Java的
EyyüpAlkış

7

IMEI很好,但只能在带有手机的Android设备上使用。您还应该考虑支持没有手机的平板电脑或其他Android设备。

您有一些替代方法,例如:构建类成员,BT MAC,WLAN MAC,甚至更好-所有这些的组合。

我已经在我的博客上的一篇文章中解释了这些详细信息,请参阅:http : //www.pocketmagic.net/?p=1662


6

由于此处没有答案提到的是完美的,防故障的ID,它既可以通过系统更新持久化,又可以在所有设备中使用(主要是由于Google没有提供单独的解决方案),所以我决定发布一种方法接下来的最好的事情是将两个可用的标识符组合在一起,并在运行时检查它们之间的选择。

在编写代码之前,请注意以下三个事实:

  1. TelephonyManager.getDeviceId()(akaIMEI)不适用于非GSM,3G,LTE等设备,但在存在相关硬件时,即使没有插入SIM卡或没有SIM卡插槽,也总是返回唯一ID(一些OEM已做到这一点)。

  2. 根据Android政策,由于Gingerbread(Android 2.3)android.os.Build.SERIAL 必须存在于任何不提供IMEI的设备上,也就是说,不存在上述硬件。

  3. 由于事实(2.),这两个唯一标识符中的至少一个将始终存在,并且SERIAL 可以与IMEI同时出现。

注意:事实(1.)和(2.)基于Google声明

有了上述事实,通过检查是否存在与IMEI绑定的硬件,始终可以拥有唯一的标识符,如果没有,则回退到SERIAL,因为无法检查现有的SERIAL是否有效。下面的静态类提供了两种方法来检查此类存在以及使用IMEI或SERIAL:

import java.lang.reflect.Method;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;

public class IDManagement {

    public static String getCleartextID_SIMCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

        if(isSIMAvailable(mContext,telMgr)){
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId());
            return telMgr.getDeviceId();

        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static String getCleartextID_HARDCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if(telMgr != null && hasTelephony(mContext)){           
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId() + "");

            return telMgr.getDeviceId();    
        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static boolean isSIMAvailable(Context mContext, 
            TelephonyManager telMgr){

        int simState = telMgr.getSimState();

        switch (simState) {
        case TelephonyManager.SIM_STATE_ABSENT:
            return false;
        case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
            return false;
        case TelephonyManager.SIM_STATE_PIN_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_PUK_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_READY:
            return true;
        case TelephonyManager.SIM_STATE_UNKNOWN:
            return false;
        default:
            return false;
        }
    }

    static public boolean hasTelephony(Context mContext)
    {
        TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm == null)
            return false;

        //devices below are phones only
        if (Build.VERSION.SDK_INT < 5)
            return true;

        PackageManager pm = mContext.getPackageManager();

        if (pm == null)
            return false;

        boolean retval = false;
        try
        {
            Class<?> [] parameters = new Class[1];
            parameters[0] = String.class;
            Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
            Object [] parm = new Object[1];
            parm[0] = "android.hardware.telephony";
            Object retValue = method.invoke(pm, parm);
            if (retValue instanceof Boolean)
                retval = ((Boolean) retValue).booleanValue();
            else
                retval = false;
        }
        catch (Exception e)
        {
            retval = false;
        }

        return retval;
    }


}

我会建议使用getCleartextID_HARDCHECK。如果反射不停留在您的环境中,请使用getCleartextID_SIMCHECK方法,但应考虑到它应适合您的特定SIM卡状态需求。

PS:请注意,OEM已成功针对Google政策(包括具有相同SERIAL的多个设备)对SERIAL进行了修正,而Google指出大型OEM中至少存在一个已知案例(未披露,我不知道哪个品牌要么,我猜三星)。

免责声明:这回答了获取唯一设备ID的原始问题,但是OP通过指出他需要为APP提供唯一ID引入了歧义。即使对于这种情况,Android_ID会更好,例如,通过两次安装不同的ROM(甚至可以是相同的ROM)对应用程序进行Titanium备份后,它将无法正常工作。我的解决方案保持的持久性与闪存或出厂重置无关,并且仅在通过黑客/硬件模块发生IMEI或SERIAL篡改时才会失败。


5

上述所有方法都存在问题。Reto Meier在Google i / o上发布了一个强有力的答案,说明了如何实现这一点,这应该满足大多数开发人员跟踪安装之间用户的需求。

这种方法将为您提供一个匿名的安全用户ID,该ID在不同设备(包括基于主要Google帐户的平板电脑)上以及在同一设备上的安装之间对于用户都是永久的。基本方法是生成随机用户ID,并将其存储在应用程序的共享首选项中。然后,您使用Google的备份代理将链接到Google帐户的共享首选项存储在云中。

让我们通过完整的方法。首先,我们需要使用Android备份服务为SharedPreferences创建备份。首先通过以下链接注册您的应用:http : //developer.android.com/google/backup/signup.html

Google将为您提供一个备份服务密钥,您需要将其添加到清单中。您还需要告知应用程序使用BackupAgent,如下所示:

<application android:label="MyApplication"
         android:backupAgent="MyBackupAgent">
    ...
    <meta-data android:name="com.google.android.backup.api_key"
        android:value="your_backup_service_key" />
</application>

然后,您需要创建备份代理,并告诉其将帮助代理用于共享首选项:

public class MyBackupAgent extends BackupAgentHelper {
    // The name of the SharedPreferences file
    static final String PREFS = "user_preferences";

    // A key to uniquely identify the set of backup data
    static final String PREFS_BACKUP_KEY = "prefs";

    // Allocate a helper and add it to the backup agent
    @Override
    public void onCreate() {
        SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this,          PREFS);
        addHelper(PREFS_BACKUP_KEY, helper);
    }
}

要完成备份,您需要在主活动中创建一个BackupManager实例:

BackupManager backupManager = new BackupManager(context);

最后,创建一个用户ID(如果尚不存在),并将其存储在SharedPreferences中:

  public static String getUserID(Context context) {
            private static String uniqueID = null;
        private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
    if (uniqueID == null) {
        SharedPreferences sharedPrefs = context.getSharedPreferences(
                MyBackupAgent.PREFS, Context.MODE_PRIVATE);
        uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
        if (uniqueID == null) {
            uniqueID = UUID.randomUUID().toString();
            Editor editor = sharedPrefs.edit();
            editor.putString(PREF_UNIQUE_ID, uniqueID);
            editor.commit();

            //backup the changes
            BackupManager mBackupManager = new BackupManager(context);
            mBackupManager.dataChanged();
        }
    }

    return uniqueID;
}

现在,即使用户切换设备,该User_ID也将在安装过程中保持不变。

有关此方法的更多信息,请参见此处的Reto演讲。 http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html

有关如何实现备份代理的完整详细信息,请参见此处的开发人员网站:http : //developer.android.com/guide/topics/data/backup.html 我特别建议在测试底部的部分进行备份,因为备份确实如此不会立即发生,因此要测试您必须强制执行备份。


2

另一种方法是在没有任何权限的应用程序中使用/ sys / class / android_usb / android0 / iSerial。

user@creep:~$ adb shell ls -l /sys/class/android_usb/android0/iSerial
-rw-r--r-- root     root         4096 2013-01-10 21:08 iSerial
user@creep:~$ adb shell cat /sys/class/android_usb/android0/iSerial
0A3CXXXXXXXXXX5

为此,只需使用FileInputStream打开iSerial文件并读出字符即可。只要确保将其包装在异常处理程序中即可,因为并非所有设备都有此文件。

至少已知以下设备对此文件具有世界可读性:

  • Galaxy Nexus
  • Nexus S
  • 摩托罗拉Xoom 3g
  • 东芝AT300
  • HTC One V
  • 迷你MK802
  • 三星Galaxy S II

您还可以在此处查看我的博客文章:http : //insitusec.blogspot.com/2013/01/leaking-android-hardware-serial-number.html,在这里我可以讨论哪些其他文件可用于获取信息。


感谢您发布答案!请务必仔细阅读有关自我促销常见问题解答。另请注意,每次链接到您自己的站点/产品,都必须发布免责声明。
Andrew Barber

1

正如@haserman所说:

TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

但是有必要在清单文件中包含许可:

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

1

Android OS设备的唯一设备ID(字符串)。

String deviceId;
    final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephony.getDeviceId() != null){
            deviceId = mTelephony.getDeviceId(); 
         }
        else{
            deviceId = Secure.getString(getApplicationContext().getContentResolver(),   Secure.ANDROID_ID); 
         }

但我强烈推荐Google建议的这种方法::

识别应用程序安装


1

Build.SERIAL这是最简单的方法,尽管并不完全可靠,因为它可能为空或有时返回的值与设备设置中看到的值不同(证明1证明2)。

取决于设备的制造商和Android版本,有几种方法可以获取该数字,因此我决定在一个要点中编译所有可能找到的解决方案。这是它的简化版本:

public static String getSerialNumber() {
    String serialNumber;

    try {
        Class<?> c = Class.forName("android.os.SystemProperties");
        Method get = c.getMethod("get", String.class);

        serialNumber = (String) get.invoke(c, "gsm.sn1");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ril.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ro.serialno");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "sys.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = Build.SERIAL;

        // If none of the methods above worked
        if (serialNumber.equals(""))
            serialNumber = null;
    } catch (Exception e) {
        e.printStackTrace();
        serialNumber = null;
    }

    return serialNumber;
}


-1

我发现@emmby发布的示例类是一个很好的起点。但是,正如其他海报所提到的那样,它有一些缺陷。最主要的是,它会不必要地将UUID持久保存到XML文件,然后始终从该文件中检索它。这使该类容易受到黑客攻击:任何拥有扎根手机的人都可以编辑XML文件,以为其提供新的UUID。

我已经更新了代码,以便仅在绝对必要时(例如,当使用随机生成的UUID时)才可以持久保存为XML,并按照@Brill Pappin的答案重新构造了逻辑:

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

public class DeviceUuidFactory {
    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";

    protected static UUID uuid;

    public DeviceUuidFactory(Context context) {

        if( uuid ==null ) {
            synchronized (DeviceUuidFactory.class) {
                if( uuid == null) {
                    final SharedPreferences prefs = context.getSharedPreferences( PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null );

                    if (id != null) {
                        // Use the ids previously computed and stored in the prefs file
                        uuid = UUID.fromString(id);

                    } else {

                        final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);

                        // Use the Android ID unless it's broken, in which case fallback on deviceId,
                        // unless it's not available, then fallback on a random number which we store
                        // to a prefs file
                        try {
                             if ( "9774d56d682e549c".equals(androidId) || (androidId == null) ) {
                                final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();

                                if (deviceId != null)
                                {
                                    uuid = UUID.nameUUIDFromBytes(deviceId.getBytes("utf8"));
                                }
                                else
                                {
                                    uuid = UUID.randomUUID();

                                    // Write the value out to the prefs file so it persists
                                    prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();
                                }
                            }
                            else
                            {
                                uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
                            } 
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }



                    }

                }
            }
        }

    }


    /**
     * Returns a unique UUID for the current android device.  As with all UUIDs, this unique ID is "very highly likely"
     * to be unique across all Android devices.  Much more so than ANDROID_ID is.
     *
     * The UUID is generated by using ANDROID_ID as the base key if appropriate, falling back on
     * TelephonyManager.getDeviceID() if ANDROID_ID is known to be incorrect, and finally falling back
     * on a random UUID that's persisted to SharedPreferences if getDeviceID() does not return a
     * usable value.
     *
     * In some rare circumstances, this ID may change.  In particular, if the device is factory reset a new device ID
     * may be generated.  In addition, if a user upgrades their phone from certain buggy implementations of Android 2.2
     * to a newer, non-buggy version of Android, the device ID may change.  Or, if a user uninstalls your app on
     * a device that has neither a proper Android ID nor a Device ID, this ID may change on reinstallation.
     *
     * Note that if the code falls back on using TelephonyManager.getDeviceId(), the resulting ID will NOT
     * change after a factory reset.  Something to be aware of.
     *
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID directly.
     *
     * @see http://code.google.com/p/android/issues/detail?id=10603
     *
     * @return a UUID that may be used to uniquely identify your device for most purposes.
     */
    public UUID getDeviceUuid() {
        return uuid;
    }

将ID放入共享的首选项中会损害获得真正唯一ID的原始目标。例如,如果您想使用该ID作为某些限制的键,那么当熟练的用户对设备进行root操作并可以访问您的共享首选项文件时,您将很困惑。它的内容可能会被复制,这意味着...
Eugene Wechsler

MB的答案和您的答案也存在另一个错误。
Fred Grott

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.