io.github.tjg1.nori.adapter.GoogleIAPHandler.java Source code

Java tutorial

Introduction

Here is the source code for io.github.tjg1.nori.adapter.GoogleIAPHandler.java

Source

/*
 * This file is part of nori.
 * Copyright (c) 2014-2016 Tomasz Jan Gralczyk <tomg@fastmail.uk>
 * License: GNU GPLv2
 */

package io.github.tjg1.nori.adapter;

import android.app.Activity;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.List;

import io.github.tjg1.nori.util.iab.IabHelper;
import io.github.tjg1.nori.util.iab.IabResult;
import io.github.tjg1.nori.util.iab.Inventory;
import io.github.tjg1.nori.util.iab.Purchase;

// This could be implemented as a fragment displaying the ListView and handling IAB functions.

/**
 * An adapter populating the ListView with available Google donation amounts and handling
 * interactions with the Google Play in-app purchase service.
 */
public class GoogleIAPHandler extends ArrayAdapter<Pair<String, String>>
        implements IabHelper.OnIabSetupFinishedListener, IabHelper.QueryInventoryFinishedListener,
        IabHelper.OnIabPurchaseFinishedListener, IabHelper.OnConsumeFinishedListener,
        AdapterView.OnItemClickListener {

    //region Instance fields
    /** List of item SKUs available for purchase. */
    protected final List<String> itemSkus;
    /** Listener handling user events and interactions with the Google IAP service. */
    protected final GoogleIAPHandler.Listener listener;
    /** Activity context the adapter is used in. */
    private final Activity activity;
    /** Google in-app purchase helper class. */
    private final IabHelper iabHelper;
    //endregion

    //region Constructors
    /**
     * Create a new object acting as a listener for {@link IabHelper} events and as an Adapter
     * for the donation amount {@link android.widget.ListView}.
     *
     * @param activity  Activity context.
     * @param iabHelper Google in-app purchase helper class.
     * @param itemSkus  List of item SKUs available for purchase.
     * @param resource  Layout resource used to display donation amounts.
     */
    public GoogleIAPHandler(@NonNull Activity activity, @NonNull IabHelper iabHelper, @LayoutRes int resource,
            @NonNull List<String> itemSkus, @NonNull Listener listener) {
        super(activity, resource);

        this.activity = activity;
        this.iabHelper = iabHelper;
        this.itemSkus = itemSkus;
        this.listener = listener;
    }
    //endregion

    //region ArrayAdapter<Pair<String, String>> methods
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Create the list view item.
        View view = convertView;

        if (view == null) {
            view = LayoutInflater.from(getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
        }

        // Get SKU details.
        Pair<String, String> skuPair = getItem(position);

        // Populate the views.
        TextView textView = (TextView) view.findViewById(android.R.id.text1);
        textView.setText(skuPair.second);

        return view;
    }
    //endregion

    //region IabHelper.OnIabSetupFinishedListener methods
    /**
     * Called to notify that setup is complete.
     *
     * @param result The result of the setup process.
     */
    @Override
    public void onIabSetupFinished(IabResult result) {
        if (result.isSuccess()) {
            if (iabHelper == null)
                return;

            try {
                // Query the prices of IAP items and display them in the ListView.
                iabHelper.queryInventoryAsync(true, itemSkus, null, this);
                return;
            } catch (IabHelper.IabAsyncInProgressException e) {
                listener.onPurchaseError(e);
                return;
            }
        }
        listener.onPurchaseError(null);
    }
    //endregion

    //region IabHelper.QueryInventoryFinishedListener methods
    /**
     * Called to notify that an inventory query operation completed.
     *
     * @param result The result of the operation.
     * @param inv    The inventory.
     */
    @Override
    public void onQueryInventoryFinished(IabResult result, Inventory inv) {
        if (result.isSuccess()) {
            if (iabHelper == null)
                return;
            // Populate adapter with SKU details.
            for (String sku : itemSkus) {
                if (inv.hasDetails(sku)) {
                    add(new Pair<>(sku, inv.getSkuDetails(sku).getPrice()));
                }
            }
            notifyDataSetChanged();
            return;
        }
        listener.onPurchaseError(null);
    }
    //endregion

    //region IabHelper.OnIabPurchaseFinishedListener methods
    /**
     * Called to notify that an in-app purchase finished. If the purchase was successful,
     * then the sku parameter specifies which item was purchased. If the purchase failed,
     * the sku and extraData parameters may or may not be null, depending on how far the purchase
     * process went.
     *
     * @param result The result of the purchase.
     * @param info   The purchase information (null if purchase failed)
     */
    @Override
    public void onIabPurchaseFinished(IabResult result, Purchase info) {
        if (iabHelper == null)
            return;

        if (result.isSuccess()) {
            // Consume the purchase, so that the user can donate multiple times.
            try {
                iabHelper.consumeAsync(info, this);
            } catch (IabHelper.IabAsyncInProgressException e) {
                e.printStackTrace();
            }

            listener.onPurchaseComplete(info);
        }
    }
    //endregion

    //region IabHelper.OnConsumeFinishedListener
    /**
     * Called to notify that a consumption has finished.
     *
     * @param purchase The purchase that was (or was to be) consumed.
     * @param result   The result of the consumption operation.
     */
    @Override
    public void onConsumeFinished(Purchase purchase, IabResult result) {
        // Do nothing.
    }
    //endregion

    //region AdapterView.OnItemClickListener methods
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
        final String sku = getItem(position).first;

        try {
            // Launch Google Play purchase flow.
            iabHelper.launchPurchaseFlow(activity, sku, 0, this);
        } catch (IabHelper.IabAsyncInProgressException e) {
            listener.onPurchaseError(e);
        }
    }
    //endregion

    //region Listener interface
    /** Interface used to handle user interaction with the ListView and purchase events. */
    public interface Listener {

        /**
         * Called when an error occurs while interacting with the Google in-app purchase service.
         *
         * @param error Error that occurred, can be null if not known.
         */
        public void onPurchaseError(@Nullable Exception error);

        /**
         * Called when the Google in-app purchase is completed.
         *
         * @param info Information about the purchase.
         */
        public void onPurchaseComplete(Purchase info);
    }
    //endregion
}