org.kontalk.ui.DonationFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.kontalk.ui.DonationFragment.java

Source

/*
 * Kontalk Android client
 * Copyright (C) 2017 Kontalk Devteam <devteam@kontalk.org>
    
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
    
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
    
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.kontalk.ui;

import java.util.Arrays;

import org.kontalk.BuildConfig;
import org.kontalk.R;
import org.kontalk.billing.BillingResult;
import org.kontalk.billing.BillingServiceManager;
import org.kontalk.billing.IBillingService;
import org.kontalk.billing.IInventory;
import org.kontalk.billing.IProductDetails;
import org.kontalk.billing.IPurchase;
import org.kontalk.billing.OnBillingSetupFinishedListener;
import org.kontalk.billing.OnConsumeFinishedListener;
import org.kontalk.billing.OnPurchaseFinishedListener;
import org.kontalk.billing.QueryInventoryFinishedListener;
import org.kontalk.util.SystemUtils;

import android.app.Activity;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.text.ClipboardManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Toast;

/**
 * Donation fragment.
 * @author Daniele Ricci
 * @author Andrea Cappelli
 */
public class DonationFragment extends Fragment implements OnClickListener {

    // for Google Play
    private IBillingService mBillingService;
    private static final int IAB_REQUEST_CODE = 10001;

    OnPurchaseFinishedListener mPurchaseFinishedListener = new OnPurchaseFinishedListener() {

        public void onPurchaseFinished(BillingResult result, IPurchase purchase) {
            if (mBillingService == null)
                return;

            if (result.isSuccess()) {
                // consume purchase in the background
                mBillingService.consumeAsync(purchase, mConsumeFinishedListener);
            }
        }
    };

    OnConsumeFinishedListener mConsumeFinishedListener = new OnConsumeFinishedListener() {
        public void onConsumeFinished(IPurchase purchase, BillingResult result) {
            int msg;
            if (result.isSuccess())
                msg = R.string.msg_iab_thankyou;
            else
                msg = R.string.msg_iab_thankyou_warning;
            Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
        }
    };

    private final class OnPreConsumeFinishedListener implements OnConsumeFinishedListener {
        private int mConsumedItems;
        private String[] mItems;

        public void onConsumeFinished(IPurchase purchase, BillingResult result) {
            mConsumedItems++;
            if (mConsumedItems >= mItems.length) {
                mConsumedItems = 0;
                showDonationSelector(mItems);
            }
        }

        public void setDonationItems(String[] items) {
            mItems = items;
            mConsumedItems = 0;
        }
    }

    OnPreConsumeFinishedListener mPreConsumeFinishedListener = new OnPreConsumeFinishedListener();

    public IBillingService getBillingService() {
        return mBillingService;
    }

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

        View button = view.findViewById(R.id.donate_google);
        if (BillingServiceManager.isEnabled())
            button.setOnClickListener(this);
        else
            button.setVisibility(View.GONE);

        view.findViewById(R.id.donate_paypal).setOnClickListener(this);
        view.findViewById(R.id.donate_bitcoin).setOnClickListener(this);
        view.findViewById(R.id.donate_flattr).setOnClickListener(this);

        return view;
    }

    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.donate_google:
            donateGoogle();
            break;

        case R.id.donate_paypal:
            donatePaypal();
            break;

        case R.id.donate_bitcoin:
            donateBitcoin();
            break;

        case R.id.donate_flattr:
            donateFlattr();
            break;
        }
    }

    private void donateFlattr() {
        SystemUtils.openURL(getContext(), getString(R.string.flattr_url));
    }

    private void donateBitcoin() {
        final String address = getString(R.string.bitcoin_address);
        Uri uri = Uri.parse("bitcoin:" + address);
        Intent intent = SystemUtils.externalIntent(Intent.ACTION_VIEW, Uri.parse(uri.toString()));

        Activity ctx = getActivity();
        final PackageManager pm = ctx.getPackageManager();
        if (pm.resolveActivity(intent, 0) != null)
            startActivity(intent);
        else
            new MaterialDialog.Builder(getActivity()).title(R.string.title_bitcoin_dialog)
                    .content(getString(R.string.text_bitcoin_dialog, address)).positiveText(android.R.string.ok)
                    .neutralText(R.string.copy_clipboard).onNeutral(new MaterialDialog.SingleButtonCallback() {
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                            ClipboardManager cpm = (ClipboardManager) getActivity()
                                    .getSystemService(Context.CLIPBOARD_SERVICE);
                            cpm.setText(address);

                            Toast.makeText(getActivity(), R.string.bitcoin_clipboard_copied, Toast.LENGTH_LONG)
                                    .show();
                        }
                    }).show();
    }

    private void donatePaypal() {
        // just start Paypal donate button URL
        SystemUtils.openURL(getContext(), getString(R.string.paypal_url));
    }

    private void setupGoogle(final Dialog progress) {
        if (mBillingService == null) {
            mBillingService = BillingServiceManager.getInstance(getActivity());
            mBillingService.enableDebugLogging(BuildConfig.DEBUG);

            mBillingService.startSetup(new OnBillingSetupFinishedListener() {
                public void onSetupFinished(BillingResult result) {
                    if (!result.isSuccess()) {
                        alert(getString(R.string.iab_error_setup, result.getResponse()));
                        mBillingService = null;
                        progress.dismiss();
                        return;
                    }

                    queryInventory(progress);
                }
            });
        }

        else {
            queryInventory(progress);
        }
    }

    private void queryInventory(final Dialog progress) {
        final String[] iabItems = getResources().getStringArray(R.array.iab_items);

        QueryInventoryFinishedListener gotInventoryListener = new QueryInventoryFinishedListener() {
            public void onQueryInventoryFinished(BillingResult result, IInventory inventory) {
                if (mBillingService == null)
                    return;

                // dismiss progress
                progress.dismiss();

                if (result.isFailure()) {
                    alert(getString(R.string.iab_error_query, result.getResponse()));
                }

                else {
                    // prepare items for the dialog
                    String[] dialogItems = new String[iabItems.length];

                    for (int i = 0; i < iabItems.length; i++) {
                        IProductDetails sku = inventory.getSkuDetails(iabItems[i]);
                        if (sku != null) {
                            dialogItems[i] = sku.getDescription();
                        } else {
                            dialogItems[i] = iabItems[i];
                        }
                    }

                    // setup pre-consume listener
                    mPreConsumeFinishedListener.setDonationItems(dialogItems);
                    int purchases = 0;
                    // consume purchases just to be sure
                    for (String item : iabItems) {
                        IPurchase purchase = inventory.getPurchase(item);
                        if (purchase != null) {
                            purchases++;
                            mBillingService.consumeAsync(purchase, mPreConsumeFinishedListener);
                        }
                    }

                    // no purchases to be consumed, show donation now
                    if (purchases == 0)
                        showDonationSelector(dialogItems);
                }
            }
        };

        if (mBillingService != null)
            mBillingService.queryInventoryAsync(true, Arrays.asList(iabItems), gotInventoryListener);
    }

    private void showDonationSelector(CharSequence[] dialogItems) {
        final String[] iabItems = getResources().getStringArray(R.array.iab_items);

        // show dialog with choices
        new MaterialDialog.Builder(getActivity()).items(dialogItems)
                .itemsCallback(new MaterialDialog.ListCallback() {
                    @Override
                    public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
                        // start the purchase
                        String itemId = iabItems[position];
                        mBillingService.launchPurchaseFlow(getActivity(), itemId, IAB_REQUEST_CODE,
                                mPurchaseFinishedListener);
                    }
                }).negativeText(android.R.string.cancel).show();
    }

    private void donateGoogle() {
        // progress dialog
        Dialog dialog = new MaterialDialog.Builder(getActivity()).content(R.string.msg_connecting_iab)
                .cancelable(true).progress(true, 0).cancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        // FIXME this doesn't seem to work in some cases
                        if (mBillingService != null) {
                            mBillingService.dispose();
                            mBillingService = null;
                        }
                    }
                }).show();

        setupGoogle(dialog);
    }

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

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

    private void alert(String message) {
        new MaterialDialog.Builder(getActivity()).content(message).positiveText(android.R.string.ok).show();
    }
}