Codename One tries to make the lives of software developers easier by integrating several forms of built-in monetization solutions such as ad network support, in-app-purchase etc.

A lot of the monetization options are available as 3rd party cn1lib’s that you can install thru the Codename One website.

Google Play Ads

The most effective network is the simplest banner ad support. To enable mobile ads just create an ad unit in Admob’s website, you should end up with the key similar to this:

ca-app-pub-8610616152754010/3413603324

To enable this for Android just define the android.googleAdUnitId=ca-app-pub-8610616152754010/3413603324 in the build arguments and for iOS use the same as in ios.googleAdUnitId. The rest is seamless, the right ad will be created for you at the bottom of the screen and the form should automatically shrink to fit the ad. This shrinking is implemented differently between iOS and Android due to some constraints but the result should be similar and this should work reasonably well with device rotation as well.

Google play ads
Figure 1. Google play ads

There’s a special ad unit id to use for test ads. If you specify ca-app-pub-3940256099942544/6300978111, you’ll get test ads for your development phase. This is important because you’re not allowed to click on your own ads. When it’s time to create a production release, you should replace this with the real value you generated in adMob.

In App Purchase

Codename One’s in app purchase API’s try to generalize 3 different concepts for purchase:

  1. Google’s in app purchase

  2. Apple’s in app purchase

  3. Mobile payments for physical goods

While all 3 approaches end up with the developer getting paid, all 3 take a different approach to the same idea. Google and Apple work with “products” which you can define and buy through their respective stores. You need to define the product in the development environment and then send the user to purchase said product.

Once the product is purchased you receive an event that the purchase was completed and you can act appropriately. On the other hand mobile payments are just a transfer of a sum of money.

Both Google’s and Apple’s stores prohibit the sale of physical goods via the stores, so a mobile payment system needs to be used for those cases. This is where the similarity ends between the Google & Apple approach. Google expects developers to build their own storefront and provides developers with an API to extract the data in order to construct said storefront. Apple expects the developers to open its storefront to perform everything.

We tried to encode all 3 approaches into the purchase API which means you would need to handle all 3 cases when working. Unfortunately these things are very hard to simulate and can only be properly tested on the device.

So to organize the above we have:

  1. Managed payments - payments are handled by the platform. We essentially buy an item not transfer money (in app purchase).

  2. Manual payments - we transfer money, there are no items involved.

final Purchase p = Purchase.getInAppPurchase();

if(p != null) {
    if(p.isManualPaymentSupported()) {
        purchaseDemo.addComponent(new Label("Manual Payment Mode"));
        final TextField tf = new TextField("100");
        tf.setHint("Send us money, thanks");
        Button sendMoney = new Button("Send Us Money");
        sendMoney.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                p.pay(Double.parseDouble(tf.getText()), "USD");
            }
        });
        purchaseDemo.addComponent(tf);
        purchaseDemo.addComponent(sendMoney);
    }
    if(p.isManagedPaymentSupported()) {
        purchaseDemo.addComponent(new Label("Managed Payment Mode"));
        for(int iter = 0 ; iter < ITEM_NAMES.length ; iter++) {
            Button buy = new Button(ITEM_NAMES[iter]);
            final String id = ITEM_IDS[iter];
            buy.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    p.purchase(id);
                }
            });
            purchaseDemo.addComponent(buy);
        }
    }
} else {
    purchaseDemo.addComponent(new Label("Payment unsupported on this device"));
}

The item names in the demo code above should be hard coded and added to the appropriate stores inventory. Which is a very platform specific process for iTunes and Google play. Once this is done you should be able to issue a purchase request either in the real or the sandbox store.