比方说,我有一些做X的Android应用程序。免费版本有广告或基本功能。我想要一个支付版本,删除广告并添加额外的功能。
如何使用付费应用作为“许可密钥”来解锁免费应用中的功能?
因此,用户将安装免费应用程序,然后安装付费应用程序以获取额外功能,但他们仍将运行免费应用程序(现在将解锁)。这样做的最佳方法是什么?
答案 0 :(得分:37)
使用PackageManager确保已安装付费软件包。并确保您的免费包裹签名与安装的高级包裹签名相匹配否则,有人可以安装未签名的应用程序,其包名称与您的付费包名称相匹配,并以这种方式解锁溢价。
这篇文章可以帮助您找到您的签名Detect if app was downloaded from Android Market
答案 1 :(得分:20)
我正在使用它:
PackageManager manager = getPackageManager();
if (manager.checkSignatures("core.package.name", "key.package.name")
== PackageManager.SIGNATURE_MATCH) {
//full version
}
这很简单,很有效。
答案 2 :(得分:8)
这是一个简单的函数,用于检查是否存在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;
}
代码来自this forum post,基于yoki.org概述的方法。
答案 3 :(得分:7)
正如其他人指出的那样,是的,您可以使用PackageManager来检测付费“密钥”应用程序的存在,但如果有人只安装付费版本,卸载免费版本等,则会出现问题。用户可能会对此感到恼火必须保持两次下载以使您的一个应用程序工作。 FWIW,我认为DoubleTwist Air Sync就是这样做的。我非常确定Air Sync应用程序除了在免费的DoubleTwist应用程序中启用功能外什么都不做。
更实际的路线可能是拥有两个单独的应用,然后可以使用ContentProvider和/或sharedUserId将prefs和数据从一个导入到另一个。然后,您可以共享大部分代码using a shared library project。 然而这意味着两个应用都需要使用不同的内容URI,因为两个应用无法使用相同的权限,这有点痛苦,因为您的共享库代码不能只具有静态CONTENT_URI或者您通常在ContentProvider实现中找到的AUTHORITY字段。
我开始认为两个单独的应用程序带有两个或多或少的独立代码库是可行的方法,因为在两个项目之间复制代码实际上可能比尝试维护具有各种开关的共享库更容易启用或禁用免费版和付费版之间的功能。
实际上,edgman建议使用单个应用程序和using licensing可能是管理免费和付费版应用程序的最佳方式。它解决了上面列出的所有问题,虽然公平地说我还没有使用许可证。
EDIT 许可似乎只允许付费应用(无聊),所以如果您想提供免费版本,这是不可取的。但是in-app billing可能是您管理免费/付费版本的“正确”方式。也许它对OP来说没问题,但我不觉得要求两个应用总是安装在用户的设备上是理想的。如果付费用户在新设备上安装该应用程序,则似乎可以下载先前的交易,这样他们就不必支付两次。
答案 4 :(得分:3)
如果两个应用程序都来自同一个开发人员并使用相同的密钥签名,则他们应该能够私下共享信息。你可以使用一个文件(用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的条形码扫描仪是否可用。
在任何情况下,如果你愿意的话,另一个想法是你可以“启用”只有一个付费的多个应用程序。您的付费应用将是一个简单的“支持此开发者”,可以从您的所有应用中删除广告。这是一个有趣的付费模式恕我直言。
答案 5 :(得分:1)
以下是如何完成的一个例子:
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所述)相结合,您应该很高兴。
答案 6 :(得分:1)
什么absolut只分发免费/演示应用程序并在应用程序中实现以使其成为专业人士?因此,只有一个应用程序用户必须安装,他们可以测试基本功能,并将有一个按钮,如“升级到亲$ 1,99”,将调用应用程序内购买。
答案 7 :(得分:0)
显然,如果没有50点声望我就无法发表评论,所以我会把它放在自己的答案中。
其他人引用的PackageManager方法似乎是一个很好而且简单的方法,但正如hackbod所提到的,拥有两个已安装的应用程序对于用户而言是令人讨厌的(并且有点令人困惑)。
但是 - 我还没试过,因为我还没有发布我的应用程序 - 看起来你可以保留一个以false开头的变量,然后如果发现安装了Pro版本则更新为true。该变量不会因为Pro版本不存在而恢复为false。然后,您可以让用户知道他们需要安装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也提到了。**但似乎这种情况可能不会经常发生。如果有人支付然后退回(特别是如果你没有收费),那么他们可能决定停止使用该应用......或者他们试图窃取它,在这种情况下还有其他方法可以做到这一点。如果这种可能性与您有关,那么应用内结算可能是您的最佳选择。但是,如果您只是想要一个简单的措施来阻止临时用户,并且您不想强迫他们一直安装两个应用程序,那么这可能是一个选项。
**我想你可以为另一个变量保留一个时间戳,并要求用户将Pro版本安装到该时间戳之后的几个小时,然后允许他们卸载......
答案 8 :(得分:-1)
大多数应用开发者采用的路线是只有一个版本的应用,但根据“许可证密钥”的存在启用(附加)或禁用(广告)功能。