在Codename中测试应用程序内购买一个模拟器导致空指针异常 [英] Test In-App-Purchase in Codename One simulator results in Null Pointer Exception

查看:139
本文介绍了在Codename中测试应用程序内购买一个模拟器导致空指针异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我决定采用免费增值方式,并提供一个从灯光升级到完整版本的按钮,而不是创建我的应用程序的灯光和完整版本。

Instead of creating a light and a full version of my app, I decided to go the freemium way and offer a button to upgrade from the light to the full version.

该应用程序仅适用于Google Play商店。所以我在Play商店中创建了一个应用内购买,如 http://mobilecodetogo.blogspot.fr/2013/03/android-does-it-better-in-app-purchase.html

The application is only available on the Google Play Store. So I created an in app purchase in the Play Store as described http://mobilecodetogo.blogspot.fr/2013/03/android-does-it-better-in-app-purchase.html.

以下是我实施的代码:

if (buyFull) {

              if (ParametresGeneraux.getPurchase().isManagedPaymentSupported()) {
                  String[] skus = {"ParametresGeneraux.getFullVersionSKU()"};

                   if (ParametresGeneraux.getPurchase().isItemListingSupported()) {
                     Product[] products = ParametresGeneraux.getPurchase().getProducts(skus);
                     String items = "";

                     if (products != null) {
                       for (Product p : products) {
                          items += p.getDescription();
                       }
                     }

                     Dialog.show("Produits intégrés", "Les produits intégrés sont " + items,
                                                         "OK", "Cancel");
                 }

                 // On achète
                 ParametresGeneraux.getPurchase().purchase("ParametresGeneraux.getFullVersionSKU()");
           } else {
                   Dialog.show("Évolution impossible", "Impossible d'évoluer vers la version complète. Votre compte n'a pas été débité.", "OK", "Compris");
                  }

其中 ParametresGeneraux.getPurchase()正在执行 Purchase.getInAppPurchase()

当我在带有Android皮肤(Nexus 5)的模拟器上测试时,列表未显示,并且在执行购买后它总是导致空指针异常:

When I test it on the simulator with an Android skin (Nexus 5) the listing is not shown and it always results in a null pointer exception after executing the purchase :

java.lang.NullPointerException
at com.codename1.impl.javase.JavaSEPort$82$5$1.run(JavaSEPort.java:7936)
at com.codename1.ui.Display.processSerialCalls(Display.java:1152)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1096)
at com.codename1.ui.Display.mainEDTLoop(Display.java:997)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)

相反,在提交应用程序几小时后设备上,购买是收费的(所以找到项目,而不是空)。但是,当我重新启动应用程序时,它仍处于轻型版本。

On the contrary on the device few hours after submitting the app, the purchase is charged (so item is found and not null). However when I restart the app it is still in light version.

以下是我如何测试它是否是轻型版本(在主类的init方法中):

Here is how I test if it is a light version (in the init method from the main class) :

    ParametresGeneraux.setPurchase(Purchase.getInAppPurchase());
    ParametresGeneraux.setLightVersion(true);
    if (ParametresGeneraux.getPurchase().isManagedPaymentSupported()) {
        if (ParametresGeneraux.getPurchase().wasPurchased(ParametresGeneraux.getFullVersionSKU())) {
            ParametresGeneraux.setLightVersion(false);
        }
    } 

根据这个2014 SO 问题(以及之后关闭的RFE) )我假设 wasPurchased 也适用于Android。所以我不知道为什么它不起作用。

According to this 2014 SO question (and the mentioned RFE that has been closed since then) I assume wasPurchased should also work on Android. So I don't know why it does not work.

其实我的问题是:

是否有可能用模拟器测试应用程序购买?

Is it possible to test in app purchase with the simulator ?

wasPurchased 选择正确的方法检查用户是否已经买了这个功能?

Is wasPurchased the right method to pick up to check whether the user has bought the feature ?

非常感谢你给我一些提示!

Thanks a lot for giving me hints!

推荐答案

因此,为了摆脱在模拟器中返回buy()方法后出现的NPE,主类必须实现PurchaseCallback接口 !!!

So to get rid of the NPE that appears right after the purchase() method returns in the simulator, the main class MUST implement PurchaseCallback interface!!!

Main CN1类是具有start()和init()方法的类,而不是状态机,如[Shai] [2]所示。这是一个至关重要的部分,应该在[购买教程] [3]中强调,尽管这在API文档中写得很好:

The Main CN1 class is the one with the start() and init() methods not the state machine as [indicated by Shai][2]. This is a crucial part and should be stressed in the [Purchase tutorial][3] although this is well written in the API documentation :


public interface PurchaseCallback
主类必须实现的回调接口才能使应用内购买工作。一旦主类实现此接口,就会调用其中的方法来指示各种购买状态。

public interface PurchaseCallback Callback interface that the main class must implement in order for in-app-purchasing to work. Once the main class implements this interface the methods within it are invoked to indicate the various purchase states.

现在 purchase()返回时,将调用PurchasePallchased()来自PurchaseCallback实现的方法。模拟器在CN1InAppPurchases文件(Linux上的.cn1文件夹)中跟踪购买情况。

Now the itemPurchased() method from the PurchaseCallback implementation gets called when the after purchase() returns. And the simulator keeps track of the purchase in the CN1InAppPurchases file (.cn1 folder on Linux).

此外,现在已经实现了PurchaseCallback,模拟器中的 (但不在Android设备上) wasPurchased()方法返回预期值,具体取决于先前的purchase()调用是否成功。

Furthermore now that the PurchaseCallback has been implemented, in the simulator (not on the Android device however) the wasPurchased() method returns the expected value depending on whether or not a previous purchase() call succeeded.

这篇关于在Codename中测试应用程序内购买一个模拟器导致空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆