Android Open Source - android-wallet Send Tab






From Project

Back to project page android-wallet.

License

The source code is released under:

GNU General Public License

If you think the Android project android-wallet 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 Flavien Charlon/*from w  w w.  j a  v  a2  s. co  m*/
 *
 * 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 com.coinprism.wallet.fragment;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;

import com.coinprism.model.APIException;
import com.coinprism.model.AssetDefinition;
import com.coinprism.model.WalletState;
import com.coinprism.utils.Formatting;
import com.coinprism.wallet.ProgressDialog;
import com.coinprism.wallet.R;
import com.coinprism.wallet.UserPreferences;
import com.coinprism.wallet.adapter.AssetSelectorAdapter;
import com.google.zxing.integration.android.IntentIntegrator;

import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.crypto.TransactionSignature;
import org.bitcoinj.script.ScriptBuilder;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;

/**
 * The tab allowing the user to send assets or bitcoins.
 */
public class SendTab extends Fragment
{
    private AssetSelectorAdapter adapter;
    private Spinner assetSpinner;
    private EditText toAddress;
    private EditText amount;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_tab_send, container, false);
        this.assetSpinner = (Spinner) rootView.findViewById(R.id.assetSpinner);

        Button sendButton = (Button) rootView.findViewById(R.id.sendButton);
        toAddress = (EditText) rootView.findViewById(R.id.toAddress);
        amount = (EditText) rootView.findViewById(R.id.amount);

        sendButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                onSend();
            }
        });
        this.adapter = new AssetSelectorAdapter(this.getActivity(), new ArrayList<AssetDefinition>());
        this.adapter.add(null);
        this.assetSpinner.setAdapter(adapter);

        ImageButton scanButton = (ImageButton)rootView.findViewById(R.id.qrCodeButton);
        scanButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                IntentIntegrator integrator = new IntentIntegrator(SendTab.this.getActivity());
                integrator.initiateScan();
            }
        });

        WalletState.getState().setSendTab(this);
        return rootView;
    }

    /**
     * Notifies the UI of an available balance update.
     */
    public void updateWallet()
    {
        if (!isAdded())
            return;

        this.adapter.clear();

        // Add uncolored bitcoins to the list
        this.adapter.add(null);
        // Add all known assets to the list
        this.adapter.addAll(WalletState.getState().getAPIClient().getAllAssetDefinitions());
    }

    public void setAddress(String value)
    {
        this.toAddress.setText(value);
    }

    private void onSend()
    {
        final String to = toAddress.getText().toString();
        final String unitString = amount.getText().toString();
        final BigDecimal decimalAmount;

        final AssetDefinition selectedAsset = (AssetDefinition) assetSpinner.getSelectedItem();

        final ProgressDialog progressDialog = new ProgressDialog();

        try
        {
            decimalAmount = new BigDecimal(unitString);
        }
        catch (NumberFormatException exception)
        {
            showError(getString(R.string.tab_send_error_invalid_amount));
            return;
        }

        AsyncTask<Void, Void, Transaction> getTransaction = new AsyncTask<Void, Void, Transaction>()
        {
            private String subCode;

            protected Transaction doInBackground(Void... _)
            {
                try
                {
                    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(
                        SendTab.this.getActivity());

                    String value = sharedPreferences.getString(
                        UserPreferences.defaultFeesKey, getString(R.string.default_fees));

                    BigDecimal decimal = new BigDecimal(value);
                    long fees = decimal.scaleByPowerOfTen(8).toBigInteger().longValue();

                    if (selectedAsset == null)
                    {
                        // Send uncolored bitcoins
                        return WalletState.getState().getAPIClient().buildTransaction(
                            WalletState.getState().getConfiguration().getAddress(),
                            to, decimalAmount.scaleByPowerOfTen(8).toBigInteger().toString(), null, fees);
                    }
                    else
                    {
                        // Send an asset
                        BigInteger unitAmount = decimalAmount
                            .scaleByPowerOfTen(selectedAsset.getDivisibility()).toBigInteger();
                        return WalletState.getState().getAPIClient().buildTransaction(
                            WalletState.getState().getConfiguration().getAddress(),
                            to, unitAmount.toString(), selectedAsset.getAssetId(), fees);
                    }
                }
                catch (APIException exception)
                {
                    // The API returned an error
                    subCode = exception.getSubCode();
                    return null;
                }
                catch (Exception exception)
                {
                    return null;
                }
            }

            @Override
            protected void onPostExecute(Transaction result)
            {
                super.onPostExecute(result);

                if (!progressDialog.getIsCancelled())
                {
                    progressDialog.dismiss();
                    if (result != null)
                        onConfirm(result, decimalAmount, selectedAsset, to);
                    else if (subCode == null)
                        showError(getString(R.string.tab_send_error_connection_error));
                    else if (subCode.equals("InsufficientFunds"))
                        showError(getString(R.string.tab_send_error_insufficient_funds));
                    else if (subCode.equals("InsufficientColoredFunds"))
                        showError(getString(R.string.tab_send_error_insufficient_asset));
                    else if (subCode.equals("AmountUnderDustThreshold") || subCode.equals("ChangeUnderDustThreshold"))
                        showError(getString(R.string.tab_send_error_amount_too_low));
                    else
                        showError(getString(R.string.tab_send_error_server_error));
                }
            }
        };

        progressDialog.configure(
            getString(R.string.tab_send_dialog_please_wait),
            getString(R.string.tab_send_dialog_verifying_balance),
            true);
        progressDialog.show(this.getActivity().getSupportFragmentManager(), "");

        getTransaction.execute();
    }

    private void onConfirm(final Transaction result, final BigDecimal decimalAmount,
        final AssetDefinition selectedAsset, final String to)
    {
        final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this.getActivity());

        // Setting Dialog Title
        alertDialog.setTitle(getString(R.string.tab_send_dialog_confirm_transaction));

        final String assetName;
        if (selectedAsset == null)
            assetName = getString(R.string.tab_send_dialog_confirm_message_amount_bitcoin);
        else
        {
            if (selectedAsset.getName() != null && selectedAsset.getTicker() != null)
            {
                assetName = String.format(getString(R.string.tab_send_dialog_confirm_message_amount_known_asset),
                    selectedAsset.getTicker(), selectedAsset.getName());
            }
            else
            {
                assetName = String.format(
                    getString(R.string.tab_send_dialog_confirm_message_amount_unknown_asset),
                    selectedAsset.getAssetId());
            }
        }

        final String message = String.format(getString(R.string.tab_send_dialog_confirm_message),
            Formatting.formatNumber(decimalAmount), assetName, to);

        final View dialogView = getActivity().getLayoutInflater().inflate(R.layout.dialog_confirm_send, null);
        if (!WalletState.getState().getConfiguration().isPasswordEnabled())
            dialogView.findViewById(R.id.passwordContainer).setVisibility(View.GONE);

        final TextView messageText = (TextView) dialogView.findViewById(R.id.sendSummary);
        messageText.setText(message);
        alertDialog.setView(dialogView);

        alertDialog.setPositiveButton(
            getString(R.string.tab_send_dialog_confirm_button),
            new DialogInterface.OnClickListener()
            {
                public void onClick(DialogInterface dialog, int which)
                {
                    final EditText walletPasswordText = (EditText) dialogView.findViewById(R.id.walletPassword);
                    final String password = walletPasswordText.getText().toString();

                    if (!WalletState.getState().getConfiguration().isPasswordEnabled()
                        || WalletState.getState().getConfiguration().comparePassword(password))
                        onConfirmed(result);
                    else
                        showError(getString(R.string.tab_send_dialog_confirm_password_incorrect));
                }
            });

        alertDialog.setNegativeButton(
            getString(android.R.string.cancel),
            new DialogInterface.OnClickListener()
            {
                public void onClick(DialogInterface dialog, int which)
                {
                    dialog.cancel();
                }
            });

        alertDialog.show();
    }

    private void onConfirmed(final Transaction result)
    {
        final ProgressDialog progressDialog = new ProgressDialog();

        AsyncTask<Void, Void, String> broadcastTask = new AsyncTask<Void, Void, String>()
        {
            protected String doInBackground(Void... addresses)
            {
                try
                {
                    for (int i = 0; i < result.getInputs().size(); i++)
                    {
                        final ECKey key = WalletState.getState().getConfiguration().getKey();
                        TransactionSignature signature =
                            result.calculateSignature(i, key,
                                result.getInputs().get(i).getScriptBytes(), Transaction.SigHash.ALL, false);

                        result.getInputs().get(i).setScriptSig(ScriptBuilder.createInputScript(signature, key));
                    }

                    return WalletState.getState().getAPIClient().broadcastTransaction(result);
                }
                catch (Exception e)
                {
                    return null;
                }
            }

            @Override
            protected void onPostExecute(String result)
            {
                super.onPostExecute(result);
                progressDialog.dismiss();

                if (result != null)
                {
                    showSuccess(result);
                }
                else
                {
                    showError(getString(R.string.tab_send_error_broadcast));
                }
            }
        };

        progressDialog.configure(
            getString(R.string.tab_send_dialog_please_wait),
            getString(R.string.tab_send_dialog_broadcasting),
            false);

        progressDialog.show(this.getActivity().getSupportFragmentManager(), "");

        broadcastTask.execute();
    }

    private void showSuccess(final String transactionId)
    {
        WalletState.getState().getBalanceTab().triggerRefresh();
        WalletState.getState().getTransactionsTab().triggerRefresh();

        final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this.getActivity());

        // Setting Dialog Title
        alertDialog.setTitle(getString(R.string.tab_send_dialog_transaction_success_title));
        alertDialog.setMessage(getString(R.string.tab_send_dialog_transaction_successful_message));

        this.amount.setText("");
        this.toAddress.setText("");

        alertDialog.setPositiveButton(
            getString(R.string.tab_send_dialog_transaction_successful_see),
            new DialogInterface.OnClickListener()
            {
                public void onClick(DialogInterface dialog, int which)
                {
                    String url = String.format(getString(R.string.link_transaction), transactionId);
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(url));
                    startActivity(intent);
                }
            });

        alertDialog.setNegativeButton(
            getString(R.string.tab_send_dialog_transaction_successful_close),
            new DialogInterface.OnClickListener()
            {
                public void onClick(DialogInterface dialog, int which)
                {
                    dialog.cancel();
                }
            });

        alertDialog.show();
    }

    private void showError(String message)
    {
        final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this.getActivity());

        alertDialog.setTitle(getString(R.string.tab_send_error_dialog_title));
        alertDialog.setMessage(message);
        alertDialog.setPositiveButton(getString(android.R.string.ok), null);

        alertDialog.show();
    }
}




Java Source Code List

com.coinprism.model.APIClient.java
com.coinprism.model.APIException.java
com.coinprism.model.AddressBalance.java
com.coinprism.model.AssetBalance.java
com.coinprism.model.AssetDefinition.java
com.coinprism.model.BalanceLoader.java
com.coinprism.model.CoinprismWalletApplication.java
com.coinprism.model.DownloadImageTask.java
com.coinprism.model.QRCodeEncoder.java
com.coinprism.model.SingleAssetTransaction.java
com.coinprism.model.TransactionsLoader.java
com.coinprism.model.WalletConfiguration.java
com.coinprism.model.WalletState.java
com.coinprism.utils.Formatting.java
com.coinprism.utils.SecurePreferences.java
com.coinprism.utils.StretchingImageView.java
com.coinprism.wallet.ApplicationTest.java
com.coinprism.wallet.ProgressDialog.java
com.coinprism.wallet.QRCodeDialog.java
com.coinprism.wallet.UserPreferences.java
com.coinprism.wallet.WalletOverview.java
com.coinprism.wallet.adapter.AssetBalanceAdapter.java
com.coinprism.wallet.adapter.AssetSelectorAdapter.java
com.coinprism.wallet.adapter.TabsPagerAdapter.java
com.coinprism.wallet.adapter.TransactionAdapter.java
com.coinprism.wallet.fragment.BalanceTab.java
com.coinprism.wallet.fragment.SendTab.java
com.coinprism.wallet.fragment.TransactionsTab.java