Java tutorial
/* * Copyright 2011-2012 the original author or authors. * * 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 piuk.blockchain.android.ui; import java.util.ArrayList; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.text.ClipboardManager; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Toast; import com.google.bitcoin.core.Address; import com.google.bitcoin.core.AddressFormatException; import com.google.bitcoin.core.ECKey; import com.google.bitcoin.core.WrongNetworkException; import com.google.bitcoin.uri.BitcoinURIParseException; import piuk.BitcoinAddress; import piuk.BitcoinURI; import piuk.MyRemoteWallet; import piuk.blockchain.android.R; import piuk.blockchain.android.Constants; import piuk.blockchain.android.WalletApplication.AddAddressCallback; import piuk.blockchain.android.ui.dialogs.RequestPasswordDialog; import piuk.blockchain.android.util.ActionBarFragment; import piuk.blockchain.android.util.ViewPagerTabs; /** * @author Andreas Schildbach */ public final class WalletAddressesActivity extends AbstractWalletActivity { public static void start(final Context context, final boolean sending) { final Intent intent = new Intent(context, WalletAddressesActivity.class); intent.putExtra(EXTRA_SENDING, sending); context.startActivity(intent); } private static final String EXTRA_SENDING = "sending"; private WalletActiveAddressesFragment activeAddressesFragment; private WalletArchivedAddressesFragment archivedAddressesFragment; private SendingAddressesFragment sendingAddressesFragment; int pagerPosition = 0; private final Handler handler = new Handler(); @Override public boolean onCreateOptionsMenu(final Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.addresses_menu, menu); return true; } @Override public boolean onPrepareOptionsMenu(final Menu menu) { super.onPrepareOptionsMenu(menu); { MenuItem item = menu.findItem(R.id.addresses_menu_generate); item.setVisible(pagerPosition == 0); } { MenuItem item = menu.findItem(R.id.addresses_menu_scan_watch_only); item.setVisible(pagerPosition == 0); } { MenuItem item = menu.findItem(R.id.addresses_menu_paste); item.setVisible(pagerPosition == 2); } { MenuItem item = menu.findItem(R.id.addresses_menu_scan_uri); item.setVisible(pagerPosition == 2); } return true; } public void handleAddWatchOnly(String data) throws Exception { try { new Address(Constants.NETWORK_PARAMETERS, data); } catch (Exception e) { longToast(R.string.send_coins_fragment_receiving_address_error); return; } final String address = data; final AlertDialog.Builder b = new AlertDialog.Builder(this); b.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (application.getRemoteWallet() == null) return; application.getRemoteWallet().addWatchOnly(address); application.saveWallet(new SuccessCallback() { @Override public void onSuccess() { EditAddressBookEntryFragment.edit(getSupportFragmentManager(), address); } @Override public void onFail() { } }); } }); b.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); b.setTitle("Watch Only Address"); b.setMessage("Do you wish to add the Watch Only bitcoin address " + data + " to your wallet? \n\nYou will not be able to spend any funds in this address unless you have the private key stored elsewhere. You should never add a Watch Only address that you do not have the private key for."); b.show(); } @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { case R.id.addresses_menu_generate: handleAddAddress(); return true; case R.id.addresses_menu_paste: handlePasteClipboard(); return true; case R.id.addresses_menu_scan_uri: showQRReader(new QrCodeDelagate() { @Override public void didReadQRCode(String contents) throws Exception { try { final BitcoinAddress address; if (contents.matches("[a-zA-Z0-9]*")) { address = new BitcoinAddress(contents); } else { final BitcoinURI bitcoinUri = new BitcoinURI(contents); address = bitcoinUri.getAddress(); } handler.postDelayed(new Runnable() { public void run() { EditAddressBookEntryFragment.edit(getSupportFragmentManager(), address.toString()); } }, 500); } catch (final AddressFormatException x) { errorDialog(R.string.send_coins_uri_parse_error_title, contents); } catch (final BitcoinURIParseException x) { errorDialog(R.string.send_coins_uri_parse_error_title, contents); } } }); return true; case R.id.addresses_menu_scan_watch_only: if (application.getRemoteWallet() == null) return false; System.out.println("showQRReader()"); showQRReader(new QrCodeDelagate() { @Override public void didReadQRCode(String data) throws Exception { System.out.println("didReadQRCode() " + data); handleAddWatchOnly(data); } }); return true; } return false; } @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.address_book_content); final ActionBarFragment actionBar = getActionBarFragment(); actionBar.setPrimaryTitle(R.string.address_book_activity_title); actionBar.setBack(new OnClickListener() { public void onClick(final View v) { finish(); } }); actionBar.addButton(android.R.drawable.ic_menu_more).setOnClickListener(new OnClickListener() { public void onClick(final View v) { openOptionsMenu(); } }); final ViewPager pager = (ViewPager) findViewById(R.id.address_book_pager); if (pager != null) { final ViewPagerTabs pagerTabs = (ViewPagerTabs) findViewById(R.id.address_book_pager_tabs); pagerTabs.addTabLabels(R.string.address_book_list_receiving_title, R.string.address_book_list_archived_title, R.string.address_book_list_sending_title); final ProxyOnPageChangeListener pagerListener = new ProxyOnPageChangeListener(pagerTabs) { @Override public void onPageSelected(final int position) { super.onPageSelected(position); pagerPosition = position; } }; final PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager()); pager.getCurrentItem(); pager.setAdapter(pagerAdapter); pager.setOnPageChangeListener(pagerListener); final int position = getIntent().getBooleanExtra(EXTRA_SENDING, true) == true ? 2 : 0; pager.setCurrentItem(position); pager.setPageMargin(2); pager.setPageMarginDrawable(R.color.background_less_bright); pagerListener.onPageSelected(position); pagerListener.onPageScrolled(position, 0, 0); archivedAddressesFragment = new WalletArchivedAddressesFragment(); activeAddressesFragment = new WalletActiveAddressesFragment(); sendingAddressesFragment = new SendingAddressesFragment(); } updateFragments(); } private void updateFragments() { if (application.getRemoteWallet() == null) return; final String[] addressesArray = application.getRemoteWallet().getActiveAddresses(); final ArrayList<Address> addresses = new ArrayList<Address>(addressesArray.length); for (final String address : addressesArray) { try { addresses.add(new Address(Constants.NETWORK_PARAMETERS, address)); } catch (WrongNetworkException e) { e.printStackTrace(); } catch (AddressFormatException e) { e.printStackTrace(); } } sendingAddressesFragment.setWalletAddresses(addresses); } private class PagerAdapter extends FragmentStatePagerAdapter { public PagerAdapter(final FragmentManager fm) { super(fm); } @Override public int getCount() { return 3; } @Override public Fragment getItem(final int position) { if (position == 0) return activeAddressesFragment; else if (position == 1) return archivedAddressesFragment; else return sendingAddressesFragment; } } private void handlePasteClipboard() { final ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); if (clipboardManager.hasText()) { final String text = clipboardManager.getText().toString().trim(); try { final Address address = new Address(Constants.NETWORK_PARAMETERS, text); EditAddressBookEntryFragment.edit(getSupportFragmentManager(), address.toString()); } catch (final AddressFormatException x) { toast(R.string.send_coins_parse_address_error_msg); } } else { toast(R.string.address_book_msg_clipboard_empty); } } private void reallyGenerateAddress() { application.addKeyToWallet(new ECKey(), null, 0, new AddAddressCallback() { public void onSavedAddress(String address) { Toast.makeText(self, getString(R.string.toast_generated_address, address), Toast.LENGTH_LONG) .show(); EditAddressBookEntryFragment.edit(getSupportFragmentManager(), address); updateFragments(); } public void onError(String reason) { Toast.makeText(self, reason, Toast.LENGTH_LONG).show(); updateFragments(); } }); } private void handleAddAddress() { if (application.getRemoteWallet() == null) return; MyRemoteWallet remoteWallet = application.getRemoteWallet(); if (remoteWallet.isDoubleEncrypted() == false) { reallyGenerateAddress(); } else { if (remoteWallet.temporySecondPassword == null) { RequestPasswordDialog.show(getSupportFragmentManager(), new SuccessCallback() { public void onSuccess() { reallyGenerateAddress(); } public void onFail() { Toast.makeText(getApplication(), R.string.generate_key_no_password_error, Toast.LENGTH_LONG) .show(); } }, RequestPasswordDialog.PasswordTypeSecond); } else { reallyGenerateAddress(); } } updateFragments(); } private class ProxyOnPageChangeListener implements OnPageChangeListener { private final OnPageChangeListener onPageChangeListener; public ProxyOnPageChangeListener(final OnPageChangeListener onPageChangeListener) { this.onPageChangeListener = onPageChangeListener; } public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) { onPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels); } public void onPageSelected(final int position) { onPageChangeListener.onPageSelected(position); } public void onPageScrollStateChanged(final int state) { onPageChangeListener.onPageScrollStateChanged(state); } } }