在安卓中生成唯一标识符(UUID)

18

几个月来,我一直在使用一个类来生成一个在重新安装之间保持不变的UUID。我的应用程序是关于折扣的,所以我依靠这个UUID来限制每个设备上的优惠券数量。

protected void getDeviceId(){
    try {
        Context context = cordova.getActivity().getApplicationContext();
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        String uuid;
        String androidID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
        String deviceID = tm.getDeviceId();
        String simID = tm.getSimSerialNumber();

        if ("9774d56d682e549c".equals(androidID) || androidID == null) {
            androidID = "";
        }

        if (deviceID == null) {
            deviceID = "";
        }

        if (simID == null) {
            simID = "";
        }

        uuid = androidID + deviceID + simID;
        uuid = String.format("%32s", uuid).replace(' ', '0');
        uuid = uuid.substring(0, 32);
        uuid = uuid.replaceAll("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5");

        this.callbackContext.success(uuid);
    }catch(Exception e ) {
        this.callbackContext.error("Exception occurred: ".concat(e.getMessage()));
    }
}
那就是我生成uuid的核心。问题是,这个周末有人使用XT1032和Android 5.1,在每次安装应用程序后都能够重新生成不同的UUID,并获得免费优惠券。我使用的这种方法可能会被欺骗吗?也许用一个rooted手机?我一无所知。我需要能够在安装之间创建可靠的UUID。
4个回答

30

我以前用过这个,对我来说工作得很好。

public String createTransactionID() throws Exception{
    return UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
}

到目前为止我还没有得到那个。你得到了吗? - vidulaJ
3
我需要始终生成相同的ID。我认为这只提供了一个随机块?问题是,当人们删除我的应用程序后重新安装时,我必须为同一部手机重新生成相同的ID,以便能够识别它。我认为这样行不通? - monxas
这是你从问题中所要求的吗?如果是,你必须保持一些参数的唯一性。 - vidulaJ
这就是问题所在,能够为每个手机分配一个唯一的ID并通过安装保持不变,这就是我使用获取设备ID、获取SIM卡序列号等方法的原因... - monxas
4
我很惊讶这个回答获得了19个赞,而没有人理解原帖作者的问题。 - Houman
显示剩余3条评论

8
您的UUID取决于三个不同的ID,这些ID都很容易更改。无法确定这是否是原因,但查看此处的代码:

SSN(SIM序列号) getSimSerialNumber()可获取连接的SIM卡的SSN。为同一设备生成不同的UUID的简单方法就是插入不同的SIM卡。虽然有些麻烦,但仍然可行。

IMEI / MEID getDeviceId()返回IMEI或MEID。因此,另一种方法是更改设备的IMEI。如果您只搜索“无需root更改手机IMEI”,则会得到大量可行的结果。这可能是更容易的方式(如果自动化)。

Android设备ID ANDROID_ID根据文档在每次恢复电话时更改。因此,用户可以通过恢复电话来更改UUID

由于您的UUID基于三个唯一ID链,欺骗系统就像链中最薄弱的环节一样容易。在此链中,ANDROID_ID是最强的环节,我建议您只使用它。 请参阅此链接作为替代方案


编辑:

虽然ANDROID_ID仍然是识别先前用户的最佳方法,但自Oreo以来,其使用和独特性已经有所更新。访问#ANDROID_ID页面以获取更多详细信息。

更改的摘要如下:

针对Android Oreo或更高版本并安装在Android Oreo或更高版本上的应用程序,每个ANDROID_ID都由安装该应用程序的用户、应用程序的签名(基本上对于不同的应用程序是不同的,但不一定)和设备唯一。因此,尽管在大多数情况下您仍将获得相同的ID,但以不同用户身份安装应用程序仍将生成不同的ANDROID_ID。这些更改是为了保护用户的隐私。

ANDROID_ID的权限也有更新。


是的,你说得对。你知道java.util.UUID.randomUUID()在同一设备上的不同安装之间是否会提供相同的数字吗?其他人指向那里,但我不确定他们是否理解我的问题。 - monxas
1
@monxas 使用 java.util.UUID.randomUUID() 将每次生成不同的 UUID,但它使用的机制即在生成之前检查是否已存在,仅在用户重新安装应用程序时确保不同的 UUID(升级时保持相同)。我认为这不是您想要的(如果用户具有 root 访问权限,则文件也可以被删除)。 - Abbas
谢谢,我差不多确定那不是我需要的。我会使用android_ID。 - monxas
@monxas 我和你一样遇到了同样的问题。你最终是否采用了使用 Android_ID 的方法?你遇到了什么问题吗? - Houman
@Houman 尽管 ANDROID_ID 仍然是识别用户在重新安装应用后的最佳方式。自 Android Oreo 以来,其使用和唯一性已经有了一些更新:请参阅上面链接中的 ANDROID_ID 以获取详细信息。 - Abbas
显示剩余2条评论

2
如果您需要在不同的安装之间创建可靠的UUID,那么这个答案中的建议是您最好的选择。请注意,在设备恢复出厂设置后,ANDROID_ID可能会发生更改,因此它永远不会是无法欺骗您的应用程序的内容。正如您所注意到的那样,大多数其他"UUID"也可能在应用程序安装之间发生更改。有关更多信息,请阅读谷歌的唯一标识符最佳实践。这是必须阅读的。

事实是我已经在我的代码中使用了Secure.ANDROID_ID,但某些人以某种方式绕过它,每次重新安装应用程序时都会获得一个新的UUID。当手机被rooted时,Android ID是否可以更改? - monxas
@monxas 是的,Android_id可以更改,而且它并不是百分之百可靠的。但似乎这是最好的可行选项。 - Houman

1
从Android 10开始,Google限制对所有硬件识别ID的访问权限只限于系统应用或作为完全成熟的mdm控制器的应用程序(据我所知)。以前,您必须要求用户授权,现在甚至不能这样做。
更常见的情况是,您希望按设备付费而不是按Google帐户付费,后者可以在多个设备上使用,但这也适用于您的优惠券。
Google仅建议在类似情况下使用其Firebase ID系统。他们总是强调安全性,并确保您需要使用Google服务。
我能想到的唯一解决方法是您自己的网络服务,包括用户帐户+密码(提供会话令牌或类似令牌),但这对于优惠券应用程序来说可能过于麻烦了?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接