eu.vranckaert.worktime.utils.donations.DonationsFragment.java Source code

Java tutorial

Introduction

Here is the source code for eu.vranckaert.worktime.utils.donations.DonationsFragment.java

Source

/*
 * Copyright 2013 Dirk Vranckaert
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.vranckaert.worktime.utils.donations;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.webkit.WebView;
import android.webkit.WebView.HitTestResult;
import android.webkit.WebViewClient;
import android.widget.*;
import eu.vranckaert.worktime.R;
import eu.vranckaert.worktime.utils.donations.google.BillingService;
import eu.vranckaert.worktime.utils.donations.google.BillingService.RequestPurchase;
import eu.vranckaert.worktime.utils.donations.google.BillingService.RestoreTransactions;
import eu.vranckaert.worktime.utils.donations.google.Consts;
import eu.vranckaert.worktime.utils.donations.google.Consts.PurchaseState;
import eu.vranckaert.worktime.utils.donations.google.Consts.ResponseCode;
import eu.vranckaert.worktime.utils.donations.google.PurchaseObserver;
import eu.vranckaert.worktime.utils.donations.google.ResponseHandler;

public class DonationsFragment extends Fragment {
    private DonatePurchaseObserver mDonatePurchaseObserver;
    private Handler mHandler;

    private Spinner mGoogleSpinner;
    private TextView mFlattrUrl;

    private BillingService mBillingService;

    private static final int DIALOG_BILLING_NOT_SUPPORTED_ID = 1;
    private static final int DIALOG_THANKS = 2;

    /** An array of product list entries for the products that can be purchased. */
    private static String[] CATALOG;

    private static final String[] CATALOG_DEBUG = new String[] { "android.test.purchased", "android.test.canceled",
            "android.test.refunded", "android.test.item_unavailable" };

    private boolean mGoogleEnabled;

    /**
     * A {@link PurchaseObserver} is used to get callbacks when Android Market sends messages to
     * this application so that we can update the UI.
     */
    private class DonatePurchaseObserver extends PurchaseObserver {
        public DonatePurchaseObserver(Handler handler) {
            super(getActivity(), handler);
        }

        @Override
        public void onBillingSupported(boolean supported) {
            Log.d(DonationsUtils.TAG, "supported: " + supported);
            if (!supported) {
                displayDialog(DIALOG_BILLING_NOT_SUPPORTED_ID);
            }
        }

        @Override
        public void onPurchaseStateChange(PurchaseState purchaseState, String itemId, final String orderId,
                long purchaseTime, String developerPayload) {
            Log.d(DonationsUtils.TAG, "onPurchaseStateChange() itemId: " + itemId + " " + purchaseState);
        }

        @Override
        public void onRequestPurchaseResponse(RequestPurchase request, ResponseCode responseCode) {
            Log.d(DonationsUtils.TAG, request.mProductId + ": " + responseCode);
            if (responseCode == ResponseCode.RESULT_OK) {
                Log.d(DonationsUtils.TAG, "purchase was successfully sent to server");
                displayDialog(DIALOG_THANKS);
            } else if (responseCode == ResponseCode.RESULT_USER_CANCELED) {
                Log.d(DonationsUtils.TAG, "user canceled purchase");
            } else {
                Log.d(DonationsUtils.TAG, "purchase failed");
            }
        }

        @Override
        public void onRestoreTransactionsResponse(RestoreTransactions request, ResponseCode responseCode) {
            if (responseCode == ResponseCode.RESULT_OK) {
                Log.d(DonationsUtils.TAG, "completed RestoreTransactions request");
            } else {
                Log.d(DonationsUtils.TAG, "RestoreTransactions error: " + responseCode);
            }
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.donations__fragment, container, false);

        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        /* Flattr */
        if (DonationsUtils.getResourceBoolean(getActivity(), "donations__flattr_enabled")) {
            // inflate flattr view into stub
            ViewStub flattrViewStub = (ViewStub) getActivity().findViewById(R.id.donations__flattr_stub);
            flattrViewStub.inflate();

            buildFlattrView();
        }

        /* Google */
        mGoogleEnabled = DonationsUtils.getResourceBoolean(getActivity(), "donations__google_enabled");
        if (mGoogleEnabled) {
            // inflate google view into stub
            ViewStub googleViewStub = (ViewStub) getActivity().findViewById(R.id.donations__google_stub);
            googleViewStub.inflate();

            // get catalog from xml config
            CATALOG = DonationsUtils.getResourceStringArray(getActivity(), "donations__google_catalog");

            // choose donation amount
            mGoogleSpinner = (Spinner) getActivity().findViewById(R.id.donations__google_android_market_spinner);
            ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity(),
                    R.array.donations__google_android_market_promt_array, android.R.layout.simple_spinner_item);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            mGoogleSpinner.setAdapter(adapter);

            mHandler = new Handler();
            mDonatePurchaseObserver = new DonatePurchaseObserver(mHandler);
            mBillingService = new BillingService();
            mBillingService.setContext(getActivity());

            Button btGoogle = (Button) getActivity()
                    .findViewById(R.id.donations__google_android_market_donate_button);
            btGoogle.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    donateGoogleOnClick(v);
                }
            });
        }

        /* PayPal */
        if (DonationsUtils.getResourceBoolean(getActivity(), "donations__paypal_enabled")) {
            // inflate paypal view into stub
            ViewStub paypalViewStub = (ViewStub) getActivity().findViewById(R.id.donations__paypal_stub);
            paypalViewStub.inflate();

            Button btPayPal = (Button) getActivity().findViewById(R.id.donations__paypal_donate_button);
            btPayPal.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    donatePayPalOnClick(v);
                }
            });
        }
    }

    /**
     * Donate button executes donations based on selection in spinner
     * 
     * @param view
     */
    public void donateGoogleOnClick(View view) {
        final int index;
        index = mGoogleSpinner.getSelectedItemPosition();
        Log.d(DonationsUtils.TAG, "selected item in spinner: " + index);

        if (!Consts.DEBUG) {
            if (!mBillingService.requestPurchase(CATALOG[index], null)) {
                displayDialog(DIALOG_BILLING_NOT_SUPPORTED_ID);
            }
        } else {
            // when debugging, choose android.test.x item
            if (!mBillingService.requestPurchase(CATALOG_DEBUG[0], null)) {
                displayDialog(DIALOG_BILLING_NOT_SUPPORTED_ID);
            }
        }
    }

    /**
     * Donate button with PayPal by opening browser with defined URL For possible parameters see:
     * https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/
     * e_howto_html_Appx_websitestandard_htmlvariables
     * 
     * @param view
     */
    public void donatePayPalOnClick(View view) {
        Uri.Builder uriBuilder = new Uri.Builder();
        uriBuilder.scheme("https").authority("www.paypal.com").path("cgi-bin/webscr");
        uriBuilder.appendQueryParameter("cmd", "_donations");

        uriBuilder.appendQueryParameter("business",
                DonationsUtils.getResourceString(getActivity(), "donations__paypal_user"));
        uriBuilder.appendQueryParameter("lc", "US");
        uriBuilder.appendQueryParameter("item_name",
                DonationsUtils.getResourceString(getActivity(), "donations__paypal_item_name"));
        uriBuilder.appendQueryParameter("no_note", "1");
        // uriBuilder.appendQueryParameter("no_note", "0");
        // uriBuilder.appendQueryParameter("cn", "Note to the developer");
        uriBuilder.appendQueryParameter("no_shipping", "1");
        uriBuilder.appendQueryParameter("currency_code",
                DonationsUtils.getResourceString(getActivity(), "donations__paypal_currency_code"));
        // uriBuilder.appendQueryParameter("bn", "PP-DonationsBF:btn_donate_LG.gif:NonHosted");
        Uri payPalUri = uriBuilder.build();

        if (DonationsUtils.DEBUG) {
            Log.d(DonationsUtils.TAG, "Opening the browser with the url: " + payPalUri.toString());
        }

        // Start your favorite browser
        Intent viewIntent = new Intent(Intent.ACTION_VIEW, payPalUri);
        startActivity(viewIntent);
    }

    /**
     * Called when this activity becomes visible.
     */
    @Override
    public void onStart() {
        super.onStart();

        if (mGoogleEnabled) {
            ResponseHandler.register(mDonatePurchaseObserver);
        }
    }

    /**
     * Called when this activity is no longer visible.
     */
    @Override
    public void onStop() {
        super.onStop();

        if (mGoogleEnabled) {
            ResponseHandler.unregister(mDonatePurchaseObserver);
        }
    }

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

        if (mGoogleEnabled) {
            mBillingService.unbind();
        }
    }

    private void displayDialog(int id) {
        int icon = -1;
        int title = -1;
        int message = -1;

        switch (id) {
        case DIALOG_BILLING_NOT_SUPPORTED_ID:
            icon = android.R.drawable.ic_dialog_alert;
            title = R.string.donations__google_android_market_not_supported_title;
            message = R.string.donations__google_android_market_not_supported;
        case DIALOG_THANKS:
            icon = android.R.drawable.ic_dialog_info;
            title = R.string.donations__thanks_dialog_title;
            message = R.string.donations__thanks_dialog;
        default:
        }

        AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
        dialog.setIcon(icon);
        dialog.setTitle(title);
        dialog.setMessage(message);
        dialog.setCancelable(true);
        dialog.setNeutralButton(R.string.donations__button_close, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        dialog.show();
    }

    /**
     * Build view for Flattr. see Flattr API for more information:
     * http://developers.flattr.net/button/
     */
    @SuppressLint("SetJavaScriptEnabled")
    @TargetApi(11)
    private void buildFlattrView() {
        final FrameLayout mLoadingFrame;
        final WebView mFlattrWebview;

        mFlattrWebview = (WebView) getActivity().findViewById(R.id.donations__flattr_webview);
        mLoadingFrame = (FrameLayout) getActivity().findViewById(R.id.donations__loading_frame);

        // disable hardware acceleration for this webview to get transparent background working
        if (Build.VERSION.SDK_INT >= 11) {
            mFlattrWebview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }

        // define own webview client to override loading behaviour
        mFlattrWebview.setWebViewClient(new WebViewClient() {
            /**
             * Open all links in browser, not in webview
             */
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
                view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(urlNewString)));

                return false;
            }

            /**
             * Links in the flattr iframe should load in the browser not in the iframe itself,
             * http:/
             * /stackoverflow.com/questions/5641626/how-to-get-webview-iframe-link-to-launch-the
             * -browser
             */
            @Override
            public void onLoadResource(WebView view, String url) {
                if (url.contains("flattr")) {
                    HitTestResult result = view.getHitTestResult();
                    if (result != null && result.getType() > 0) {
                        view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
                        view.stopLoading();
                    }
                }
            }

            /**
             * After loading is done, remove frame with progress circle
             */
            @Override
            public void onPageFinished(WebView view, String url) {
                // remove loading frame, show webview
                if (mLoadingFrame.getVisibility() == View.VISIBLE) {
                    mLoadingFrame.setVisibility(View.GONE);
                    mFlattrWebview.setVisibility(View.VISIBLE);
                }
            }
        });

        // get flattr values from xml config
        String projectUrl = DonationsUtils.getResourceString(getActivity(), "donations__flattr_project_url");
        String flattrUrl = DonationsUtils.getResourceString(getActivity(), "donations__flattr_url");

        // make text white and background transparent
        String htmlStart = "<html> <head><style type='text/css'>*{color: #FFFFFF; background-color: transparent;}</style>";

        // https is not working in android 2.1 and 2.2
        String flattrScheme;
        if (Build.VERSION.SDK_INT >= 9) {
            flattrScheme = "https://";
        } else {
            flattrScheme = "http://";
        }

        // set url of flattr link
        mFlattrUrl = (TextView) getActivity().findViewById(R.id.donations__flattr_url);
        mFlattrUrl.setText(flattrScheme + flattrUrl);

        String flattrJavascript = "<script type='text/javascript'>" + "/* <![CDATA[ */" + "(function() {"
                + "var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];"
                + "s.type = 'text/javascript';" + "s.async = true;" + "s.src = '" + flattrScheme
                + "api.flattr.com/js/0.6/load.js?mode=auto';" + "t.parentNode.insertBefore(s, t);" + "})();"
                + "/* ]]> */" + "</script>";
        String htmlMiddle = "</head> <body> <div align='center'>";
        String flattrHtml = "<a class='FlattrButton' style='display:none;' href='" + projectUrl
                + "' target='_blank'></a> <noscript><a href='" + flattrScheme + flattrUrl
                + "' target='_blank'> <img src='" + flattrScheme
                + "api.flattr.com/button/flattr-badge-large.png' alt='Flattr this' title='Flattr this' border='0' /></a></noscript>";
        String htmlEnd = "</div> </body> </html>";

        String flattrCode = htmlStart + flattrJavascript + htmlMiddle + flattrHtml + htmlEnd;

        mFlattrWebview.getSettings().setJavaScriptEnabled(true);

        mFlattrWebview.loadData(flattrCode, "text/html", "utf-8");

        // make background of webview transparent
        // has to be called AFTER loadData
        // http://stackoverflow.com/questions/5003156/android-webview-style-background-colortransparent-ignored-on-android-2-2
        mFlattrWebview.setBackgroundColor(0x00000000);
    }
}