com.ubiLive.GameCloud.payment.GoogleBillingActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.ubiLive.GameCloud.payment.GoogleBillingActivity.java

Source

package com.ubiLive.GameCloud.payment;

import java.util.HashMap;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Window;

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

import com.ubiLive.GameCloud.CloudGamePlayer;
import com.ubiLive.GameCloud.Constants;
import com.ubiLive.GameCloud.DebugLog;
import com.ubiLive.GameCloud.Browser.WebBrowser;
import com.ubiLive.GameCloud.googlepurchaseutil.IabHelper;
import com.ubiLive.GameCloud.googlepurchaseutil.IabResult;
import com.ubiLive.GameCloud.googlepurchaseutil.Inventory;
import com.ubiLive.GameCloud.googlepurchaseutil.Purchase;

/**
 *   This activity performs the purchase of a new level 
 *   At first we access the server to get the available In App items - each In App item correlates to a game level;
 *   Then we go through the In App items and find the level that the user is about to purchase.
 *   Lastly, we get the offer for this level and perform the purchase.
 */
public class GoogleBillingActivity extends Activity {

    protected final static String TAG = GoogleBillingActivity.class.getName();
    private IabHelper mHelper;
    private String mJsonData;
    private String mProductIdStr;
    // (arbitrary) request code for the purchase flow
    static final int RC_REQUEST = 10001;
    private HashMap<String, GooglePurchaseInfo> mGooglePurchaseMap = new HashMap<String, GooglePurchaseInfo>();
    private GooglePurchaseInfo mGooglePurchaseInfo;
    public static String mStrId;//session ID for the server requestion ->  client response (each times)

    private class GooglePurchaseInfo {
        public String idStr;
        public String packageNameStr;
        public String productIdStr;
        public String developerPayloadStr;
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        /*refer to
         * Webview client google play in-app purchase spec
         * http://wiki.ubitus.net/pages/viewpage.action?pageId=32640257
         * {
         *   "id": "zkvkjxklrwekrejw"
         *   "type": "set",
         *   "google": {
         *       "packageName": "devils",
         *       "productId": "product_id",
         *       "purchaseType": "inapp",
         *       "developerPayload": "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ"
         *   }
         * }
         */
        String base64EncodedPublicKey = "DUMMY_BILLING_PUBLICKEY";
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        Bundle bundleData = getIntent().getExtras();
        if (CloudGamePlayer.sWebBrowser.getBillingStatus() == Constants.BILLING_STATUS_START) {
            DebugLog.d(TAG, "GoogleBillingActivity.onCreate() line50");
            //finish();
            return;
        }

        mJsonData = bundleData.getString("jsonData");
        DebugLog.d(TAG, "BillingActivity.onCreate() mJsonData=" + mJsonData);
        // compute your public key and store it in base64EncodedPublicKey
        mHelper = new IabHelper(this, base64EncodedPublicKey);

        JSONObject json;
        try {
            json = new JSONObject(mJsonData);
            mStrId = json.getString("id");
            GooglePurchaseInfo googlePurchaseInfo = new GooglePurchaseInfo();
            googlePurchaseInfo.idStr = json.optString("id");
            googlePurchaseInfo.packageNameStr = json.optString("packageName");
            googlePurchaseInfo.productIdStr = json.optString("productId");
            googlePurchaseInfo.developerPayloadStr = json.optString("developerPayload");
            mGooglePurchaseMap.put(googlePurchaseInfo.productIdStr, googlePurchaseInfo);

            mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
                public void onIabSetupFinished(final IabResult result) {
                    DebugLog.d(TAG, "Setup finished.");

                    if (!result.isSuccess()) {
                        // Oh noes, there was a problem.
                        //                             complain("Problem setting up in-app billing: " + result);
                        return;
                    }

                    // Have we been disposed of in the meantime? If so, quit.
                    if (mHelper == null)
                        return;

                    // IAB is fully set up. Now, let's get an inventory of stuff we own.
                    DebugLog.d(TAG, "Setup successful. Querying inventory.");
                    mHelper.queryInventoryAsync(mGotInventoryListener);
                }
            });

            processGooglePurchase(googlePurchaseInfo.productIdStr);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            DebugLog.d(TAG, "exception = " + e.getMessage());
            finish();
        }
        CloudGamePlayer.sWebBrowser.setBillingStatus(Constants.BILLING_STATUS_START);
        DebugLog.d(TAG, "GoogleBillingActivity() leave ");
    }

    public void onDestroy() {
        super.onDestroy();
        if (mHelper != null) {
            mHelper.dispose();
            mHelper = null;
        }
        DebugLog.d(TAG, "GoogleBillingActivity() - shutting down license service");

    }

    // Listener that's called when we finish querying the items and subscriptions we own
    IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
        public void onQueryInventoryFinished(final IabResult result, final Inventory inventory) {
            DebugLog.d(TAG, "Query inventory finished.");

            // Have we been disposed of in the meantime? If so, quit.
            if (mHelper == null)
                return;

            // Is it a failure?
            if (result.isFailure()) {
                //                complain("Failed to query inventory: " + result);
                return;
            }

            DebugLog.d(TAG, "Query inventory was successful.");

            /*
             * Check for items we own. Notice that for each purchase, we check
             * the developer payload to see if it's correct! See
             * verifyDeveloperPayload().
             */

        }

    };

    private void processGooglePurchase(String productIdStr) {
        mGooglePurchaseInfo = mGooglePurchaseMap.get(productIdStr);
        String result;
        DebugLog.d(TAG, "processGooglePurchase() productIdStr = " + productIdStr);
        if (mGooglePurchaseInfo != null) {
            // TODO Auto-generated method stub
            DebugLog.d(TAG, "processGooglePurchase() to call launchPurchaseFlow()");
            if (mHelper != null) {
                mHelper.launchPurchaseFlow(this, mGooglePurchaseInfo.productIdStr, RC_REQUEST,
                        mPurchaseFinishedListener, mGooglePurchaseInfo.developerPayloadStr);
            }
        } else {
            result = "{" + "\"code\": \"" + Constants.RESPONSE_500
                    + "\",\"message\": \" player internal error(500) \"}";

            CloudGamePlayer.sWebBrowser.ubiGCPlayerCallback("googlePurchase", result);
        }

    }

    // Callback for when a purchase is finished
    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
            DebugLog.d(TAG, "onIabPurchaseFinished() Purchase finished: " + result + ", purchase: " + purchase);
            if (mHelper == null) {
                finish();
                return;
            }

            if (result.isFailure()) {
                //                complain("Error purchasing: " + result);
                //                setWaitScreen(false);
                String resultStr = "{" + "\"code\": \"" + Constants.RESPONSE_500
                        + "\",\"message\": \" player internal error(500) \"}";

                CloudGamePlayer.sWebBrowser.ubiGCPlayerCallback("googlePurchase", resultStr);
                finish();
                return;
            }
            if (!verifyDeveloperPayload(purchase)) {
                //                complain("Error purchasing. Authenticity verification failed.");
                //                setWaitScreen(false);
                String resultStr = "{" + "\"code\": \"" + Constants.RESPONSE_500
                        + "\",\"message\": \" player internal error(500) \"}";

                CloudGamePlayer.sWebBrowser.ubiGCPlayerCallback("googlePurchase", resultStr);
                finish();
                return;
            }

            GooglePurchaseInfo googlePurchaseInfo = mGooglePurchaseMap.get(purchase.getSku());
            String resultStr;
            if (googlePurchaseInfo != null) {
                DebugLog.d(TAG, "onIabPurchaseFinished() Purchase successful.");
                /**
                 * 
                 *   {
                 *       "id": "zkvkjxklrwekrejw"
                 *       "type": "result",
                 *      "code": "200",
                 *       "google": { 
                 *           "orderId":"12999763169054705758.1371079406387615", 
                 *           "packageName":"com.example.app",
                 *           "productId":"exampleSku",
                 *           "purchaseTime":1345678900000,
                 *           "purchaseState":0,
                 *           "developerPayload":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
                 *           "purchaseToken":"rojeslcdyyiapnqcynkjyyjh"
                 *       } 
                 *   }
                 */
                resultStr = "{" + "\"id\": \"" + googlePurchaseInfo.idStr + "\"," + "\"type\": \"result\","
                        + "\"code\": \"" + Constants.RESPONSE_200 + "\"," + "\"google\": {\"orderId\": \""
                        + purchase.getOrderId() + "\"," + "\"packageName\": \"" + purchase.getPackageName() + "\","
                        + "\"productId\": \"" + purchase.getSku() + "\"," + "\"purchaseTime\": "
                        + purchase.getPurchaseTime() + "," + "\"purchaseState\": " + purchase.getPurchaseState()
                        + "," + "\"developerPayload\": \"" + purchase.getDeveloperPayload() + "\","
                        + "\"purchaseToken\": \"" + purchase.getToken() + "\"," + "}}";

                mGooglePurchaseMap.remove(purchase.getSku());

            } else {
                resultStr = "{" + "\"code\": \"" + Constants.RESPONSE_500
                        + "\",\"message\": \" player internal error(500) \"}";
            }
            CloudGamePlayer.sWebBrowser.ubiGCPlayerCallback("googlePurchase", resultStr);
            CloudGamePlayer.sWebBrowser.setBillingStatus(Constants.BILLING_STATUS_END);
            WebBrowser.sIsBillingTriggered = false;
            finish();
            //            if (purchase.getSku().equals(SKU_GAS)) {
            //                // bought 1/4 tank of gas. So consume it.
            //                DebugLog.d(TAG, "Purchase is gas. Starting gas consumption.");
            //                helper.consumeAsync(purchase, mConsumeFinishedListener);
            //            }
            //            else if (purchase.getSku().equals(SKU_PREMIUM)) {
            //                // bought the premium upgrade!
            //                DebugLog.d(TAG, "Purchase is premium upgrade. Congratulating user.");
            //                alert("Thank you for upgrading to premium!");
            //                mIsPremium = true;
            //                updateUi();
            //                setWaitScreen(false);
            //            }
            //            else if (purchase.getSku().equals(SKU_INFINITE_GAS)) {
            //                // bought the infinite gas subscription
            //                DebugLog.d(TAG, "Infinite gas subscription purchased.");
            //                alert("Thank you for subscribing to infinite gas!");
            //                mSubscribedToInfiniteGas = true;
            //                mTank = TANK_MAX;
            //                updateUi();
            //                setWaitScreen(false);
            //            }
        }
    };

    /** Verifies the developer payload of a purchase. */
    boolean verifyDeveloperPayload(Purchase p) {
        String payload = p.getDeveloperPayload();

        /*
         * TODO: verify that the developer payload of the purchase is correct. It will be
         * the same one that you sent when initiating the purchase.
         *
         * WARNING: Locally generating a random string when starting a purchase and
         * verifying it here might seem like a good approach, but this will fail in the
         * case where the user purchases an item on one device and then uses your app on
         * a different device, because on the other device you will not have access to the
         * random string you originally generated.
         *
         * So a good developer payload has these characteristics:
         *
         * 1. If two different users purchase an item, the payload is different between them,
         *    so that one user's purchase can't be replayed to another user.
         *
         * 2. The payload must be such that you can verify it even when the app wasn't the
         *    one who initiated the purchase flow (so that items purchased by the user on
         *    one device work on other devices owned by the user).
         *
         * Using your own server to store and verify developer payloads across app
         * installations is recommended.
         */

        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        DebugLog.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
        if (mHelper == null)
            return;

        // Pass on the activity result to the helper for handling
        if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
            // not handled, so handle it ourselves (here's where you'd
            // perform any handling of activity results not related to in-app
            // billing...
            super.onActivityResult(requestCode, resultCode, data);
        } else {
            DebugLog.d(TAG, "onActivityResult handled by IABUtil.");
        }
    }

    // Called when consumption is complete
    IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
        public void onConsumeFinished(Purchase purchase, IabResult result) {
            DebugLog.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);

            // if we were disposed of in the meantime, quit.
            if (mHelper == null)
                return;

            // We know this is the "gas" sku because it's the only one we consume,
            // so we don't check which sku was consumed. If you have more than one
            // sku, you probably should check...
            if (result.isSuccess()) {
                // successfully consumed, so we apply the effects of the item in our
                // game world's logic, which in our case means filling the gas tank a bit
                DebugLog.d(TAG, "Consumption successful. Provisioning.");
                //                mTank = mTank == TANK_MAX ? TANK_MAX : mTank + 1;
                //                saveData();
                //                alert("You filled 1/4 tank. Your tank is now " + String.valueOf(mTank) + "/4 full!");
            } else {
                //                complain("Error while consuming: " + result);
            }
            //            updateUi();
            //            setWaitScreen(false);
            DebugLog.d(TAG, "End consumption flow.");
        }
    };
}