【问题标题】:Generating Device-Specific Serial Number [duplicate]生成设备特定的序列号 [重复]
【发布时间】:2011-03-28 18:01:41
【问题描述】:

我希望能够为每个 Android 设备生成唯一的序列号,以用于解锁应用程序。我怎么能这样做?

编辑:

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

【问题讨论】:

    标签: android licensing license-key


    【解决方案1】:

    您可以使用Android id。这个 id 对于设备应该是唯一的,但是如何设置取决于设备制造商的实现。

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

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

    【讨论】:

    • 不幸的是,过去有制造商将 ANDROID_ID 设置为空,或者更糟的是,所有设备都设置为空!请参阅this thread
    【解决方案2】:

    为什么不使用他们的谷歌帐户名称?很容易获得,只需要对清单文件进行简单的请求。他们会用 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
    

    我写了一个简单的警报,以确保我在这里找到了一个帐户完整的代码:

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

    【讨论】:

    • 从 android 8.0 开始,这需要请求用户许可。否则它只会返回一个空的帐户数组。
    【解决方案3】:

    Android 已经提供了一个licensing service 供付费应用使用。你有什么不想使用它的理由吗?请记住,尝试将您的应用程序锁定到特定手机会非常惹恼更换设备的用户(例如,迟早要全部更换)。

    【讨论】:

    • 添加提问的原因
    【解决方案4】:

    来自 Google Developer 解决 PR​​NG 问题的解决方案,通过反射获取唯一的设备序列号:

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

    【讨论】:

      【解决方案5】:

      您可以使用序列号作为唯一标识符,因为它们在所有设备中都可用。您不应使用 IMEI 作为唯一标识符,因为它们在 WIFI 选项卡(没有 SIM 卡插槽的选项卡)中不是 abalibale。

      你可以使用

          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) {
          }
      

      【讨论】:

        【解决方案6】:

        您可以为此使用 IMEI 号码。

        【讨论】:

        • 我不会为此使用imei。访问 imei 需要特殊权限,看起来您正在使用您不应该使用的数据并使用户产生怀疑。 imei 不是你应该在手机上存储的东西。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-06
        • 1970-01-01
        • 1970-01-01
        • 2020-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多