我如何使用我的应用程序的付费版本作为免费版本的“钥匙”?

比方说,我有一些X的Android应用程序,免费版本有广告或基本function。 我想有一个付费版本,删除广告,并添加额外的function。

如何使用付费应用程序作为“许可证密钥”来解锁免费应用程序中的function?

所以用户将安装免费的应用程序,然后安装付费应用程序来获得额外的function,但他们仍然会运行免费的应用程序(现在将被解锁)。 什么是最好的方法来做到这一点?

使用PackageManager来确保您的付费软件包已安装。 并确保您的免费套餐签名符合安装的高级套餐签名。 否则,有人可以安装未经签名的应用程序包名称匹配您的付费软件包名称和解锁溢价这种方式。

这篇文章可以帮助你find你的签名检测,如果应用程序从Android电子市场下载

我正在使用这个:

PackageManager manager = getPackageManager(); if (manager.checkSignatures("core.package.name", "key.package.name") == PackageManager.SIGNATURE_MATCH) { //full version } 

这很简单,它的工作原理。

这是一个简单的函数,用于检查Pro Key是否存在,并检查包签名是否与免费版本匹配:

 protected static boolean isProInstalled(Context context) { PackageManager manager = context.getPackageManager(); if (manager.checkSignatures(context.getPackageName(), "com.your.pro.key") == PackageManager.SIGNATURE_MATCH) { //Pro key installed, and signatures match return true; } return false; } 

代码来自这个论坛post ,基于在yoki.org概述的方法。

正如其他人指出的,是的,你可以使用PackageManager来检测付费“钥匙”应用程序的存在,但如果有人只安装付费版本,卸载免费版本等等,这是有问题的。用户可能会烦恼不得不保持大约两次下载,使您的一个应用程序的工作。 FWIW,我认为DoubleTwist Air Sync就是这样做的。 我很确定Air Sync应用程序除了在免费的DoubleTwist应用程序中启用function外,什么也不做。

更实际的路线可能是有两个独立的应用程序,然后使用ContentProvider和/或sharedUserId将prefs和数据从一个导入到另一个。 然后,您可以使用共享库项目共享大部分代码。 然而,这意味着这两个应用程序都需要使用不同的内容URI,因为两个应用程序不能使用相同的权限,这很痛苦,因为您的共享库代码不能像您一样拥有一个静态的CONTENT_URI或AUTHORITY字段通常在ContentProvider实现中find。

我开始认为有两个或多或less的独立代码库的两个单独的应用程序是要走的路,因为在两个项目之间复制代码实际上可能比试图维护一个共享库以及各种开关来启用或禁用免费和付费版本之间的function。

实际上,edgmanbuild议使用单个应用程序并使用许可证,这可能是pipe理应用程序的免费和付费版本的最佳方式。 它解决了上面列出的所有问题,虽然公平我自己还没有使用许可证。

编辑许可似乎只允许付费应用程序(令人失望),所以如果你想提供免费版本,这是一个不行。 但是,应用内结算可能是您pipe理免费/付费版本的“正确”方式。 也许这对OP是好的,但我不觉得需要两个应用程序总是安装在用户的设备是理想的。 如果付费用户将该应用安装在新设备上,则似乎可以下载先前的交易,以便他们不必支付两次。

如果这两个应用程序都来自同一个开发人员,并由同一个密钥签名,他们应该能够私下共享信息。 您可以使用一个文件(与MODE_PRIVATE一起存储),但我认为最简单的方法就是使用SharedPreferences – 在付费应用程序中设置一个标志,这个标志将被免费阅读。 请参阅http://developer.android.com/guide/topics/data/data-storage.html 。 不知道是否很容易规避,特别是在根植设备上…

另一种方法是检查付费应用程序是否已安装,例如通过检查是否接受特定的意图。 另见: http : //developer.android.com/resources/articles/can-i-use-this-intent.html ; 在这个例子中,他们检查ZXing的条码扫描器是否可用。

无论如何,如果你愿意的话,这个想法的另一个转折就是你可以只用一次支付“启用”多个应用程序。 您的付费应用程序将是一个简单的“支持这个开发人员”,将从您的所有应用程序中删除广告。 这是一个有趣的付费模式恕我直言。

下面是一个如何实现的例子:

 Intent unlockerAppPresence = null; APP_LITE_VERSION = false; try { unlockerAppPresence = context.getPackageManager().getLaunchIntentForPackage("nameofthepackagethatunlockyoursoftware"); } catch (Exception e1) { APP_LITE_VERSION = true; } if (unlockerAppPresence == null) APP_LITE_VERSION = true; 

将此与检查应用程序的开发人员签名(如@Fedor所述)结合使用,您应该很好。

什么绝对只分发免费/演示应用程序,并实施应用程序,使其亲? 因此,只有一个应用程序用户必须安装,他们可以testing基本function,并会有一个button,如“升级到专业版$ 1,99”,将调用应用程序内购买。

显然我不能评论没有50的声望,所以我会把它放在自己的答案。

其他人引用的PackageManager方法似乎是一个很好而且简单的方法,但是正如hackbod提到的,有两个已安装的应用程序对用户来说很烦人(有点令人困惑)。

然而 – 我还没有尝试过,因为我还没有发布我的应用程序 – 似乎你可以保留一个variables,开始为false,然后更新为真,如果它发现了Pro版本安装。 这个variables不会因为Pro版本不存在而恢复为false。 然后,您可以让用户知道两个版本都需要安装Pro,然后打开试用版并单击解锁。 一旦完成,试用版将成为完整版本,并通知您(如果发现安装了Pro版本)您现在可以卸载Pro版本,您将继续拥有完全访问权限。

有点像这样:

 String msg = ""; boolean sigMatch = isProInstalled(context); if (unlocked) { // If you get here by clicking a button that goes away once the app is unlocked, then you may never see this. Still, better safe than sorry. msg += "Thanks! You already have access to the full game."; } else { if (sigMatch) { unlocked = true; saveData(); // I assume you already know how to store variables. msg += "Unlock successful. You now have access to the full game." } else { msg += "You are using a Trial version of this game. (blah, blah). To unlock the full version, please purchase XYZ Pro. Install the application and then start this application again and go into this screen again. You should get a message letting you know that the app has been successfully unlocked, after which you may uninstall the Pro version. You do not have to keep it on your device after unlocking the game."; } } if (sigMatch) { msg += " If you like, you may now uninstall the Pro application. You will continue to have full access to XYZ."; } 

现在,这并不能告诉你用户是否支付Pro版本,然后在24小时之内将其返回,因为hackbod也提到了这一点。**但是,似乎这种情况可能不会经常发生。 如果有人付钱,然后退还(特别是如果你不是非常收费),那么他们可能决定停止使用应用程序…或者他们试图窃取它,在这种情况下,还有其他方法可以做到这一点。 如果这种可能性与您有关,那么应用内结算可能是您的最佳select。 但是,如果您只是在寻找一种简单的措施来阻止临时用户,而您又不想强迫他们一直安装两个应用程序,那么这可能是一个select。

**我想你可以保留一个时间戳与另一个variables,并要求用户保持专业版安装,直到该时间戳后的几个小时,然后让他们卸载…

大多数应用程序开发人员采取的路线是只有一个版本的应用程序,但function启用(额外)或禁用(广告)的基础上存在的“许可证密钥”。