Android Open Source - capture-the-flag Purchase Premium Fragment






From Project

Back to project page capture-the-flag.

License

The source code is released under:

Copyright ? 2014 Microsoft Mobile Oy. All rights reserved. Microsoft is a registered trademark of Microsoft Corporation. Nokia and HERE are trademarks and/or registered trademarks of Nokia Corporati...

If you think the Android project capture-the-flag listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (c) 2014 Microsoft Mobile. All rights reserved.
 * See the license text file provided with this project for more information.
 *///  w  w  w .j  ava  2 s .  com

package com.nokia.example.capturetheflag;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.onepf.oms.OpenIabHelper;
import org.onepf.oms.appstore.googleUtils.IabHelper;
import org.onepf.oms.appstore.googleUtils.IabResult;
import org.onepf.oms.appstore.googleUtils.Inventory;
import org.onepf.oms.appstore.googleUtils.Purchase;
import org.onepf.oms.appstore.googleUtils.SkuDetails;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A fragment for upgrading the app to premium version.
 *
 * Uses the OpenIAB library to request product info and purchasing premium version.
 * @see <a href="https://github.com/onepf/OpenIAB">OpenIAB documentation</a>.
 */
public class PurchasePremiumFragment extends Fragment implements MainActivity.BackCallback {

    private static final String TAG = "CtF/PurchasePremiumFragment";

    public static final String FRAGMENT_TAG = "PurchasePremiumFragment";
    public static final int RC_REQUEST = 10001;

    // Nokia In-App Payment constants
    private static final String NOKIA_PREMIUM_PRODUCT_ID = "1023610"; // Test ID

    // Google In-App Billing constants
    private static final String Base64EncodedPublicKey = "INSERT_YOUR_PUBLIC_KEY_HERE";
    private static final String SKU_PREMIUM = "android.test.purchased";

    /**
     * SKU mappings
     */
    static {
        OpenIabHelper.mapSku(SKU_PREMIUM, OpenIabHelper.NAME_NOKIA, NOKIA_PREMIUM_PRODUCT_ID);
    }

    private OpenIabHelper mHelper;
    private boolean mIsPremium;
    private boolean mSetupDone = false;
    private String mDeveloperPayload;

    private TextView mTitleLine;
    private TextView mDescriptionLine;
    private TextView mPriceLine;
    private Button mBuyButton;

    private ProgressDialog mWaitScreen;

    /**
     * Callback for when setup is finished. See OpenIAB documentation for
     * details.
     */
    private IabHelper.OnIabSetupFinishedListener mSetupListener =
        new IabHelper.OnIabSetupFinishedListener() {
        
        @Override
        public void onIabSetupFinished(IabResult result) {
            if (!result.isSuccess()) {
                toast(getString(R.string.problem_setting_up_iap) + result);
                Log.e(TAG, "Problem setting up in-app billing: " + result);
            } else {
                Log.d(TAG, "Setup successful. Querying inventory.");
                mSetupDone = true;
                mWaitScreen = ProgressDialog.show(getActivity(), null, getText(R.string.fetching_product_info));

                // Query for already purchased items and SKU details for items what user can buy.
                List<String> skus = new ArrayList<String>();
                skus.add(SKU_PREMIUM);
                mHelper.queryInventoryAsync(true, skus, mGotInventoryListener);
            }
        }
    };

    /**
     * Callback for when inventory query is finished. See OpenIAB documentation for details.
     */
    private IabHelper.QueryInventoryFinishedListener mGotInventoryListener =
        new IabHelper.QueryInventoryFinishedListener() {
        
        public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
            if (result.isFailure()) {
                Log.d(TAG, "Failed to query inventory: " + result);
                toast(getString(R.string.failed_to_query_inventory, result));
                mTitleLine.setText(getString(R.string.failed_to_fetch_product_info));
            } else {
                Log.d(TAG, "Query inventory was successful.");
                SkuDetails premiumDetails = inventory.getSkuDetails(SKU_PREMIUM);
                
                if (premiumDetails != null) {
                    String title = premiumDetails.getTitle();
                    String description = premiumDetails.getDescription();
                    String price = premiumDetails.getPrice();
                    mTitleLine.setText(title);
                    mDescriptionLine.setText(description);
                    mPriceLine.setText(getString(R.string.upgrade_to_premium, price));
                } else {
                    mTitleLine.setText(getString(R.string.failed_to_fetch_product_info));
                }

                // Do we already have the premium upgrade purchased?
                Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM);
                mIsPremium = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase));
                Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));

                if (mIsPremium) {
                    purchased();
                }
            }
            
            dismissWaitScreen();
        }
    };

    /**
     * Callback for when a purchase is finished. See OpenIAB documentation for details.
     */
    private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener =
        new IabHelper.OnIabPurchaseFinishedListener() {
        
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
            Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
            
            if (result.isFailure()) {
                Log.d(TAG, "Error purchasing: " + result);
                alert(getString(R.string.error_purchasing, result));
            } else if (!verifyDeveloperPayload(purchase)) {
                alert(getString(R.string.error_purchasing,
                    getString(R.string.authenticity_verification_failed)));
            } else {
                Log.d(TAG, "Purchase successful.");

                if (purchase.getSku().equals(SKU_PREMIUM)) {
                    toast(getString(R.string.thank_you_for_purchasing));
                    mIsPremium = true;
                    purchased();
                }
            }
            
            dismissWaitScreen();
        }
    };

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        ((MainActivity) activity).setBackCallback(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.buy_premium_layout, container, false);
        mBuyButton = (Button) v.findViewById(R.id.buy_premium);

        mBuyButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                purchasePremium();
            }
        });

        mTitleLine = (TextView) v.findViewById(R.id.premium_title_line);
        mDescriptionLine = (TextView) v.findViewById(R.id.premium_description_line);
        mPriceLine = (TextView) v.findViewById(R.id.premium_price_line);

        mDeveloperPayload = "You_should_pass_in_a_string_token_that_helps_your_application_to_identify_the_user_who_made_the_purchase";

        if (Base64EncodedPublicKey.contains("INSERT_YOUR")) {
            mBuyButton.setEnabled(false);
            mTitleLine.setText(getString(R.string.failed_to_fetch_product_info));
            alert(getString(R.string.missing_iap_key, "PurchasePremiumFragment"));
        } else {
            Map<String, String> storeKeys = new HashMap<String, String>();
            storeKeys.put(OpenIabHelper.NAME_GOOGLE, Base64EncodedPublicKey);

            try {
                mHelper = new OpenIabHelper(getActivity(), storeKeys);
                mHelper.startSetup(mSetupListener);
            }
            catch (IllegalArgumentException e) {
                mBuyButton.setEnabled(false);
                mTitleLine.setText(getString(R.string.failed_to_fetch_product_info));
                alert(getString(R.string.invalid_iap_key, "PurchasePremiumFragment"));
            }
        }

        return v;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (mHelper != null) {
            mHelper.dispose();
            mHelper = null;
        }
    }

    @Override
    public void onBackPressed() {
        getFragmentManager().beginTransaction().remove(this).commit();
        ((MainActivity) getActivity()).setBackCallback(null);
    }

    /**
     * Dismisses the wait screen.
     */
    private void dismissWaitScreen() {
        mWaitScreen.dismiss();
        mWaitScreen = null;
    }

    /**
     * Updates the UI and unlocks the premium functionality when the purchase has been completed.
     */
    private void purchased() {
        mBuyButton.setText("Purchased");
        mBuyButton.setEnabled(false);
        Settings.setPremium(SKU_PREMIUM, getActivity());
        ((MainActivity) getActivity()).unlockPremium();
    }

    /**
     * Verifies the authenticity of 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.
     *
     * @param purchase The {@link org.onepf.oms.appstore.googleUtils.Purchase} to verify.
     * @return <code>true</code> if the payload was valid, <code>false</code> if not.
     */
    private boolean verifyDeveloperPayload(Purchase purchase) {
        String payload = purchase.getDeveloperPayload();

        return payload.equals(mDeveloperPayload);
    }

    /**
     * Initiates the purchase process for the premium product if not already purchased.
     */
    public void purchasePremium() {
        if (!mSetupDone) {
            toast(getString(R.string.billing_setup_not_complete_yet));
        } else {
            if (!mIsPremium) {
                mWaitScreen = ProgressDialog.show(getActivity(), null, getText(R.string.purchasing_product));
                mHelper.launchPurchaseFlow(getActivity(), SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener, mDeveloperPayload);
            } else {
                toast(getString(R.string.premium_already_purchased));
                mBuyButton.setEnabled(false);
            }
        }
    }

    /**
     * Handles an in-app purchase activity result with request code = PurchasePremiumFragment.RC_REQUEST.
     * Called from {@link com.nokia.example.capturetheflag.MainActivity#onActivityResult(int, int, android.content.Intent)}.
     *
     * @param requestCode The request code.
     * @param resultCode  The result code.
     * @param data The data.
     */
    public void handleActivityResult(int requestCode, int resultCode, Intent data) {
        mHelper.handleActivityResult(requestCode, resultCode, data);
    }

    /**
     * Creates and shows toast with the given text.
     *
     * @param message Text for the toast.
     */
    private void toast(String message) {
        Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();
    }

    /**
     * Creates and shows an alert dialog with the given text.
     *
     * @param message Text for the alert dialog.
     */
    private void alert(String message) {
        AlertDialog.Builder bld = new AlertDialog.Builder(getActivity());
        bld.setMessage(message);
        bld.setNeutralButton(getString(R.string.ok), null);
        bld.create().show();
    }
}




Java Source Code List

com.nokia.example.capturetheflag.AboutActivity.java
com.nokia.example.capturetheflag.Controller.java
com.nokia.example.capturetheflag.CreateGameFragment.java
com.nokia.example.capturetheflag.GameEndedDialogFragment.java
com.nokia.example.capturetheflag.GameMenuFragment.java
com.nokia.example.capturetheflag.HelpActivity.java
com.nokia.example.capturetheflag.JoinGameFragment.java
com.nokia.example.capturetheflag.MainActivity.java
com.nokia.example.capturetheflag.PauseDialog.java
com.nokia.example.capturetheflag.PurchasePremiumFragment.java
com.nokia.example.capturetheflag.ServerSettingsDialog.java
com.nokia.example.capturetheflag.Settings.java
com.nokia.example.capturetheflag.location.LocationManagerBase.java
com.nokia.example.capturetheflag.location.LocationManagerFactory.java
com.nokia.example.capturetheflag.location.LocationManagerInterface.java
com.nokia.example.capturetheflag.location.LocationManagerListener.java
com.nokia.example.capturetheflag.location.LocationUtils.java
com.nokia.example.capturetheflag.location.google.LocationManagerGoogle.java
com.nokia.example.capturetheflag.location.here.LocationManagerHere.java
com.nokia.example.capturetheflag.map.GameMapFactory.java
com.nokia.example.capturetheflag.map.GameMapInterface.java
com.nokia.example.capturetheflag.map.GameMapUtils.java
com.nokia.example.capturetheflag.map.MarkerFactoryBase.java
com.nokia.example.capturetheflag.map.google.GameMapGoogle.java
com.nokia.example.capturetheflag.map.google.MarkerFactoryGoogle.java
com.nokia.example.capturetheflag.map.here.GameMapHere.java
com.nokia.example.capturetheflag.map.here.MarkerFactoryHere.java
com.nokia.example.capturetheflag.network.FlagCapturedResponse.java
com.nokia.example.capturetheflag.network.GameListRequest.java
com.nokia.example.capturetheflag.network.GameListResponse.java
com.nokia.example.capturetheflag.network.JSONRequest.java
com.nokia.example.capturetheflag.network.JSONResponse.java
com.nokia.example.capturetheflag.network.JoinRequest.java
com.nokia.example.capturetheflag.network.JoinedResponse.java
com.nokia.example.capturetheflag.network.NetworkClient.java
com.nokia.example.capturetheflag.network.OfflineClient.java
com.nokia.example.capturetheflag.network.SocketIONetworkClient.java
com.nokia.example.capturetheflag.network.UpdatePlayerRequest.java
com.nokia.example.capturetheflag.network.UpdatePlayerResponse.java
com.nokia.example.capturetheflag.network.model.Flag.java
com.nokia.example.capturetheflag.network.model.Game.java
com.nokia.example.capturetheflag.network.model.ModelConstants.java
com.nokia.example.capturetheflag.network.model.Player.java
com.nokia.example.capturetheflag.notifications.NotificationsManagerBase.java
com.nokia.example.capturetheflag.notifications.NotificationsManagerFactory.java
com.nokia.example.capturetheflag.notifications.NotificationsManagerInterface.java
com.nokia.example.capturetheflag.notifications.NotificationsUtils.java
com.nokia.example.capturetheflag.notifications.google.GcmBroadcastReceiver.java
com.nokia.example.capturetheflag.notifications.google.GcmIntentService.java
com.nokia.example.capturetheflag.notifications.google.NotificationsManagerGoogle.java
com.nokia.example.capturetheflag.notifications.nokia.NokiaNotificationsBroadcastReceiver.java
com.nokia.example.capturetheflag.notifications.nokia.NokiaNotificationsIntentService.java
com.nokia.example.capturetheflag.notifications.nokia.NotificationsManagerNokia.java