/* * Aegis Bitcoin Wallet - The secure Bitcoin wallet for Android * Copyright 2014 Bojan Simic and specularX.co, designed by Reuven Yamrom * * 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.aegiswallet.actions; import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.preference.PreferenceManager; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.app.Fragment; import android.support.v4.app.NotificationCompat; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.text.Spannable; import android.text.SpannableString; import android.util.Log; import android.util.TypedValue; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.aegiswallet.PayBitsApplication; import com.aegiswallet.R; import com.aegiswallet.adapters.PendingTransactionListAdapter; import com.aegiswallet.adapters.TransactionListAdapter; import com.aegiswallet.helpers.CustomSharer; import com.aegiswallet.helpers.CustomTypefaceSpan; import com.aegiswallet.listeners.BackupCompletedListener; import com.aegiswallet.listeners.ImportCompletedListener; import com.aegiswallet.listeners.PasswordProvidedListener; import com.aegiswallet.listeners.SMSTaskCompletedListener; import com.aegiswallet.listeners.WalletDecryptedListener; import com.aegiswallet.listeners.WalletEncryptedListener; import com.aegiswallet.objects.SMSTransactionPojo; import com.aegiswallet.services.PeerBlockchainService; import com.aegiswallet.tasks.BackupWalletTask; import com.aegiswallet.tasks.DecryptWalletTask; import com.aegiswallet.tasks.EncryptWalletTask; import com.aegiswallet.tasks.GetCurrencyInfoTask; import com.aegiswallet.tasks.HandleSMSResponsesTask; import com.aegiswallet.utils.BasicUtils; import com.aegiswallet.utils.Constants; import com.aegiswallet.utils.WalletUtils; import com.google.bitcoin.core.Address; import com.google.bitcoin.core.ECKey; import com.google.bitcoin.core.Transaction; import com.google.bitcoin.core.Wallet; import java.math.BigDecimal; import java.math.BigInteger; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; public class MainActivity extends Activity implements PasswordProvidedListener, WalletEncryptedListener, BackupCompletedListener, ImportCompletedListener, WalletDecryptedListener, SMSTaskCompletedListener{ private String TAG = this.getClass().getName(); private ListView transactionListView; private ListView pendingTransactionListView; private PayBitsApplication application; private Wallet wallet; private SharedPreferences prefs; private Context context = this; private ImageButton requestBTCButton; private ImageButton sendBTCButton; private TextView balanceInCurrencyView; private TextView getBalanceInCurrencyViewType; private Button mainEncryptionButton; private TransactionListAdapter transactionListAdapter; private PendingTransactionListAdapter pendingTransactionListAdapter; private Handler balanceHandler; private TextView walletBalanceView; private TextView walletWatchAddressBalanceView; private LinearLayout watchedBalanceLinearLayout; private TextView blockchainStatus; private BroadcastReceiver receiver; private NotificationManager notificationManager; //Drawer stuff private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; private CharSequence mDrawerTitle; private CharSequence mTitle; private String[] drawerOptions; private ArrayAdapter<String> arrayAdapter; ArrayList<Transaction> recentTransactions; ArrayList<SMSTransactionPojo> pendingTransactions; private List<ECKey> keyList; private AlertDialog qrCodeAlertDialog = null; private ImageButton openDrawerButton; private boolean nfcEnabled; private final AtomicLong lastViewUpdateTime = new AtomicLong(0); private PeerBlockchainService peerBlockchainService; private boolean isServiceBound = false; private SharedPreferences smsTxnsPrefs; private ServiceConnection blockchainServiceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { peerBlockchainService = ((PeerBlockchainService.LocalBinder) service).getService(); } public void onServiceDisconnected(ComponentName className) { peerBlockchainService = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); application = (PayBitsApplication) getApplication(); prefs = PreferenceManager.getDefaultSharedPreferences(this); smsTxnsPrefs = application.getSharedPreferences(getString(R.string.sms_transaction_filename), Context.MODE_PRIVATE); //smsTxnsPrefs.edit().clear().commit(); wallet = application.getWallet(); application.initializeShamirSecretSharing(context); checkIfAppInitiated(); setContentView(R.layout.activity_main); getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); getActionBar().setCustomView(R.layout.aegis_actionbar); openDrawerButton = (ImageButton) findViewById(R.id.action_bar_icon); openDrawerButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mDrawerLayout != null) { if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) mDrawerLayout.closeDrawer(Gravity.LEFT); else mDrawerLayout.openDrawer(Gravity.LEFT); } } }); notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); blockchainStatus = (TextView) findViewById(R.id.blockchain_status); blockchainStatus.setTypeface(BasicUtils.getCustomTypeFace(getBaseContext())); setupBlockchainBroadcastReceiver(blockchainStatus); GetCurrencyInfoTask currencyInfoTask = new GetCurrencyInfoTask(getApplicationContext()); currencyInfoTask.execute(); //currencyInfoTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); watchedBalanceLinearLayout = (LinearLayout) findViewById(R.id.watched_balance_view); walletBalanceView = (TextView) findViewById(R.id.wallet_balance); walletBalanceView.setTypeface(BasicUtils.getCustomTypeFace(getBaseContext())); if (!prefs.contains(Constants.CURRENCY_PREF_KEY)) { prefs.edit().putString(Constants.CURRENCY_PREF_KEY, "USD").commit(); } walletWatchAddressBalanceView = (TextView) findViewById(R.id.watch_only_balance); updateMainViews(); determineSelectedAddress(); application.startBlockchainService(false); handleButtons(); recentTransactions = (ArrayList<Transaction>) wallet.getRecentTransactions(50, true); transactionListAdapter = new TransactionListAdapter(this, R.layout.transaction_detail_row, recentTransactions, wallet); transactionListView = (ListView) findViewById(R.id.transaction_list); if (recentTransactions == null || recentTransactions.size() == 0) transactionListView.setEmptyView(findViewById(R.id.transaction_empty_view_main)); transactionListView.setAdapter(transactionListAdapter); handlePendingTransactions(); initiateHandlers(walletBalanceView); application.addWalletListener(balanceHandler); checkWalletEncryptionStatus(); this.registerReceiver(receiver, new IntentFilter(PeerBlockchainService.ACTION_BLOCKCHAIN_STATE)); doDrawerSetup(); String message = getIntent().getStringExtra("message"); if (message != null) { Toast.makeText(context, message, Toast.LENGTH_LONG).show(); getIntent().removeExtra("message"); } nfcEnabled = prefs.contains(Constants.SHAMIR_ENCRYPTED_KEY) ? false : true; checkBackupDone(); doBackupReminder(); isServiceBound = this.bindService(new Intent(this, PeerBlockchainService.class), blockchainServiceConnection, Context.BIND_AUTO_CREATE); HandleSMSResponsesTask handleSMSResponsesTask = new HandleSMSResponsesTask(this); //handleSMSResponsesTask.execute(); handleSMSResponsesTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); sendMessagesToWear(); } private void sendMessagesToWear(){ application.sendMessage("MessageAddress", prefs.getString(Constants.PREFS_KEY_SELECTED_ADDRESS, null)); if(wallet != null) { String currencyValue = WalletUtils.getWalletCurrencyValue(getApplicationContext(), prefs, wallet.getBalance(Wallet.BalanceType.ESTIMATED)); application.sendMessage("MessageBalance", currencyValue); String exchangeRate = WalletUtils.getExchangeRateWithSymbol(this, prefs); if(exchangeRate != null) application.sendMessage("MessageBitcoinValue", exchangeRate); } } private void handlePendingTransactions(){ SharedPreferences smsPrefs = application.getSharedPreferences(getString(R.string.sms_transaction_filename), Context.MODE_PRIVATE); if(pendingTransactions != null) pendingTransactions.clear(); if(pendingTransactionListAdapter != null) pendingTransactionListAdapter.notifyDataSetInvalidated(); pendingTransactions = BasicUtils.getAllPendingTransactions(smsPrefs); if (pendingTransactions.size() > 0) { pendingTransactionListView = (ListView) findViewById(R.id.pending_transaction_list); pendingTransactionListView.setVisibility(View.VISIBLE); pendingTransactionListAdapter = new PendingTransactionListAdapter( this, R.layout.pending_transaction_detail_row, pendingTransactions); pendingTransactionListView.setAdapter(pendingTransactionListAdapter); pendingTransactionListAdapter.notifyDataSetChanged(); } } private void checkIfAppInitiated() { if (!prefs.getBoolean(Constants.APP_INIT_COMPLETE, false)) { Intent openMainActivity = new Intent(this, InitAppAction.class); openMainActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(openMainActivity); } } private void doDrawerSetup() { mTitle = mDrawerTitle = getTitle(); drawerOptions = getResources().getStringArray(R.array.drawer_items); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.left_drawer); if (wallet.isEncrypted()) { drawerOptions[3] = getString(R.string.drawer_wallet_decrypt); } else { drawerOptions[3] = getString(R.string.drawer_wallet_encrypt); } mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); arrayAdapter = new ArrayAdapter<String>(this, R.layout.drawer_list_item, drawerOptions); mDrawerList.setAdapter(arrayAdapter); mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { switch (position) { case 0: mDrawerLayout.closeDrawer(mDrawerList); launchShowTransactionsActivity(); break; //show addresses case 1: mDrawerLayout.closeDrawer(mDrawerList); launchShowAddressesActivity(); break; //show currencies case 2: mDrawerLayout.closeDrawer(mDrawerList); launchCurrencyActivity(); break; case 3: mDrawerLayout.closeDrawer(mDrawerList); if (wallet.isEncrypted()) { //do decrypt wallet if (application.getKeyCache() != null) { DecryptWalletTask decryptWalletTask = new DecryptWalletTask(context, wallet, null, application); //decryptWalletTask.execute(); decryptWalletTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } //Means x2 is written to the tag. else if (!prefs.contains(Constants.SHAMIR_ENCRYPTED_KEY)) { Intent decryptIntent = new Intent(context, NFCActivity.class); decryptIntent.putExtra("nfc_action", "decrypt"); startActivity(decryptIntent); } else { application.showPasswordPrompt(context, Constants.ACTION_DECRYPT); } } else { if (nfcEnabled) { Intent decryptIntent = new Intent(context, NFCActivity.class); decryptIntent.putExtra("nfc_action", "encrypt"); startActivity(decryptIntent); } else { application.showPasswordPrompt(context, Constants.ACTION_ENCRYPT); } } break; //If doing backup. case 4: mDrawerLayout.closeDrawer(mDrawerList); if (nfcEnabled) { Intent intent = new Intent(context, NFCActivity.class); intent.putExtra("nfc_action", "backup"); startActivity(intent); } else application.showPasswordPrompt(context, Constants.ACTION_BACKUP); break; case 5: mDrawerLayout.closeDrawer(mDrawerList); initiateSettingsActivity(); break; default: break; } } }); // ActionBarDrawerToggle ties together the the proper interactions // between the sliding drawer and the action bar app icon mDrawerToggle = new ActionBarDrawerToggle( this, /* host Activity */ mDrawerLayout, /* DrawerLayout object */ R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */ R.string.drawer_open, /* "open drawer" description for accessibility */ R.string.drawer_close /* "close drawer" description for accessibility */ ) { public void onDrawerClosed(View view) { setTitle(mTitle); //getActionBar().setTitle(mTitle); invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } public void onDrawerOpened(View drawerView) { //getActionBar().setTitle(mDrawerTitle); setTitle(mDrawerTitle); if (wallet.isEncrypted()) { drawerOptions[3] = getString(R.string.drawer_wallet_decrypt); } else { drawerOptions[3] = getString(R.string.drawer_wallet_encrypt); } arrayAdapter.notifyDataSetChanged(); invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } }; mDrawerLayout.setDrawerListener(mDrawerToggle); mDrawerList.setItemChecked(0, true); setTitle(drawerOptions[0]); mDrawerLayout.closeDrawer(mDrawerList); } @Override public void setTitle(CharSequence title) { SpannableString s = new SpannableString(title); s.setSpan(new CustomTypefaceSpan(this, "regular.otf"), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //getActionBar().setTitle(s); mTitle = s; } @Override public boolean onPrepareOptionsMenu(Menu menu) { // If the nav drawer is open, hide action items related to the content view boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); //menu.findItem(R.id.action_websearch).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggls mDrawerToggle.onConfigurationChanged(newConfig); } private void setupBlockchainBroadcastReceiver(final TextView blockchainStatus) { receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int download = intent.getIntExtra(PeerBlockchainService.ACTION_BLOCKCHAIN_STATE_DOWNLOAD, PeerBlockchainService.ACTION_BLOCKCHAIN_STATE_DOWNLOAD_OK); Date bestChainDate = (Date) intent.getSerializableExtra(PeerBlockchainService.ACTION_BLOCKCHAIN_STATE_BEST_CHAIN_DATE); long blockchainLag = System.currentTimeMillis() - bestChainDate.getTime(); boolean blockchainUptodate = blockchainLag < Constants.BLOCKCHAIN_UPTODATE_THRESHOLD_MS; boolean downloadOk = download == PeerBlockchainService.ACTION_BLOCKCHAIN_STATE_DOWNLOAD_OK; String downloading = downloadOk ? getString(R.string.synchronizing_network) : getString(R.string.sync_stalled); Date currentDate = new Date(); long daysOutOfDate = TimeUnit.MILLISECONDS.toDays(currentDate.getTime() - bestChainDate.getTime()) + 1; if (!blockchainUptodate) { blockchainStatus.setText(downloading + " " + daysOutOfDate + " " + getString(R.string.sync_days_behind)); blockchainStatus.setTextColor(getResources().getColor(R.color.custom_red)); } else { blockchainStatus.setText(getString(R.string.sync_completed)); blockchainStatus.setTextColor(getResources().getColor(R.color.custom_green)); } updateMainViews(); } }; } @Override protected void onResume() { super.onResume(); mDrawerLayout.closeDrawer(Gravity.LEFT); checkIfAppInitiated(); nfcEnabled = prefs.contains(Constants.SHAMIR_ENCRYPTED_KEY) ? false : true; updateMainViews(); doDrawerSetup(); registerReceiver(receiver, new IntentFilter(PeerBlockchainService.ACTION_BLOCKCHAIN_STATE)); checkBackupDone(); String message = getIntent().getStringExtra("message"); if (message != null) { Toast.makeText(context, message, Toast.LENGTH_LONG).show(); getIntent().removeExtra("message"); } isServiceBound = this.bindService(new Intent(this, PeerBlockchainService.class), blockchainServiceConnection, Context.BIND_AUTO_CREATE); handlePendingTransactions(); sendMessagesToWear(); doBackupReminder(); } @Override protected void onDestroy() { super.onDestroy(); doServiceUnbind(); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); } @Override public void onBackPressed() { super.onBackPressed(); this.finish(); } private void checkBackupDone() { boolean backupDone = getIntent().getBooleanExtra("backup_done", false); if (backupDone) { String fileName = getIntent().getStringExtra("backup_file"); if (fileName != null) { CustomSharer sharer = new CustomSharer(this, fileName); sharer.showCustomChooser(); getIntent().removeExtra("backup_done"); getIntent().removeExtra("backup_file"); } } } @Override protected void onPause() { unregisterReceiver(receiver); doServiceUnbind(); super.onPause(); } private void doServiceUnbind() { if (blockchainServiceConnection != null && isServiceBound) { unbindService(blockchainServiceConnection); isServiceBound = false; } } private void updateMainViews() { walletBalanceView.setText(BasicUtils.satoshiToBTC(wallet.getBalance(Wallet.BalanceType.ESTIMATED))); balanceInCurrencyView = (TextView) findViewById(R.id.wallet_balance_in_currency); balanceInCurrencyView.setTypeface(BasicUtils.getCustomTypeFace(getBaseContext())); String currencyValue = WalletUtils.getWalletCurrencyValue(getApplicationContext(), prefs, wallet.getBalance(Wallet.BalanceType.ESTIMATED)); getBalanceInCurrencyViewType = (TextView) findViewById(R.id.wallet_balance_currency_type); getBalanceInCurrencyViewType.setTypeface(BasicUtils.getCustomTypeFace(getBaseContext())); if (currencyValue.length() >= 10) { balanceInCurrencyView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 32); getBalanceInCurrencyViewType.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22); } else if (currencyValue.length() >= 6) { balanceInCurrencyView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40); getBalanceInCurrencyViewType.setTextSize(TypedValue.COMPLEX_UNIT_SP, 28); } balanceInCurrencyView.setText(currencyValue); getBalanceInCurrencyViewType.setText(" " + prefs.getString(Constants.CURRENCY_PREF_KEY, null)); BigInteger watchedBalance = wallet.getWatchedBalance(); if (watchedBalance != null && watchedBalance.longValue() > 0) { watchedBalanceLinearLayout.setVisibility(View.VISIBLE); walletWatchAddressBalanceView.setText(getString(R.string.watched_balance_string) + " " + BasicUtils.satoshiToBTC(wallet.getWatchedBalance())); } else { watchedBalanceLinearLayout.setVisibility(View.GONE); } checkWalletEncryptionStatus(); recentTransactions = (ArrayList<Transaction>) wallet.getRecentTransactions(50, true); if (transactionListAdapter != null) { transactionListAdapter.clear(); transactionListAdapter.notifyDataSetInvalidated(); //transactionListAdapter.addAll(WalletUtils.getRelevantTransactions(recentTransactions, wallet)); transactionListAdapter.addAll(recentTransactions); transactionListAdapter.notifyDataSetChanged(); } //Update the last view update time here. lastViewUpdateTime.set(System.currentTimeMillis()); sendMessagesToWear(); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU) { if (mDrawerLayout != null) { if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) mDrawerLayout.closeDrawer(Gravity.LEFT); else mDrawerLayout.openDrawer(Gravity.LEFT); } return true; } return super.onKeyUp(keyCode, event); } private void checkWalletEncryptionStatus() { if (mainEncryptionButton == null) mainEncryptionButton = (Button) findViewById(R.id.wallet_main_encryption_button); if (wallet.isEncrypted()) { mainEncryptionButton.setText(R.string.wallet_encrypted_button_string); mainEncryptionButton.setTextColor(getResources().getColor(R.color.custom_green)); mainEncryptionButton.setEnabled(false); } else { mainEncryptionButton.setText(R.string.wallet_not_encrypted_button_string); mainEncryptionButton.setTextColor(getResources().getColor(R.color.custom_red)); mainEncryptionButton.setEnabled(true); } } private void initiateHandlers(final TextView wallet_balance) { balanceHandler = new Handler() { @Override public void handleMessage(Message msg) { final long now = System.currentTimeMillis(); boolean shouldNotify = false; //If the last view update time is less than one second ago we don't do anything. //This is to stop the app from crashing. if (now - lastViewUpdateTime.get() < 1500) { shouldNotify = false; } else shouldNotify = true; Bundle data = msg.getData(); int status = data.getInt("status"); switch (status) { case Constants.WALLET_UPDATE_COINS_RECEIVED: Double amountReceived = data.getDouble("amount"); notifyCoinsReceivedOrSent(amountReceived, true); if (shouldNotify) { updateMainViews(); } break; case Constants.WALLET_UPDATE_COINS_SENT: Double amountSent = data.getDouble("amount"); notifyCoinsReceivedOrSent(amountSent, false); if (shouldNotify) updateMainViews(); break; case Constants.WALLET_UPDATE_REORGANIZED: //Do something upon reorg? //updateMainViews(); if (shouldNotify) updateMainViews(); break; case Constants.WALLET_UPDATE_TRANS_CONFIDENCE: if (shouldNotify) { updateMainViews(); } break; case Constants.WALLET_UPDATE_CHANGED: //Do something upon change? if (shouldNotify) { checkWalletEncryptionStatus(); updateMainViews(); } break; case Constants.WALLET_UPDATE_KEYS_ADDED: if (shouldNotify) { updateMainViews(); } break; default: break; } } }; } private void handleButtons() { requestBTCButton = (ImageButton) findViewById(R.id.request_coins_button); requestBTCButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { launchRequestActivity(); } }); sendBTCButton = (ImageButton) findViewById(R.id.send_coins_button); sendBTCButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { launchScanActivity(); } }); mainEncryptionButton = (Button) findViewById(R.id.wallet_main_encryption_button); mainEncryptionButton.setTypeface(BasicUtils.getCustomTypeFace(getBaseContext())); if (wallet.isEncrypted()) mainEncryptionButton.setText(getString(R.string.wallet_encrypted_button_string)); else mainEncryptionButton.setText(getString(R.string.wallet_not_encrypted_button_string)); mainEncryptionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (!wallet.isEncrypted()) { if (nfcEnabled) { Intent decryptIntent = new Intent(context, NFCActivity.class); decryptIntent.putExtra("nfc_action", "encrypt"); startActivity(decryptIntent); } else { application.showPasswordPrompt(context, Constants.ACTION_ENCRYPT); } } } }); } private void initiateSettingsActivity() { Intent settingsIntent = new Intent(this, SettingsActivity.class); startActivity(settingsIntent); } private void launchCurrencyActivity() { Intent viewCurrencyIntent = new Intent(this, CurrencyActivity.class); startActivity(viewCurrencyIntent); } private void launchShowAddressesActivity() { Intent showAddressesIntent = new Intent(this, ShowAddressesActivity.class); startActivity(showAddressesIntent); } private void launchShowTransactionsActivity() { Intent showTransactionListIntent = new Intent(this, ShowTransactionsActivity.class); startActivity(showTransactionListIntent); } private void launchRequestActivity() { Intent requestIntent = new Intent(this, RequestBitcoinActivity.class); startActivity(requestIntent); } private void launchScanActivity() { Intent sendIntent = new Intent(this, AddressScanActivity.class); startActivity(sendIntent); } @Override public boolean onCreateOptionsMenu(Menu menu) { return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } else { return super.onOptionsItemSelected(item); } } /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { public PlaceholderFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } } public Address determineSelectedAddress() { final String selectedAddress = prefs.getString(Constants.PREFS_KEY_SELECTED_ADDRESS, null); Address firstAddress = null; for (final ECKey key : wallet.getKeys()) { if (!wallet.isKeyRotating(key)) { final Address address = key.toAddress(Constants.NETWORK_PARAMETERS); if (address.toString().equals(selectedAddress)) { return address; } if (firstAddress == null) { firstAddress = address; } } } prefs.edit().putString(Constants.PREFS_KEY_SELECTED_ADDRESS, firstAddress.toString()).commit(); return firstAddress; } private void encryptWallet(String password) { try { EncryptWalletTask encryptWalletTask = new EncryptWalletTask(context, wallet, password, application, false); Log.d(TAG, "about to do execute..."); //encryptWalletTask.execute(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) encryptWalletTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); else encryptWalletTask.execute(); } catch (Exception e){ Log.d(TAG, e.getMessage()); } } @Override public void onPasswordProvided(String password, int action) { if (action == Constants.ACTION_ENCRYPT) { encryptWallet(password); } else if (action == Constants.ACTION_DECRYPT) { DecryptWalletTask decryptWalletTask = new DecryptWalletTask(context, wallet, password, application); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) decryptWalletTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); else decryptWalletTask.execute(); } else if (action == Constants.ACTION_BACKUP) { BackupWalletTask backupWalletTask = new BackupWalletTask(application, context, wallet, password); //backupWalletTask.execute(); backupWalletTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } } @Override public void onWalletEncrypted() { updateMainViews(); } @Override public void onWalletDecrypted(String password) { updateMainViews(); } @Override public void onBackupCompleted(String filePath) { String fileName = filePath; CustomSharer sharer = new CustomSharer(this, fileName); sharer.showCustomChooser(); } @Override public void onImportCompleted(String fileName, List<ECKey> keyList) { //Will NOT return a file name if the wallet was unencrypted. if (!wallet.isEncrypted()) { application.showImportCompletedPrompt(context, fileName); } } public void onClick(View v) { } public void notifyCoinsReceivedOrSent(Double amount, boolean received) { final NotificationCompat.Builder notification = new NotificationCompat.Builder(MainActivity.this); String eventTitle = ""; String eventLocation = ""; String eventDescription = ""; int wearIcon = 0; BigDecimal decimal = BigDecimal.valueOf(amount); BigInteger amountBigInt = decimal.toBigInteger(); if (received) { notification.setSmallIcon(R.drawable.aegis_receive_icon); notification.setContentText(getString(R.string.received_string) + " " + BasicUtils.satoshiToBTC(amountBigInt) + getString(R.string.btc_string)); eventTitle = "Aegis Receive"; eventLocation = "Aegis Wallet"; eventDescription = getString(R.string.received_string) + " " + BasicUtils.satoshiToBTC(amountBigInt) + getString(R.string.btc_string); wearIcon = R.drawable.aegis_receive_icon; } else if (!received) { notification.setSmallIcon(R.drawable.aegis_send_icon); notification.setContentText(getString(R.string.sent_string) + " " + BasicUtils.satoshiToBTC(amountBigInt) + getString(R.string.btc_string)); eventTitle = "Aegis Send"; eventLocation = "Aegis Wallet"; eventDescription = getString(R.string.sent_string) + " " + BasicUtils.satoshiToBTC(amountBigInt) + getString(R.string.btc_string); wearIcon = R.drawable.aegis_send_icon; } notification.setContentTitle(getString(R.string.app_name)); PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, new Intent(MainActivity.this, MainActivity.class), 0); notification.setContentIntent(pendingIntent); notification.setOngoing(false); notificationManager.notify(1, notification.getNotification()); NotificationCompat.BigTextStyle bigStyle = new NotificationCompat.BigTextStyle(); bigStyle.bigText(eventDescription); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.icon) .setLargeIcon(BitmapFactory.decodeResource( getResources(), R.drawable.initpageicon)) .setContentTitle(eventTitle) .setContentText(eventLocation) .setContentIntent(pendingIntent) .setStyle(bigStyle); } private void doBackupReminder() { if (System.currentTimeMillis() - application.lastReminderTime < 60000) return; String lastBackupString = prefs.getString(Constants.LAST_BACKUP_DATE, null); int lastBackupNumAddresses = prefs.getInt(Constants.LAST_BACKUP_NUM_ADDRESSES, 0); final Dialog dialog = new Dialog(context); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.backup_reminder_prompt); TextView backupText = (TextView) dialog.findViewById(R.id.backup_reminder_prompt_text); Button cancelButton = (Button) dialog.findViewById(R.id.backup_reminder_prompt_cancel_button); cancelButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { dialog.dismiss(); } }); final Button okayButton = (Button) dialog.findViewById(R.id.backup_reminder_prompt_ok_button); okayButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { dialog.dismiss(); if (nfcEnabled) { Intent intent = new Intent(context, NFCActivity.class); intent.putExtra("nfc_action", "backup"); startActivity(intent); } else application.showPasswordPrompt(context, Constants.ACTION_BACKUP); } }); try { if (dialog.isShowing()) return; if (lastBackupString != null) { Date lastBackupDate = Constants.backupDateFormat.parse(lastBackupString); long currentDate = System.currentTimeMillis(); long difference = currentDate - lastBackupDate.getTime(); long days = TimeUnit.MILLISECONDS.toDays(difference); int keyChainSize = wallet.getKeychainSize(); if (days > 6) { dialog.show(); application.lastReminderTime = System.currentTimeMillis(); } else if (!prefs.contains(Constants.LAST_BACKUP_NUM_ADDRESSES)) { dialog.show(); application.lastReminderTime = System.currentTimeMillis(); } else if (keyChainSize > lastBackupNumAddresses) { backupText.setText(getString(R.string.backup_reminder_new_address)); dialog.show(); application.lastReminderTime = System.currentTimeMillis(); } } else { application.lastReminderTime = System.currentTimeMillis(); dialog.show(); } } catch (ParseException e) { Log.d(TAG, e.getMessage()); } } public void onSMSTaskCompleted(){ handlePendingTransactions(); } }