简体   繁体   English

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

[英]How can I use the paid version of my app as a “key” to the free version?

Let's say for example that I have some Android app that does X. The free version has ads or basic features. 比方说,我有一些做X的Android应用程序。免费版本有广告或基本功能。 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? 这样做的最佳方法是什么?

Use PackageManager to ensure your paid package is installed. 使用PackageManager确保已安装付费软件包。 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 如果从Android电子市场下载应用,此帖子可以帮助您找到您的签名检测

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. 它很简单,很有效。

Here's a simple function which checks for the presence of the Pro Key, and checks that the package signature matches the free 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;
}

Code is from this forum post , based on the method outlined at yoki.org . 代码来自此论坛帖子 ,基于yoki.org上列出的方法。

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. 正如其他人指出的那样,是的,您可以使用PackageManager来检测付费“密钥”应用程序的存在,但如果有人只安装付费版本,卸载免费版本等,则会出现问题。用户可能会因为不得不保持不安而感到恼火大约两次下载,让你的一个应用程序工作。 FWIW, I think DoubleTwist Air Sync does it this way. FWIW,我认为DoubleTwist Air Sync就是这样做的。 I'm pretty sure the Air Sync app doesn't do anything except enable the functionality in the free DoubleTwist app. 我很确定Air Sync应用程序除了在免费的DoubleTwist应用程序中启用功能外什么都不做。

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

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. 实际上,edgman建议使用单个应用程序并 使用许可证可能是管理应用程序的免费和付费版本的 最佳方式。 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. EDIT许可似乎只允许付费应用(无赖),所以如果你想提供免费版本,这是不可取的。 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. 也许它对OP来说没问题,但我觉得不需要总是在用户的设备上安装两个应用程序是理想的。 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. 如果付费用户在新设备上安装该应用程序,则似乎可以下载先前的交易,因此他们无需支付两次。

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. 您可以使用一个文件(存储有MODE_PRIVATE),但我认为最简单的方法是使用SharedPreferences - 在付费应用中设置一个标志,该标志将由免费的应用程序读取。 See 看到 http://developer.android.com/guide/topics/data/data-storage.html . 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 ; 另见: 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. 在那个例子中,他们检查ZXing的条形码扫描仪是否可用。

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. 这是一个有趣的付费模式恕我直言。

What absolut distributing only a free/demo app and implement in-app to make it pro? 什么absolut只分发一个免费/演示应用程序并实现在应用程序中使其成为专业? 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. 因此,只有一个应用程序用户必须安装,他们可以测试基本功能,并将有一个按钮,如“升级到亲$ 1,99”,将调用应用程序内购买。

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. 将此与检查应用程序的开发人员签名(如@Fedor所述)相结合,您应该很高兴。

Apparently I cannot comment without 50 reputation, so I will put this in its own answer. 显然我没有50的声誉就不能发表评论,所以我会把它放在自己的答案中。

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. 其他人引用的PackageManager方法似乎是一种不错的简单方法,但正如hackbod所提到的,拥有两个已安装的应用程序对于用户而言是令人讨厌的(并且有点令人困惑)。

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. 但是 - 我还没试过这个,因为我还没有发布我的应用程序 - 看起来你可以保留一个以false开头的变量,然后如果发现安装了Pro版本则更新为true。 The variable would not revert to false just because the Pro version is not there. 该变量不会因为Pro版本不存在而恢复为false。 Then, you could let the user know in both versions that they need to install Pro, then open up the Trial and click Unlock. 然后,您可以让用户知道他们需要安装Pro的两个版本,然后打开试用版并单击解锁。 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. 完成此操作后,试用版将成为完整版,并通知您(如果找到安装的Pro版本),您现在可以卸载专业版,并且您将继续拥有完全访问权限。

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. 现在,这无法告诉您用户是否支付了Pro版本,然后在24小时内返回,因为hackbod也提到了。**但似乎这种情况可能不会经常发生。 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... **我想你可以保留一个时间戳与另一个变量,并要求用户保持Pro版本安装,直到该时间戳后的几个小时,然后允许他们卸载...

大多数应用程序开发人员采用的路线是只有一个版本的应用程序,但根据“许可证密钥”的存在启用(附加)或禁用(广告)功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何制作“免费”和“付费”的风味应用程序,购买付费版本会删除免费版本 - How can I make “free” and “paid” flavour apps, where buying the paid version deletes the free version 将我的免费应用程序链接到付费版本 - Linking my free app to the paid version 如何维护应用程序的付费和免费版本 - How to maintain a paid and free version of an app Google Analytics-区分我的应用程序的免费和付费版本 - Google Analytics - Distinguishing between the free and paid version of my app Android - 如何将我的免费应用程序链接到专业版 - Android - How can I link my free app to the Pro version 如何为Android应用付费和免费版本提供两种不同的功能 - How to approach two different functionality for android app paid and free version 将付费的Android应用与免费版本合并 - Merging a paid Android app with the free version 开发免费和付费版本的应用程序的正确方法 - Correct way to develope a free and paid version of an app 免费和付费版本共享首选项 - Free and paid version sharedpreferences 如何创建应用内购买从免费版升级到付费版android - How to create in-app purchase to upgrade from free version to paid version android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM