针对初学者的应用内结算基础知识

时间:2014-09-28 10:39:43

标签: android actionscript-3 air in-app-billing ane

有些人可能会记得以前的问题。我正在构建一个适用于Android的应用程序,它运行良好。我想要的大部分功能都很棒。我自己学习了基础知识(在StackOverflow上有一些慷慨的人帮助!)但我仍然认为自己是初学者(今天的问题会向你展示我是多少初学者!)。

我的应用是一张动态地图,可显示某个国家/地区在特定时间点的历史记录。在Google Play上,用户可以免费下载基本应用程序(大多数是空的),然后他可以通过应用内结算购买包(法国,美国,英国等)。这就是我被困的地方。

我已经购买了Milkman AndroidIAB ANE并仔细阅读了文档(this one)。我设法将ANE添加到我的库并更新我的应用程序清单。我修改了示例文件以添加我的公钥和可购买包的ID。 (我不在这里发布代码,因为我不知道自从ANE获得许可后我是否被允许。)

我的应用就是这样:

  1. 第一个屏幕:带有网站链接和“回车”按钮的徽标。

  2. 点击后,用户会在屏幕上显示几个按钮(每个包/国家/地区一个)。

  3. 如果用户点击他拥有的包裹,他将被发送到所选国家/地区的地图。

  4. 如果他不拥有它,他会被问到是否愿意购买并发送购买。

  5. 问题:(警告:其中一些是值得当月的菜鸟状态,但我在这里学习正确吗?)

    1. 改编自Milkman示例的代码位于用作DocumentClass的外部.as文件中。如何将屏幕2按钮与.as文件中的函数链接? 我试过这个,但它不起作用:

      franceBtn.addEventListener(MouseEvent.CLICK, checkAndPurchase);
      function checkAndPurchase (e:MouseEvent):void{
          purchasePack1(); 
      //function from the example, it checks if the pack is owned 
      // and send the user to the store if not
      };
      
    2. 编辑1:这可能很容易,但我只是没有足够的经验来理解我需要做的事情。 我的应用程序中有一系列按钮(例如“franceBtn”,“usaBtn”和“ukBtn”)。单击这些按钮时,需要检查用户是否拥有该包(“francePack”,“usaPack”和“ukPack”),如果不是,请启动应用内购买。我试图在按钮上添加一个EventListener,但没有任何反应。不在屏幕上,不在日志中。

      2.让我们说问题1是固定的。我的应用程序是脱机使用的(除了购买额外的包)。我理解我读到的方式是,应用内购买包的“库存”是通过Google Play获得的,这意味着(如果我没记错的话)用户需要在线。有没有办法在设备内部创建某种存储此“库存”的文件,以便可以离线访问?

      编辑2:我希望用户能够在任何地方使用该应用程序,而无需联机(显然除了购买包)。但我想该应用程序会检查Google Play以了解哪些包已经拥有。所以我正在寻找一种方法来直接在设备/应用程序中存储自有包的“库存”(因此可以离线访问并在每次互联网启动时更新)。 我希望它更清楚,谢谢你指出它不是。

      我已经阅读了很多次的文档,而且我真的被卡住了,所以请,我真的很感激任何帮助。 ;)

      提前致谢, 杰里尔

      编辑3:这是我的代码中与IAB相关的部分(通过以下教程制作:here但我并不是真的理解它。我愿意学习但这是一个中级tuto ,我在互联网上找不到什么可以解释为真正的初学者做些什么。如果你有找不到的链接,我都会听到:D)

      import com.milkmangames.nativeextensions.android.*;
      import com.milkmangames.nativeextensions.android.events.*;
      import flash.events.MouseEvent;
      
      
      if (AndroidIAB.isSupported()) {
          AndroidIAB.create();
      }
      
      
      // listeners for billing service startup
      AndroidIAB.androidIAB.addEventListener(AndroidBillingEvent.SERVICE_READY, onReady);
      AndroidIAB.androidIAB.addEventListener(AndroidBillingEvent.SERVICE_NOT_SUPPORTED, onUnsupported);
      
      // start the service
      AndroidIAB.androidIAB.startBillingService("my_key");
      
      function onReady(e: AndroidBillingEvent): void {
          trace("service now ready- you can now make purchases.");
      
      }
      
      function onUnsupported(e: AndroidBillingEvent): void {
          trace("sorry, in app billing won't work on this phone!");
      
      }
      
      // listen for inventory events
      
      AndroidIAB.androidIAB.addEventListener(AndroidBillingEvent.INVENTORY_LOADED, onInventoryLoaded);
      AndroidIAB.androidIAB.addEventListener(AndroidBillingErrorEvent.LOAD_INVENTORY_FAILED, onInventoryFailed);
      
      function onInventoryLoaded(e: AndroidBillingEvent): void {
          for each(var purchase: AndroidPurchase in e.purchases) {
              trace("You own the item:" + purchase.itemId);
          }
      }
      
      function onInventoryFailed(e: AndroidBillingErrorEvent): void {
          trace("Something went wrong loading inventory: " + e.text);
      }
      
      // load the player's current inventory
      AndroidIAB.androidIAB.loadPlayerInventory();
      
      // listen for purchase events
      AndroidIAB.androidIAB.addEventListener(AndroidBillingEvent.PURCHASE_SUCCEEDED, onPurchaseSuccess);
      AndroidIAB.androidIAB.addEventListener(AndroidBillingErrorEvent.PURCHASE_FAILED, onPurchaseFailed);
      
      function onPurchaseSuccess(e: AndroidBillingEvent): void {
          var purchase: AndroidPurchase = e.purchases[0];
          trace("you purchased the item " + purchase.itemId);
          AndroidIAB.androidIAB.loadPlayerInventory();
      }
      
      function onPurchaseFailed(e: AndroidBillingErrorEvent): void {
          trace("Something went wrong with the purchase of " + e.itemId + ": " + e.text);
      }
      
      franceBtn.addEventListener(MouseEvent.CLICK, onPackOneButtonClicked);
      
      function onPackOneButtonClicked(e: MouseEvent) {
          if (purchase.itemId == "packone") {
              franceMap.visible = true;
          } else {
              AndroidIAB.androidIAB.purchaseItem("packone");
          }
      }
      

      感谢您的耐心等待!病毒Jeryl

1 个答案:

答案 0 :(得分:0)

在继续操作之前,我假设您已在Google Play的IAP部分正确设置了产品。

现在,对于你的第一个问题,我不确定这个问题,因为点击一个按钮,该事件应该开箱即用。你的代码应该是这样的:

(假设你有两个包,他们的itemIds是 com.yourcomapny.packOne com.yourcompany.packTwo

franceBtn.addEventListener( MouseEvent.CLICK, onPackOneButtonClicked );

function onPackOneButtonClicked( event:MouseEvent )
{
  if( !isPackOnePurchased() )
  {
    purchasePackOne();
  }
}

// Similarly for pack two

这是几乎相同的代码,您正在尝试编写。如果您可以发布一些无效的代码部分,也许我们可以帮助您解决更多问题。

对于你的第二部分,如果你想存储"库存"离线信息,您可以通过以下方式继续:

1)假设您创建了一个空文件。

2)假设一个人购买 com.yourcompany.packTwo 并且您收到了购买成功事件,您只需将 com.yourcompany.packTwo 添加到该文件中,从而将其标记为已购买。

3)每当你调用isPackOnePurchased或isPackTwoPurchased时,它会检查文件中是否存在相应的itemId,并决定是否需要购买此包或已经购买。

这将帮助您入门。增强用户体验和安全性的另一个方面是,无论何时用户点击按钮购买包(并且他/她连接到互联网),始终检查该包是否在库存中并根据该显示反馈。如果存在任何不一致,请始终将本地状态与库存同步。如果用户删除其应用程序数据然后尝试打开包,则可能会出现不一致。此检查将确保您的应用程序与服务器状态同步。

如果您想要下一级安全性,您可以加密信息(在这种情况下为项目ID)并将其存储为安全数据库。

可以使用多种加密方法进行加密。一种这样的方法是Rijndael encryption。您可以使用此工具this online tool为itemIds生成加密字符串。这会让你感受到我想说的话。

有关如何在基于AIR的应用程序中的本地数据库中存储信息,请参阅this link from Adobe