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

发布于 2024-09-05 22:00:38 字数 195 浏览 3 评论 0原文

举例来说,我有一些 Android 应用程序可以执行 X 操作。免费版本有广告或基本功能。我想要一个删除广告并添加额外功能的付费版本。

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

因此,用户将安装免费应用程序,然后安装付费应用程序以获得额外功能,但他们仍然会运行免费应用程序(现在将被解锁)。执行此操作的最佳方法是什么?

Let's say for example that I have some Android app that does X. The free version has ads or basic features. I want to have a paid version that removes the ads and adds extra features.

How can I use the paid app as a "license key" to unlock the features in the free app?

So the user would install the free app, then install the paid app to get the extra features, but they would still run the free app (which would now be unlocked). What's the best approach to doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

谈下烟灰 2024-09-12 22:00:38

使用 PackageManager 确保您的付费包已安装。并确保您的免费软件包签名与安装的高级软件包签名匹配。否则,有人可以安装未签名的应用程序,其软件包名称与您的付费软件包名称匹配,并以这种方式解锁高级版。

这篇文章可以帮助您找到您的签名检测应用程序从Android Market下载

Use PackageManager to ensure your paid package is installed. AND ensure your free package signature matches installed premium package signature. Otherwise somebody would be able to install unsigned app with package name matching your paid package name and unlock premium this way.

This post can help you to find your signature Detect if app was downloaded from Android Market

岁月流歌 2024-09-12 22:00:38

我正在使用这个:

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

它非常简单而且有效。

I'm using this:

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

It's pretty simple and it works.

今天小雨转甜 2024-09-12 22:00:38

这是一个简单的函数,用于检查 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;
}

代码来自 此论坛帖子,基于 yoki.org

Here's a simple function which checks for the presence of the Pro Key, and checks that the package signature matches the free version:

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

Code is from this forum post, based on the method outlined at yoki.org.

水水月牙 2024-09-12 22:00:38

正如其他人指出的那样,是的,您可以使用 PackageManager 来检测付费“关键”应用程序的存在,但如果有人只安装付费版本、卸载免费版本等,那就有问题了。用户可能会因为必须保留而感到恼火大约下载两次即可使您的一个应用程序正常运行。 FWIW,我认为 DoubleTwist Air Sync 是这样做的方式。我很确定 Air Sync 应用程序除了启用免费 DoubleTwist 应用程序中的功能外不会执行任何操作。

一种更实用的方法可能是拥有两个单独的应用程序,然后能够使用 ContentProvider 和/或 共享用户 ID。然后,您可以共享大部分代码 使用共享库项目但是这意味着两个应用程序需要使用不同的内容 URI,因为两个应用程序不能使用相同的权限,这有点痛苦,因为您的共享库代码不能只有静态 CONTENT_URI或 AUTHORITY 字段,就像您通常在 ContentProvider 实现中找到的那样。

我开始认为两个独立的应用程序具有两个或多或少独立的代码库是可行的方法,因为在两个项目之间复制代码实际上可能比尝试维护具有各种开关以启用或禁用的共享库更容易功能介于免费版和付费版之间。

实际上,edgman 对于使用单个应用程序和使用许可的建议是可能是管理应用程序的免费和付费版本的最佳方式。它解决了上面列出的所有问题,尽管公平地说,我自己还没有使用过许可。

编辑 许可似乎只允许付费应用程序(令人失望),所以它是不行的- 如果您想提供免费版本,请前往。不过,应用内结算可能是适合您的“正确”方式管理免费/付费版本。也许这对OP来说没问题,但我不认为要求用户设备上始终安装两个应用程序是理想的。如果付费用户在新设备上安装该应用程序,似乎可以下载之前的交易,这样他们就不必支付两次。

As someone else pointed out, yes, you can use PackageManager to detect the presence of the paid 'key' app, but that's problematic if someone only installs the paid version, uninstalls the free version, etc. Users might get annoyed at having to keep around two downloads to make your one app work. FWIW, I think DoubleTwist Air Sync does it this way. I'm pretty sure the Air Sync app doesn't do anything except enable the functionality in the free DoubleTwist app.

A more practical route might be to have two separate apps, then give the ability to import prefs and data from one to the other using a ContentProvider and/or sharedUserId. You can then share most of your code using a shared library project. However this means both apps need to use a different content URI since two apps can't use the same authority, which is sort of a pain, because your shared library code can't just have a static CONTENT_URI or AUTHORITY field like you'd normally find in a ContentProvider implementation.

I'm starting to think two separate apps with two more-or-less separate codebases is the way to go, because copying code between two projects might actually be easier than trying to maintain a shared library with all sorts of switches to enable or disable features between a free and paid version.

Actually, edgman's recommendation for using a single app and using licensing is probably the best way to go about managing a free and paid version of an app. It solves all of the problems listed above, although to be fair I haven't used licensing yet myself.

EDIT licensing appears to only be allowed for paid apps (bummer) so it's a no-go if you want to offer a free version. However in-app billing might be the "right" way for you to manage a free/paid version. Maybe it's Ok for the OP but I don't feel like requiring two apps to always be installed on a user's device is ideal. If a paying user installs the app on a new device, it appears to be possible to download prior transactions so they don't have to pay twice.

鸩远一方 2024-09-12 22:00:38

如果这两个应用程序来自同一开发人员并使用相同的密钥签名,那么它们应该能够私下共享信息。您可能可以使用一个文件(使用 MODE_PRIVATE 存储)
,但我认为最简单的途径是使用 SharedPreferences - 在付费应用程序中设置一个标志,免费应用程序将读取该标志。请参阅http://developer.android.com/guide/topics/data/data-storage.html
不知道它是否很容易规避,尤其是在 root 设备上......

另一种方法是检查付费应用程序是否已安装,例如通过检查它是否接受特定 Intent。另请参阅:http://developer.android.com /resources/articles/can-i-use-this-intent.html;在该示例中,他们检查 ZXing 的条形码扫描仪是否可用。

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

Provided both apps are from the same developer and signed by the same key, they should be able to share information privately. You could probably use a file (stored with MODE_PRIVATE)
, but I think the easiest route is to use SharedPreferences - set a flag in the paid app which will be read by the free one. See http://developer.android.com/guide/topics/data/data-storage.html.
No idea if it would be easy to circumvent, especially on rooted devices...

Another way would be to check if the paid app is installed, for example by checking if it accept a specific Intent. See also: http://developer.android.com/resources/articles/can-i-use-this-intent.html; in that example they check if ZXing's barcode scanner is available that way.

In any case, another twist on the idea would be that you could "enable" multiple apps with only one paying, if you so wished. Your paid app would be a simple "support this developer" which would remove ads from all your apps. That's an interesting paying model IMHO.

找个人就嫁了吧 2024-09-12 22:00:38

以下是如何完成此操作的一个示例:

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 所指出的)结合起来,您应该可以开始了。

Here is one example of how it can be done:

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;

Combine this with checking of the app's developer signature (as noted by @Fedor) and you should be good to go.

ˉ厌 2024-09-12 22:00:38

什么绝对只分发免费/演示应用程序并在应用程序内实施以使其成为专业版?因此,用户只需安装一个应用程序,他们就可以测试基本功能,并且会有一个像“升级到专业版 1.99 美元”这样的按钮,可以调用应用程序内购买。

What absolut distributing only a free/demo app and implement in-app to make it pro? Therefore there will be only one app user have to install, they can test basic functions and there will be a button like "upgrade to pro $1,99" that will call in-app purchase.

仙女 2024-09-12 22:00:38

显然,没有 50 声望我就无法发表评论,所以我会将其放在自己的答案中。

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

然而 - 我还没有尝试过这个,因为我还没有发布我的应用程序 - 似乎你可以保留一个以 false 开头的变量,然后如果发现安装了 Pro 版本则更新为 true。该变量不会仅仅因为专业版本不存在而恢复为 false。然后,您可以在两个版本中让用户知道他们需要安装 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 也提到的那样。** 但这种情况似乎不会经常发生。如果有人付款然后退回(特别是如果您收费不多),那么他们可能决定停止使用该应用程序......或者他们试图窃取它,在这种情况下还有其他方法可以做到这一点。如果您担心这种可能性,那么应用内结算可能是您的最佳选择。但是,如果您只是在寻找一种简单的措施来阻止临时用户,并且您不想强迫他们始终安装两个应用程序,那么这可能是一个选择。

** 我想你可以用另一个变量保留一个时间戳,并要求用户保留安装的专业版,直到该时间戳后的几个小时,然后允许他们卸载...

Apparently I cannot comment without 50 reputation, so I will put this in its own answer.

The PackageManager method cited by others seems like a nice and simple way to go, but as hackbod mentions, having two installed applications is annoying (and a bit confusing) for the user.

However - and I haven't tried this, because I haven't published my app yet - it seems like you could keep a variable that starts as false and then updates to true if it finds the Pro version installed. The variable would not revert to false just because the Pro version is not there. Then, you could let the user know in both versions that they need to install Pro, then open up the Trial and click Unlock. Once this is done, the Trial version would become a Full version and inform you (if it found the Pro version installed) that you can now uninstall the Pro version and you will continue to have full access.

Something a bit like this:

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

Now, this cannot tell you whether the user paid for the Pro version and then returned it within 24 hours, as hackbod also mentioned is possible.** But it seems like this scenario might not happen very often. If someone paid and then returned it (especially if you are not charging very much), then they probably decided to stop using the app... or they are trying to steal it, in which case there are other ways to do it anyway. If this possibility concerns you, then In-App Billing may be your best choice. But if you are only looking for a simple measure by which to keep out the casual user, and you don't want to force them to keep two applications installed for all time, then this might be an option.

** I suppose you could keep a timestamp with another variable, and require the user to keep the Pro version installed until some number of hours after that timestamp, THEN allow them to uninstall...

爱*していゐ 2024-09-12 22:00:38

大多数应用程序开发人员采取的方法是仅拥有一个版本的应用程序,但根据“许可证密钥”的存在启用(额外)或禁用(广告)功能。

The route most app developers take on this is to only have one version of the app, but features are enabled (extras) or disabled (ads) based on the presence of the "license key".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文