是否可以通过getInstallerPackageName 来检查安装付费android 应用程序的合法性?

Is it ok to check legality of installing paid android app by checking getInstallerPackageName?

为确保我的付费 android 应用程序是从商店合法安装的,我这样写:

String installer = getPackageManager().getInstallerPackageName(
        "com.example.myapp");

if (installer == null) {
    // app was illegally downloaded from unknown source. 
    // dear user, please re-install it from market
} 
else {
    // app was probably installed legally
    // (also it's good to check actual installer name)
}

可以吗?从市场合法购买和安装的应用程序是否有可能获得空安装程序包名称并无法通过此测试?

我知道用户可以 运行 adb -i com.fake.installer myapp.apk 并通过此检查,但更重要的是 合法 用户是否会遇到潜在问题。

您不应使用 PackageManager#getInstallerPackageName 检查该应用程序是否从 Google Play 安装或用于许可目的,原因如下:

1) 安装程序包名称将来可能会更改。例如,安装程序包名称以前是 "com.google.android.feedback"(参见 here),现在是 "com.android.vending".

2) 出于盗版原因检查安装程序包名称等同于使用 Base64 加密密码 — 这简直是糟糕的做法。

3) 合法购买该应用的用户可以旁加载 APK 或从另一个未设置正确安装程序包名称的备份应用恢复它并获得许可证检查错误。这很可能会导致差评。

4)如您所说,盗版者在安装APK时可以简单地设置安装程序包名称。


你应该使用 App Licensing or switch to In-app Billing.

虽然 getInstallerPackage("com.example.mypackagename") 可以解决问题,但对于 "hackers" 来说,在不实际付费的情况下仍然使用您的付费应用程序基本上有点困难,但这确实不是最好的方法不要让这种情况发生。

你可以做什么?

这基本上可以确保该应用已被用户使用 phone 购买。

  • 您可以做的另一件事是让您的应用程序免费并添加应用程序购买。在您的情况下,只需一次应用内购买,一次订阅。 在我看来,这是解决这个问题的更好方法,原因有二:
    1. 它解决了您原来的问题,不让用户使用您的高级功能,除非他们实际购买它们。
    2. 它使您的应用下载起来更加友好。用户可以在购买前先试用,这在尝试获得更多用户时总是一个加分项。

当然,这有一个缺点:如果您的应用程序架构不是围绕这个想法构建的,那么您需要做很多工作。但是,我认为这是完全值得的。