diff --git a/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java index abaef246..9fc842d3 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java @@ -9,26 +9,31 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.WindowManager; import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; +import com.m2049r.xmrwallet.model.WalletManager; +import com.m2049r.xmrwallet.util.Helper; + import java.io.File; +// TODO: somehow show which net we are generating for + public class GenerateFragment extends Fragment { EditText etWalletName; EditText etWalletPassword; Button bGenerate; LinearLayout llAccept; + TextView tvWalletAddress; TextView tvWalletMnemonic; Button bAccept; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -39,14 +44,20 @@ public class GenerateFragment extends Fragment { etWalletPassword = (EditText) view.findViewById(R.id.etWalletPassword); bGenerate = (Button) view.findViewById(R.id.bGenerate); llAccept = (LinearLayout) view.findViewById(R.id.llAccept); + tvWalletAddress = (TextView) view.findViewById(R.id.tvWalletAddress); tvWalletMnemonic = (TextView) view.findViewById(R.id.tvWalletMnemonic); bAccept = (Button) view.findViewById(R.id.bAccept); + boolean testnet = WalletManager.getInstance().isTestNet(); + tvWalletMnemonic.setTextIsSelectable(testnet); + etWalletName.requestFocus(); + Helper.showKeyboard(getActivity()); + setGenerateEnabled(); etWalletName.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable editable) { - setGenerateEnabled(); + showMnemonic(""); } @Override @@ -60,14 +71,15 @@ public class GenerateFragment extends Fragment { etWalletName.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(etWalletName, InputMethodManager.SHOW_IMPLICIT); + Helper.showKeyboard(getActivity()); } }); etWalletName.setOnEditorActionListener(new TextView.OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) { - etWalletPassword.requestFocus(); + if (etWalletName.length() > 0) { + etWalletPassword.requestFocus(); + } // otherwise ignore return false; } return false; @@ -77,14 +89,27 @@ public class GenerateFragment extends Fragment { etWalletPassword.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(etWalletPassword, InputMethodManager.SHOW_IMPLICIT); + Helper.showKeyboard(getActivity()); + } + }); + etWalletPassword.addTextChangedListener(new TextWatcher() { + @Override + public void afterTextChanged(Editable editable) { + showMnemonic(""); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { } }); etWalletPassword.setOnEditorActionListener(new TextView.OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) { - getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + Helper.hideKeyboard(getActivity()); generateWallet(); return false; } @@ -95,7 +120,7 @@ public class GenerateFragment extends Fragment { bGenerate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - // TODO make keyboard go away + Helper.hideKeyboard(getActivity()); generateWallet(); } }); @@ -108,6 +133,7 @@ public class GenerateFragment extends Fragment { }); bAccept.setEnabled(false); + llAccept.setVisibility(View.GONE); return view; } @@ -115,8 +141,8 @@ public class GenerateFragment extends Fragment { private void generateWallet() { String name = etWalletName.getText().toString(); if (name.length() == 0) return; - File walletFile = new File(activityCallback.getStorageRoot(), name + ".keys"); - if (walletFile.exists()) { + String walletPath = Helper.getWalletPath(getActivity(), name); + if (WalletManager.getInstance().walletExists(walletPath)) { Toast.makeText(getActivity(), getString(R.string.generate_wallet_exists), Toast.LENGTH_LONG).show(); etWalletName.requestFocus(); return; @@ -137,23 +163,18 @@ public class GenerateFragment extends Fragment { bGenerate.setEnabled(etWalletName.length() > 0); } - @Override - public void onResume() { - super.onResume(); - setGenerateEnabled(); - etWalletName.requestFocus(); - InputMethodManager imgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - imgr.showSoftInput(etWalletName, InputMethodManager.SHOW_IMPLICIT); - } - public void showMnemonic(String mnemonic) { setGenerateEnabled(); if (mnemonic.length() > 0) { tvWalletMnemonic.setText(mnemonic); bAccept.setEnabled(true); + llAccept.setVisibility(View.VISIBLE); } else { - tvWalletMnemonic.setText(getActivity().getString(R.string.generate_seed)); - bAccept.setEnabled(false); + if (llAccept.getVisibility() != View.GONE) { + tvWalletMnemonic.setText(getActivity().getString(R.string.generate_seed)); + bAccept.setEnabled(false); + llAccept.setVisibility(View.GONE); + } } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java index f3a2b6af..b9d2c757 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java +++ b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java @@ -33,6 +33,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; @@ -64,18 +65,26 @@ public class LoginActivity extends Activity } } - // adapted from http://www.mkyong.com/android/android-prompt-user-input-dialog-example/ @Override - public void onWalletSelected(final String wallet) { - Log.d(TAG, "selected wallet is ." + wallet + "."); - if (wallet.equals(getString(R.string.generate_title))) { + public void onWalletSelected(final String walletName) { + Log.d(TAG, "selected wallet is ." + walletName + "."); + if (walletName.equals(':' + getString(R.string.generate_title))) { startGenerateFragment(); } else { - promptPassword(wallet); + // now it's getting real, check if wallet exists + String walletPath = Helper.getWalletPath(this, walletName); + if (WalletManager.getInstance().walletExists(walletPath)) { + promptPassword(walletName); + } else { // this cannot really happen as we prefilter choices + Toast.makeText(this, getString(R.string.bad_wallet), Toast.LENGTH_SHORT).show(); + } } } + AlertDialog passwordDialog = null; // for preventing multiple clicks in wallet list + void promptPassword(final String wallet) { + if (passwordDialog != null) return; // we are already asking for password Context context = LoginActivity.this; LayoutInflater li = LayoutInflater.from(context); View promptsView = li.inflate(R.layout.prompt_password, null); @@ -94,37 +103,40 @@ public class LoginActivity extends Activity .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + Helper.hideKeyboardAlways(LoginActivity.this); String pass = etPassword.getText().toString(); processPasswordEntry(wallet, pass); + passwordDialog = null; } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + Helper.hideKeyboardAlways(LoginActivity.this); dialog.cancel(); + passwordDialog = null; } }); - final AlertDialog alertDialog = alertDialogBuilder.create(); - // request keyboard - alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); + passwordDialog = alertDialogBuilder.create(); + Helper.showKeyboard(passwordDialog); + // accept keyboard "ok" etPassword.setOnEditorActionListener(new TextView.OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) { - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + Helper.hideKeyboardAlways(LoginActivity.this); String pass = etPassword.getText().toString(); - alertDialog.cancel(); + passwordDialog.cancel(); processPasswordEntry(wallet, pass); + passwordDialog = null; return false; } return false; } }); - alertDialog.show(); + passwordDialog.show(); } private boolean checkWalletPassword(String walletName, String password) { @@ -191,7 +203,7 @@ public class LoginActivity extends Activity } else { String msg = getString(R.string.message_strorage_not_permitted); Log.e(TAG, msg); - Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); + Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); //throw new IllegalStateException(msg); } break; @@ -298,9 +310,10 @@ public class LoginActivity extends Activity runOnUiThread(new Runnable() { public void run() { Toast.makeText(LoginActivity.this, - getString(R.string.generate_wallet_create_failed), Toast.LENGTH_SHORT).show(); + getString(R.string.generate_wallet_create_failed_1), Toast.LENGTH_LONG).show(); } }); + newWallet.close(); return; } final String walletPath = new File(getStorageRoot(), name).getAbsolutePath(); @@ -317,7 +330,7 @@ public class LoginActivity extends Activity } else { Log.e(TAG, "Wallet store failed to " + walletPath); Toast.makeText(LoginActivity.this, - getString(R.string.generate_wallet_create_failed), Toast.LENGTH_SHORT).show(); + getString(R.string.generate_wallet_create_failed_2), Toast.LENGTH_LONG).show(); } } }); @@ -325,4 +338,5 @@ public class LoginActivity extends Activity } , "AcceptWallet", MoneroHandlerThread.THREAD_STACK_SIZE).start(); } + } diff --git a/app/src/main/java/com/m2049r/xmrwallet/LoginFragment.java b/app/src/main/java/com/m2049r/xmrwallet/LoginFragment.java index e7f1bf96..3ab58db9 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/LoginFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/LoginFragment.java @@ -26,9 +26,7 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.WindowManager; import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; @@ -39,6 +37,7 @@ import android.widget.Toast; import android.widget.ToggleButton; import com.m2049r.xmrwallet.model.WalletManager; +import com.m2049r.xmrwallet.util.Helper; import java.io.File; import java.io.IOException; @@ -108,19 +107,18 @@ public class LoginFragment extends Fragment { tbMainNet = (ToggleButton) view.findViewById(R.id.tbMainNet); etDaemonAddress = (EditText) view.findViewById(R.id.etDaemonAddress); - getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + Helper.hideKeyboard(getActivity()); etDaemonAddress.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(etDaemonAddress, InputMethodManager.SHOW_IMPLICIT); + Helper.showKeyboard(getActivity()); } }); etDaemonAddress.setOnEditorActionListener(new TextView.OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) { - getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + Helper.hideKeyboard(getActivity()); return false; } return false; @@ -155,7 +153,9 @@ public class LoginFragment extends Fragment { public void onItemClick(AdapterView parent, View view, int position, long id) { EditText tvDaemonAddress = (EditText) getView().findViewById(R.id.etDaemonAddress); if (tvDaemonAddress.getText().toString().length() == 0) { - Toast.makeText(getActivity(), getString(R.string.prompt_daemon_missing), Toast.LENGTH_LONG).show(); + Toast.makeText(getActivity(), getString(R.string.prompt_daemon_missing), Toast.LENGTH_SHORT).show(); + tvDaemonAddress.requestFocus(); + Helper.showKeyboard(getActivity()); return; } @@ -173,7 +173,7 @@ public class LoginFragment extends Fragment { } if (!checkAndSetWalletDaemon(getDaemon(), !isMainNet())) { - Toast.makeText(getActivity(), getString(R.string.warn_daemon_unavailable), Toast.LENGTH_LONG).show(); + Toast.makeText(getActivity(), getString(R.string.warn_daemon_unavailable), Toast.LENGTH_SHORT).show(); return; } @@ -181,6 +181,7 @@ public class LoginFragment extends Fragment { savePrefs(false); String wallet = itemValue.substring(WALLETNAME_PREAMBLE_LENGTH); + if (itemValue.charAt(1) == '-') wallet = ':' + wallet; activityCallback.onWalletSelected(wallet); } }); diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java index 8e101015..c1c2bcb8 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java @@ -200,11 +200,6 @@ public class WalletActivity extends Activity implements WalletFragment.Listener, Intent intent = new Intent(getApplicationContext(), WalletService.class); intent.putExtra(WalletService.REQUEST, WalletService.REQUEST_CMD_STORE); startService(intent); - runOnUiThread(new Runnable() { - public void run() { - Toast.makeText(getApplicationContext(), getString(R.string.status_wallet_unloading), Toast.LENGTH_LONG).show(); - } - }); Log.d(TAG, "STORE request sent"); } else { Log.e(TAG, "Service not bound"); @@ -259,6 +254,15 @@ public class WalletActivity extends Activity implements WalletFragment.Listener, }); } + @Override + public void onWalletStored() { + runOnUiThread(new Runnable() { + public void run() { + Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_unloaded), Toast.LENGTH_SHORT).show(); + } + }); + } + @Override public void onProgress(final String text) { //Log.d(TAG, "PROGRESS: " + text); diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java index 436d08f0..b40f3a8e 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java @@ -191,6 +191,8 @@ public class WalletService extends Service { void onProgress(String text); void onProgress(int n); + + void onWalletStored(); } String progressText = null; @@ -257,6 +259,7 @@ public class WalletService extends Service { Log.d(TAG, "storing wallet: " + myWallet.getName()); getWallet().store(); Log.d(TAG, "wallet stored: " + myWallet.getName()); + if (observer != null) observer.onWalletStored(); } } break; diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java b/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java index 873c89f1..182daf57 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java +++ b/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java @@ -18,10 +18,13 @@ package com.m2049r.xmrwallet.util; import android.Manifest; import android.app.Activity; +import android.app.Dialog; import android.content.Context; import android.content.pm.PackageManager; import android.os.Environment; import android.util.Log; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; import com.m2049r.xmrwallet.R; @@ -82,4 +85,26 @@ public class Helper { return Environment.MEDIA_MOUNTED.equals(state); } + static public void showKeyboard(Activity act) { + InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(act.getCurrentFocus(), InputMethodManager.SHOW_IMPLICIT); + } + + static public void hideKeyboard(Activity act) { + if (act.getCurrentFocus() == null) { + act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + } else { + InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow((null == act.getCurrentFocus()) ? null : act.getCurrentFocus().getWindowToken(), + InputMethodManager.HIDE_NOT_ALWAYS); + } + } + + static public void showKeyboard(Dialog dialog) { + dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); + } + + static public void hideKeyboardAlways(Activity act) { + act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + } } diff --git a/app/src/main/res/layout/gen_fragment.xml b/app/src/main/res/layout/gen_fragment.xml index 6a6edbc1..e0ed6a90 100644 --- a/app/src/main/res/layout/gen_fragment.xml +++ b/app/src/main/res/layout/gen_fragment.xml @@ -52,7 +52,7 @@ android:id="@+id/bGenerate" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="16dp" + android:layout_marginBottom="8dp" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:layout_marginTop="8dp" @@ -67,6 +67,21 @@ android:orientation="vertical" android:visibility="visible"> + + + android:textSize="20sp" />