Integrating Google Play In-app Billing into an Android Application – A Tutorial

From Techotopia
Jump to: navigation, search
PreviousTable of Contents
Signing and Preparing an Android Application for Release


You are currently reading the Eclipse - Android 4.4 Edition of this book.

Purchase the fully updated Android Studio 2.3 / Android 7 Edition of this publication in eBook ($19.99) or Print ($45.99) format

Android Studio 2.3 Development Essentials - Android 7 Edition Print and eBook (ePub/PDF/Kindle) editions contain 77 chapters and over 810 pages

Buy eBook Buy Print Preview Book


In the early days of mobile applications for operating systems such as Android and iOS, the most common method for earning revenue was to charge an upfront fee to download and install the application. Another revenue opportunity was soon introduced in the form of embedding advertising within applications. Perhaps the most common and lucrative option is now to charge the user for purchasing items from within the application after it has been installed. This typically takes the form of access to a higher level in a game, acquiring virtual goods or currency, or subscribing to the digital edition of a magazine or newspaper.

Google provides support for the integration of in app purchasing through the Google Play In-App Billing API. The purpose of this chapter is to work through a tutorial that demonstrates the steps involved in implementing basic Google Play based in-app billing within an Android application.




Installing the Google Play Billing Library

A prerequisite to implementing Google Play In-app Billing is that the Google Play Billing Library be installed on the development system. Check whether or not the library is installed by launching the Android SDK Manager by selecting the Eclipse Window -> Android SDK Manager menu option. Once loaded, scroll down to the Extras section and the Status column next to the Google Play Billing Library entry as shown in Figure 53-1:


Installing the Google Play in App Billing library

Figure 53-1


If the library is listed as Not Installed, select the check box next to the library and click on the Install packages… button. Once the installation is complete, the library will have been installed in the following path (where <sdk path> represents the location of the Android SDK as installed in the chapter entitled Setting up an Android Development Environment):

<sdk path>/extras/google/play_billing

Within the above SDK folder resides a file named IInAppBillingService.aidl which will need to be included with any projects that require Google Play billing support. The folder also includes a sample application (contained within the samples sub-directory) named TrivialDrive. Part of this sample application is a package containing a set of convenience classes that significantly ease the process of integrating billing into an application. Later in this tutorial, these classes will be imported into our own application project and used to implement in-app billing.

Creating the Example In-app Billing Project

The objective of this tutorial is to create a simple application that uses the Google in-app billing system to allow consumable purchases to be made. The application will consist of two buttons, one of which will be disabled by default. In order to enable the button so that it can be clicked, the user must purchase a “button click” item by clicking on the second button and completing a purchase. The first button will then be enabled for a single click before being disabled again until the user makes another purchase.

Begin by launching Eclipse and selecting the File -> New - > Android Application Project menu option. Within the resulting New Android Application dialog, enter InAppBilling as both the application and project names. Declare a suitable package name, this time using a real URL (since this application will be uploaded to the Google Play Developer Console, the use of com.example as part of the package name is not possible in this case).

Set the SDK menus to the latest SDK available before clicking Next. On the subsequent screens simply accept the default settings until the Blank Activity screen appears at which point the activity should be named InAppBillingActivity with corresponding layout and fragment files named activity_in_app_billing and fragment_in_app_billing respectively.

Click on Finish to initiate the project creation process.


Adding Billing Permission to the Manifest File

Before an application can support in-app billing, a new permission line must be added to the project’s AndroidManifest.xml file. Within the Project Explorer panel, therefore, locate and load the AndroidManifest.xml file for the newly created InAppBilling project and modify it to add the billing permission as follows:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ebookfrenzy.inappbilling"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19" />

     <uses-permission android:name="com.android.vending.BILLING" />
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.ebookfrenzy.inappbilling.InAppBillingActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Adding the IInAppBillingService.aidl File to the Project

The IInAppBillingService.aidl file included as part of the Google Play Billing Library should now be added to the project. This file must be added such that it is contained in a package named com.android.vending.billing. To create this package, locate the InAppBilling project in the Project Explorer panel, right-click on it and select the New -> Package option from the resulting menu. In the New Java Package dialog (Figure 53-2) make sure that the Source folder: is set to InAppBilling/src before entering com.android.vending.billing into the Name: field.


Creating the com.android.vending.billing package

Figure 53-2


Click on the Finish button to create the new package, at which point it should be listed under the src folder in the Package Explorer. Using the file system browser for your operating system, locate the IInAppBillingService.aidl file in the SDK folder and drag and drop it onto the package in the Package Explorer panel, selecting the option to copy the file to the project. Once added, the src folder should match that of Figure 53-3:


The IInAppBillingService.aidl file added to the project

Figure 53-3


With the library file installed, the next step is to import the TrivialDrive sample project into Eclipse so that the utility classes can be added to our project.

Adding the Utility Classes to the Project

The TrivialDrive sample project that was installed into the SDK as part of the Google Play Billing library includes a set of classes intended specifically to make the task of implementing in-app billing easier. Although bundled as part of the TrivialDrive project, these classes are general purpose in nature and are applicable to most application billing requirements. For the purposes of this example, we will create a new package named <domainname>.inappbilling.util within our project, where <domainname> is the reverse URL of the domain you selected when the InAppBilling project was created previously in this chapter. To create this package, right-click on the src folder of the project in the Project Explorer panel and select the New -> Package menu option. In the resulting dialog, name the package and click on Finish. Once the new package has been created, locate it in the Package Manager panel.

The next step is to import the TrivialDrive project into the Eclipse workspace so that the utility classes can be copied into the project. To achieve this, select the Eclipse File -> Import menu option and choose Android -> Existing Android Code Into Workspace from the import dialog. Click Next > and on the subsequent screen, click on the Browse.. button and navigate to the TrivialDrive sample directory located at the following path:

<sdk path>/extras/google/play_billing/samples/TrivialDrive

Select the TrivialDrive folder before clicking on OK to return to the project import dialog. Select the option to Copy projects into workspace (Figure 53-4) before clicking on Finish to import the project.


Importing the TrivialDrive project

Figure 53-4


Once the package has been imported, locate it within the Project Explorer panel (it will be named MainActivity) and unfold the src folder to locate the Java files within the following package:

com.example.android.trivialdrivesample.util 

Select all nine Java files within this package and copy and paste them into the <domainname>.inappbilling.util package of our InAppBilling project. Once imported, the src folder of the package should appear as shown in Figure 53-5:


The utility methods added to the project

Figure 53-5

Designing the User Interface

The user interface, as previously outlined, is going to consist of two buttons, the first of which can only be clicked after a purchase has been made via a click performed on the second button. Double-click on the res -> layout -> fragment_in_app_billing.xml file to load it into the Graphical Layout tool and design the user interface so that it resembles that of Figure 53-6:


The example In App Billing application user interface layout

Figure 53-6


With the user interface layout designed, switch to the XML view and name the buttons clickButton and buyButton respectively. Also, set onClick properties to configure the buttons to call methods named buttonClicked and buyClick such that the completed XML layout file reads as follows:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".InAppBillingActivity" >

    <Button
        android:id="@+id/buyButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:onClick="buyClick"
        android:text="@string/buy_string" />

    <Button
        android:id="@+id/clickButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/buyButton"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="56dp"
        android:onClick="buttonClicked"
        android:text="@string/clickme_string" />

</RelativeLayout>

With the user interface design complete, it is time to start writing some Java code to handle the purchasing and consumption of clicks.

Implementing the “Click Me” Button

When the application is initially launched, the “Click Me!” button will be disabled. To make sure that this happens, load the InAppBillingActivity.java file into the editing panel and override the onStart method to obtain a reference to the button and disable it:

package com.ebookfrenzy.inappbilling;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.Button;

public class InAppBillingActivity extends Activity {

	private Button clickButton;
	private Button buyButton;
	
	@Override 
	protected void onStart() {
		super.onStart();
		buyButton = (Button)findViewById(R.id.buyButton);
		clickButton = (Button)findViewById(R.id.clickButton);	
		clickButton.setEnabled(false);
	}
.
.
.
}

The buttonClicked method that will be called when the button is clicked by the user now also needs to be implemented. All this method needs to do is to disable the button once again so that the button cannot be clicked again until another purchase is made and to enable the buy button so that another click can be purchased. Remaining within the InAppBillingActivity.java file, implement this method as follows:

public class InAppBillingActivity extends Activity {
.
.
.
	public void buttonClicked (View view)
	{
		clickButton.setEnabled(false);
		buyButton.setEnabled(true);
	}
.
.
}

Work on the functionality of the first button is now complete. The next steps are to begin implementing the in-app billing functionality.

Google Play Developer Console and Google Wallet Accounts

Each application developer making use of Google Play billing must be identified by a unique public license key. The only way to obtain a public license key is to register an application within the Google Play Developer Console. If you do not already have a Google Play Developer Console account, go to http://play.google.com/apps/publish and follow the steps to register as outlined in the chapter entitled Signing and Preparing an Android Application for Release.

Once you are logged in, click on the Settings option (represented by the cog icon on the left hand edge of the web page) and, on the Account details page, scroll down to the Merchant Account section. In order to use in-app billing, your Google Play Developer Console account must have a Google Wallet Merchant account associated with it. If a Google Wallet merchant account is not set up, create a merchant account and register it with your Google Developer Console account before proceeding.

Obtaining the Public License Key for the Application

From the home page of the Google Play Developer Console, click on the Add new application button, specifying the default language and a title of InAppBilling. Once this information has been entered, click on the Upload APK button:


Adding a new app to the Google Play Console

Figure 53-7


It is not necessary to upload the APK file at this point, so once the application has been registered, click on the Services & APIs option to display the Base64-encoded RSA public key for the application as shown in Figure 53-8:


The Google Play Console Services and APIs screen

Figure 53-8


Keep this Browser window open for now as this key will need to be included in the application code in the next step of this tutorial.

Setting Up Google Play Billing in the Application

With the public key generated, it is now time to use that key to initialize billing within the application code. For the InAppBilling example project this will be performed in the onCreate method of the InAppBillingActivity.java file and will make use of the IabHelper class from the utilities classes previously added to the project as follows. Note that <your license key here> should be replaced by your own license key generated in the previous section and <your domain> represents the domain you selected for the project when it was created:

package com.ebookfrenzy.inappbilling;

import <your domain>.inappbilling.util.IabHelper;
import <your domain>.inappbilling.util.IabResult;
import <your domain>.inappbilling.util.Inventory;
import <your domain>.inappbilling.util.Purchase;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.Button;
import android.content.Intent;
import android.util.Log;

public class InAppBillingActivity extends Activity {

	private static final String TAG = "<your domain>.inappbilling";
	IabHelper mHelper;
	
	private Button clickButton;
	private Button buyButton;
	
	@Override 
	protected void onStart() {
		super.onStart();
		buyButton = (Button)findViewById(R.id.buyButton);
		clickButton = (Button)findViewById(R.id.clickButton);	
		clickButton.setEnabled(false);
	
		String base64EncodedPublicKey = 
                                       "<your license key here>";
        
        	mHelper = new IabHelper(this, base64EncodedPublicKey);
        
        	mHelper.startSetup(new 
			IabHelper.OnIabSetupFinishedListener() {
        	   	 public void onIabSetupFinished(IabResult result) 
			 {
        	           if (!result.isSuccess()) {
        	             Log.d(TAG, "In-app Billing setup failed: " + 
					result);
        	           } else {             
        	      	     Log.d(TAG, "In-app Billing is set up OK");
		           }
        	         }
        	});
	} 
.
.
.
}

After implementing the above changes, compile and run the application on a physical Android device (Google Play Billing cannot be tested within an emulator session) and make sure that the “In-app Billing is set up OK” message appears in the LogCat output panel.

Initiating a Google Play In-app Billing Purchase

With access to the billing system initialized, we can now turn our attention to initiating a purchase when the user touches the Buy Click button in the user interface. This was previously configured to trigger a call to a method named buyClick which now needs to be implemented in the InAppBillingActivity.java file. In addition to initiating the purchase process in this method, it will also be necessary to implement an onActivityResult method and also a listener method to be called when the purchase has completed.

Begin by editing the InAppBillingActivity.java file and adding the code for the buyClick method so that it reads as follows:

.
.
.
public class InAppBillingActivity extends Activity {

	private static final String TAG = "com.example.inappbilling";
	IabHelper mHelper;
	static final String ITEM_SKU = "android.test.purchased";
.
.
.

	public void buyClick(View view) {
    	     mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001,   
     			   mPurchaseFinishedListener, "mypurchasetoken");
	}
.
.
.
}

Clearly, all this method needs to do is make a call to the launchPurchaseFlow method of our mHelper instance. The arguments passed through to the method are as follows:

  • A reference to the enclosing Activity instance from which the method is being called.
  • The SKU that identifies the product that is being purchased. In this instance we are going to use a standard SKU provided by Google for testing purposes. This SKU, referred to as a static response SKU, will always result in a successful purchase. Other testing SKUs available for use when testing purchasing functionality without making real purchases are android.test.cancelled, android.test.refunded and android.test.item_unavailable.
  • The request code which can be any positive integer value. When the purchase has completed, the onActivityResult method will be called and passed this integer along with the purchase response. This allows the method to identify which purchase process is returning and can be useful when the method needs to be able to handle purchasing for different items.
  • The listener method to be called when the purchase is complete.
  • The developer payload token string. This can be any string value and is used to identify the purchase. For the purposes of this example, this is set to “mypurchasetoken”.

Implementing the onActivityResult Method

When the purchasing process returns, it will call a method on the calling activity named onActivityResult, passing through as arguments the request code passed through to the launchPurchaseFlow method, a result code and intent data containing the purchase response.

This method needs to identify if it was called as a result of an in-app purchase request or some request unrelated to in-app billing. It does this by calling the handleActivityResult method of the mHelper instance and passing through the incoming arguments. If this is a purchase request the mHelper will handle it and return a true value. If this is not the result of a purchase, then the method needs to pass it up to the superclass to be handled. Bringing this together results in the following code:

@Override
protected void onActivityResult(int requestCode, int resultCode, 
     Intent data) 
{
      if (!mHelper.handleActivityResult(requestCode, 
              resultCode, data)) {     
    	super.onActivityResult(requestCode, resultCode, data);
      }
}

In the event that the onActivityResult method was called in response to an in-app billing purchase, a call will then be made to the listener method referenced in the call to the launchPurchaseFlow method (in this case a method named mPurchaseFinishedListener). The next task, therefore, is to implement this method.

Implementing the Purchase Finished Listener

The “purchase finished” listener must perform a number of different tasks. In the first instance, it must check to ensure that the purchase was successful. It then needs to check the SKU of the purchased item to make sure it matches the one specified in the purchase request. In the event of a successful purchase, the method will need to consume the purchase so that the user can purchase it again when another one is needed. If the purchase is not consumed, future attempts to purchase the item will fail stating that the item has already been purchased. Whilst this would be desired behavior if the user only needed to purchase the item once, clearly this is not the behavior required for consumable purchases. Finally, the method needs to enable the “Click Me!” button so that the user can perform the button click that was purchased.

Within the InAppBillingActivity.java file, implement this method as follows:

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener 
	= new IabHelper.OnIabPurchaseFinishedListener() {
	public void onIabPurchaseFinished(IabResult result, 
                    Purchase purchase) 
	{
	   if (result.isFailure()) {
	      // Handle error
	      return;
	 }      
	 else if (purchase.getSku().equals(ITEM_SKU)) {
	     consumeItem();
	    buyButton.setEnabled(false);
	}
	      
   }
};

As can be seen from the above code fragment, in the event that the purchase was successful, a method named consumeItem() will be called. Clearly, the next step is to implement this method.

Consuming the Purchased Item

In the documentation for Google Play In-app Billing, Google recommends that consumable items be consumed before providing the user with access to the purchased item. So far in this tutorial we have performed the purchase of the item but not yet consumed it. In the event of a successful purchase, the mPurchaseFinishedListener implementation has been configured to call a method name consumeItem(). It will be the responsibility of this method to query the billing system to make sure that the purchase has been made. This involves making a call to the queryInventoryAsync() method of the mHelper object. This task is performed asynchronously from the application’s main thread and a listener method called when the task is complete. If the item has been purchased, the listener will consume the item via a call to the consumeAsync() method of the mHelper object. Bringing these requirements together results in the following additions to the InAppBillingActivity.java file:

public void consumeItem() {
	mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
	
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener 
   = new IabHelper.QueryInventoryFinishedListener() {
	   public void onQueryInventoryFinished(IabResult result,
	      Inventory inventory) {

		   		   
	      if (result.isFailure()) {
		  // Handle failure
	      } else {
                 mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU), 
			mConsumeFinishedListener);
	      }
    }
};

As with the query, the consumption task is also performed asynchronously and, in this case, is configured to call a listener named mConsumeFinishedListener when completed. This listener now needs to be implemented such that it enables the “Click Me!” button after the item has been consumed in the billing system:

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
	  new IabHelper.OnConsumeFinishedListener() {
	   public void onConsumeFinished(Purchase purchase, 
             IabResult result) {

	 if (result.isSuccess()) {		    	 
	   	  clickButton.setEnabled(true);
	 } else {
	         // handle error
	 }
  }
};

Releasing the IabHelper Instance

Throughout this tutorial, much of the work has been performed by calling methods on an instance of the IabHelper utility class named mHelper. Now that the code to handle purchasing and subsequent consumption of a virtual item is complete, the last task is to make sure this object is released when the activity is destroyed. Remaining in the InAppBillingActivity.java file, override the onDestroy() activity lifecycle method as follows:

@Override
public void onDestroy() {
	super.onDestroy();
	if (mHelper != null) mHelper.dispose();
	mHelper = null;
}

Modifying the Security.java File

When an application is compiled and installed on a device from within Eclipse, it is built and executed in debug mode. When the application is complete it is then built in release mode and uploaded to the Google Play App Store as described in the chapter entitled Signing and Preparing an Android Application for Release.

As the InAppBilling application is currently configured, purchases are being made using the android.test.purchased static response SKU code. It is important to be aware that static response SKUs can only be used when running an application in debug mode. As will be outlined later, new in-app products must be created within the Google Play developer console before full testing can be performed in release mode.

The current version of the utility classes provided with the TrivialDrive example application include an added level of security that prevents purchases from being made without a valid signature key being returned from the Google Play billing server. A side effect of this change is that it prevents the code from functioning when using the static response SKU values. Before testing the application in debug mode, therefore, a few extra lines of code need to be added to the verifyPurchase() method in the Security.java file. Within the Eclipse Project Explorer panel, select the Security.java file located in the src -> <package name> -> inappbilling.util folder of the project to load it into the editing panel. Once loaded, locate and modify the verifyPurchase() method so that it reads as follows:

package com.ebookfrenzy.inappbilling.util;

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import <your domain>.inappbilling.BuildConfig;

import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
.
.
.
    public static boolean verifyPurchase(String base64PublicKey, 
          String signedData, String signature) {
        if (TextUtils.isEmpty(signedData) || 
                TextUtils.isEmpty(base64PublicKey) ||
                TextUtils.isEmpty(signature)) {
            Log.e(TAG, "Purchase verification failed: missing data.");
            if (BuildConfig.DEBUG) {
                return true;
            }
            return false;
        }

        PublicKey key = Security.generatePublicKey(base64PublicKey);
        return Security.verify(key, signedData, signature);
    }

This will ensure that when the application is running in debug mode the method does not report an error if the signature is missing when a static response SKU purchase is verified. By checking for debug mode in this code, we ensure that this security check will function as intended when the application is built in release mode.

Testing the In-app Billing Application

Compile and run the application on a physical Android device with Google Play support and click on the “Buy a Click” button. This should cause the Google Play purchase dialog to appear listing the test item as illustrated in Figure 53-9:


Making a sample purchase on an Android device using a Google test SKU

Figure 53-9


Click on the Buy button to simulate a purchase at which point a Payment Successful message (Figure 53-10) should appear after which it should be possible to click on the “Click Me!” button once.


A successful in app purchase

Figure 53-10


Having consumed the click, it will be necessary to purchase another click in order to once again enable the button.

Building a Release APK

Up until this point the example application created in this chapter has used a static response testing SKU provided by Google for early stage testing of in-app billing. The next step is to create a real in-app billing product SKU code for a virtual item and use this when testing the application. Before creating an in-app billing product, however, the application code needs to be changed slightly so that it uses a real SKU instead of the static response SKU. The product SKU that will be used in the remainder of this chapter will be named com.example.buttonclick, so edit the InAppBillingActivity.java file and modify the SKU reference accordingly:

public class InAppBillingActivity extends Activity {

	private static final String TAG = "com.ebookfrenzy.inappbilling";
	IabHelper mHelper;
	static final String ITEM_SKU = "android.test.purchased";
	static final String ITEM_SKU = "com.example.buttonclick";
	
	private Button clickButton;
	private Button buyButton;
.
.
.

Before any products can be created, a release APK file for the application must first be uploaded to the developer console. In order to prepare this release APK file for the InAppBilling application, follow the steps outlined in the chapter entitled Signing and Preparing an Android Application for Release. Once the APK file has been created, select the previously registered application from the list of applications in the Google Play Developer Console and, from the resulting screen, click on the APK link in the left hand panel. When prompted, upload the release APK file to the console.

Creating a New In-app Product

Once the APK file has been uploaded, select the In-app Products menu item from the left hand panel of the developer console to display the screen shown in Figure 53-11:


Configuring an In App Product in the Google Play Console

Figure 53-11


To add a new product, click on the Add new product button and, in the resulting panel, set the product type to Managed product and enter a Product ID (in this case com.example.buttonclick). Click on Continue and in the second screen enter a title, description and price for the item. Change the menu at the top of the page to Activate.

On returning to the In-app Products home screen, the new product should now be listed:


A new in app product listed in the Google Play Console

Figure 53-12


Adding In-app Billing Test Accounts

Unfortunately, Google will not allow developers to make test purchases from their own Google accounts. In order to test in-app billing from this point on, it will be necessary to setup other Google accounts as testing accounts. The users of these accounts must load your application onto their devices and make test purchases. To add a test user account, click on the Settings icon located on the left hand side of your Google Play Developer Console home screen and on the account details screen scroll down to the License Testing section. In the corresponding text box, enter the Gmail accounts for the users who will be performing the in-app testing on your behalf before saving the changes.

In the absence of real users willing to test your application, it is also possible to set up a new Google account for testing purposes. Simply create a new Gmail account that is not connected in any way with your existing Google account identity. Once the account has been created and added as a test account in the Google Play Developer Console, open the Settings application on the physical Android device, select Users from the list of options and, on the Users screen, click on the ADD USER button at the top of the screen. Enter the new Gmail account and password information to create the new user on the device. Return to the device lock screen and log into the device as the test user by selecting the appropriate icon at the bottom of the screen. Note that during the test purchase, it will be necessary to enter credit card information for the new user in order to be able to fully test the in-app billing implementation.

Once the user has been added as a test account, it will be necessary to load the previously generated release APK file onto the device. Begin by enabling the device for USB debugging by following the steps in the chapter entitled Testing Android Applications on a Physical Android Device with ADB. Once enabled, attach the device to the development system and remove any previous versions of the application from the device where <package name> is the full package name of the application (for example com.ebookfrenzy.inappbilling):

adb uninstall <package name>

Next, upload the release APK created earlier in this chapter by running the following command in a Terminal or Command Prompt window:

adb –d install /path/to/release/apkfile.apk

Once the application is installed, locate it amongst the applications on the device and launch it. As long as the application remains in draft status within the Google Play Developer console no charges will be incurred by the user whilst testing the in-app billing functionality of the application. Note that the Google Play dialog (Figure 53-13) now lists the product title and price as declared for the product in the Google Play Developer Console:


Making an in app purchase with a live account


Figure 53-13


Any test purchases made in this way will be listed within the developer’s Google Wallet account but will not be billed to the user performing the testing. Any transactions not cancelled manually within Google Wallet will be cancelled automatically after 14 days.

Resolving Problems with In-App Purchasing

Implementation of Google Play in-app purchasing is a multi-step process where even the simplest of mistakes can lead to unsuccessful and confusing results. There are, however, a number of steps that can be taken to identify and resolve issues.

If in-app purchasing is not working, the first step is to ensure that the license key in the Google Play developer console matches that contained in the application code. If the key is not an exact match, purchase attempts will fail.

When testing it is also important to keep in mind that static response SKU codes only work when the application is running in debug mode. Similarly, real SKU product codes created in the developer console can only be purchased from within a release version of the application running under an account that has been authorized from within the developer console. This account must not be the same as that of the application developer registered with the Google Play developer console.

If problems persist, check the output on the Eclipse LogCat panel while the application is running in debug mode. The in-app purchase utility classes provide useful feedback in most failure situations. The level of diagnositic detail can be increased by adding the following line of code to the in-app billing initialization sequence:

mHelper.enableDebugLogging(true, TAG);  

For example:

mHelper.startSetup(new 
	IabHelper.OnIabSetupFinishedListener() {
      	  public void onIabSetupFinished(IabResult result) 
	  {
    	       if (!result.isSuccess()) {
    	          Log.d(TAG, "In-app Billing setup failed: " + 
				result);
         } else {             
    	      	    Log.d(TAG, "In-app Billing is set up OK");
    	      	    mHelper.enableDebugLogging(true, TAG);
	  }
   }
  });
}

Finally, it is not unusual for the developer to find that code that worked in debug mode using static responses fails when in release mode with real SKU values. In this situation, the LogCat output from the running release mode application can be viewed in real-time by connecting the device to the development computer and running the following adb command in a terminal or command prompt window:

adb logcat

Generally, the diagnostic messages will provide a good starting point to identify potential causes of most failures.

Summary

The Google Play In-app Billing API provides a mechanism by which users can be charged for virtual goods or services from within applications. In-app products can be configured to be subscription based, one-time purchase only, or consumable (in that the item needs to re-purchased after it is used within the application).

This chapter worked through the steps involved in preparing for and implementing Google Play in-app billing within an Android application.


You are currently reading the Eclipse - Android 4.4 Edition of this book.

Purchase the fully updated Android Studio 2.3 / Android 7 Edition of this publication in eBook ($19.99) or Print ($45.99) format

Android Studio 2.3 Development Essentials - Android 7 Edition Print and eBook (ePub/PDF/Kindle) editions contain 77 chapters and over 810 pages

Buy eBook Buy Print Preview Book



PreviousTable of Contents
Signing and Preparing an Android Application for Release