生成设备特定的序列号

15

我希望能够为每个Android设备生成唯一的序列号以用于解锁应用程序。我该如何做到这一点?

编辑:

原因是我想改进一个付费应用程序,并为已经购买旧版本(将具有不同的包名)的用户提供通过下载可解锁的免费版本来获取完整版本的方法。我会向旧版本推送一个更新,生成并显示代码,他们可以输入该代码将免费版转换为完全功能版。

6个回答

9

为什么不使用Google账户名呢?它很容易获取,只需要在清单文件上进行简单的请求即可。他们应该已经通过gplay购买了许可证,因此G+账户名就足够了...

在清单文件中:

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

获取账户名称的方法:

AccountManager am = AccountManager.get(this); // "this" references the current Context

Account[] accounts = am.getAccountsByType("com.google");

获取名称的方法:

accounts[0].name

我编写了一个简单的警报,以确保我已经找到了这里的某个账户,全部代码如下:

我编写了一个简单的 alert,以确保我已经在这里找到了某个账户。整段代码如下:

Account[] accounts = am.getAccountsByType("com.google");
    AlertDialog.Builder miaAlert = new AlertDialog.Builder(this);

    miaAlert.setTitle("i found an account name!");
    miaAlert.setMessage(accounts[0].name);
    AlertDialog alert = miaAlert.create();
    alert.show();

1
从Android 8.0开始,这需要请求用户权限。否则,它只会返回一个空的帐户数组。 - Makalele

9
您可以使用Android ID。这个ID应该是设备唯一的,但它的设置方式取决于设备制造商的实现。
String deviceId = Secure.getString(context.getContentResolver(),Secure.ANDROID_ID);

Android Id 可能会在手机恢复出厂设置时更改,并且用户也可以在已 root 的手机上更改它。但是,如果您需要一个 ID 来识别您的用户,那么这应该是可以的。


2
不幸的是,过去有一些制造商将ANDROID_ID设置为null,或者更糟糕的是,在所有设备上都设置为相同的值!请参见此线程 - Andrew T.

2

以下是谷歌开发者解决 PRNG 问题并通过反射获取唯一设备序列号的方案:

http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html

/**
 * Gets the hardware serial number of this device.
 *
 * @return serial number or {@code null} if not available.
 */
private static String getDeviceSerialNumber() {
    // We're using the Reflection API because Build.SERIAL is only available
    // since API Level 9 (Gingerbread, Android 2.3).
    try {
        return (String) Build.class.getField("SERIAL").get(null);
    } catch (Exception ignored) {
        return null;
    }
}

2

Android已经为付费应用提供了一个许可服务。您不想使用它有什么原因吗?请记住,试图将您的应用程序锁定在特定手机上将会使更换设备的用户(例如,所有用户,迟早)非常恼火。


在问题中添加了提问原因。 - Aymon Fournier

0

你可以使用序列号作为唯一标识符,因为它们在所有设备上都可用。你不应该使用IMEI作为唯一标识符,因为它们在没有SIM卡槽的WIFI平板电脑上不可用。

你可以使用

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

-1
你可以使用IMEI号码进行这个操作。

我不会使用 IMEI 做这件事。访问 IMEI 需要特殊权限,看起来像您正在使用您不应该使用的数据,这会引起用户的怀疑。IMEI 不是您应该未经处理就离开手机存储的内容。 - Janusz

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