mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-05 09:58:42 +02:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1875e2df62 | ||
![]() |
347123d961 |
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 25
|
||||
versionCode 42
|
||||
versionName "1.2.2"
|
||||
versionCode 45
|
||||
versionName "1.2.4"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
|
@@ -293,5 +293,6 @@ public class GenerateReviewFragment extends Fragment {
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.wallet_details_menu, menu);
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
}
|
@@ -48,8 +48,8 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.dialog.AboutFragment;
|
||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||
import com.m2049r.xmrwallet.dialog.DonationFragment;
|
||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||
import com.m2049r.xmrwallet.dialog.PrivacyFragment;
|
||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
@@ -132,7 +132,7 @@ public class LoginActivity extends AppCompatActivity
|
||||
});
|
||||
|
||||
if (Helper.getWritePermission(this)) {
|
||||
startLoginFragment();
|
||||
if (savedInstanceState == null) startLoginFragment();
|
||||
} else {
|
||||
Log.i(TAG, "Waiting for permissions");
|
||||
}
|
||||
@@ -1145,7 +1145,11 @@ public class LoginActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
private class AsyncOpenWallet extends AsyncTask<WalletNode, Void, Boolean> {
|
||||
private class AsyncOpenWallet extends AsyncTask<WalletNode, Void, Integer> {
|
||||
final static int OK = 0;
|
||||
final static int TIMEOUT = 1;
|
||||
final static int INVALID = 2;
|
||||
final static int IOEX = 3;
|
||||
|
||||
WalletNode walletNode;
|
||||
|
||||
@@ -1156,45 +1160,57 @@ public class LoginActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(WalletNode... params) {
|
||||
if (params.length != 1) return false;
|
||||
protected Integer doInBackground(WalletNode... params) {
|
||||
if (params.length != 1) return INVALID;
|
||||
this.walletNode = params[0];
|
||||
if (!walletNode.isValid()) return false;
|
||||
if (!walletNode.isValid()) return INVALID;
|
||||
|
||||
Log.d(TAG, "checking " + walletNode.getAddress());
|
||||
|
||||
long timeDA = new Date().getTime();
|
||||
SocketAddress address = new InetSocketAddress(walletNode.host, walletNode.port);
|
||||
long timeDB = new Date().getTime();
|
||||
Log.d(TAG, "Resolving " + walletNode.host + " took " + (timeDB - timeDA) + "ms.");
|
||||
Socket socket = new Socket();
|
||||
long timeA = new Date().getTime();
|
||||
try {
|
||||
long timeDA = new Date().getTime();
|
||||
SocketAddress address = new InetSocketAddress(walletNode.host, walletNode.port);
|
||||
long timeDB = new Date().getTime();
|
||||
Log.d(TAG, "Resolving " + walletNode.host + " took " + (timeDB - timeDA) + "ms.");
|
||||
Socket socket = new Socket();
|
||||
long timeA = new Date().getTime();
|
||||
socket.connect(address, LoginActivity.DAEMON_TIMEOUT);
|
||||
socket.close();
|
||||
long timeB = new Date().getTime();
|
||||
long time = timeB - timeA;
|
||||
Log.d(TAG, "Daemon " + walletNode.host + " is " + time + "ms away.");
|
||||
return (time < LoginActivity.DAEMON_TIMEOUT ? OK : TIMEOUT);
|
||||
} catch (IOException ex) {
|
||||
Log.d(TAG, "Cannot reach daemon " + walletNode.host + "/" + walletNode.port + " because " + ex.getMessage());
|
||||
return false;
|
||||
return IOEX;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Log.d(TAG, "Cannot reach daemon " + walletNode.host + "/" + walletNode.port + " because " + ex.getMessage());
|
||||
return INVALID;
|
||||
}
|
||||
long timeB = new Date().getTime();
|
||||
long time = timeB - timeA;
|
||||
Log.d(TAG, "Daemon " + walletNode.host + " is " + time + "ms away.");
|
||||
return time < LoginActivity.DAEMON_TIMEOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
protected void onPostExecute(Integer result) {
|
||||
super.onPostExecute(result);
|
||||
if (isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
dismissProgressDialog();
|
||||
if (result) {
|
||||
Log.d(TAG, "selected wallet is ." + walletNode.name + ".");
|
||||
// now it's getting real, check if wallet exists
|
||||
promptAndStart(walletNode);
|
||||
} else {
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.status_wallet_connect_timeout), Toast.LENGTH_LONG).show();
|
||||
switch (result) {
|
||||
case OK:
|
||||
Log.d(TAG, "selected wallet is ." + walletNode.name + ".");
|
||||
// now it's getting real, check if wallet exists
|
||||
promptAndStart(walletNode);
|
||||
break;
|
||||
case TIMEOUT:
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.status_wallet_connect_timeout), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case INVALID:
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.status_wallet_node_invalid), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case IOEX:
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.status_wallet_connect_ioex), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -36,8 +36,8 @@ import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||
import com.m2049r.xmrwallet.dialog.DonationFragment;
|
||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
@@ -223,7 +223,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
|
||||
Fragment walletFragment = new WalletFragment();
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.fragment_container, walletFragment).commit();
|
||||
.add(R.id.fragment_container, walletFragment, WalletFragment.TAG).commit();
|
||||
Log.d(TAG, "fragment added");
|
||||
|
||||
startWalletService();
|
||||
@@ -389,12 +389,12 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
Log.d(TAG, "onRefreshed()");
|
||||
try {
|
||||
final WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.TAG);
|
||||
if (wallet.isSynchronized()) {
|
||||
Log.d(TAG, "onRefreshed() synced");
|
||||
releaseWakeLock(); // the idea is to stay awake until synced
|
||||
if (!synced) {
|
||||
onProgress(null);
|
||||
if (!synced) { // first sync
|
||||
onProgress(-1);
|
||||
saveWallet(); // save on first sync
|
||||
synced = true;
|
||||
runOnUiThread(new Runnable() {
|
||||
@@ -523,10 +523,10 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
public void onProgress(final String text) {
|
||||
try {
|
||||
final WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.TAG);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
walletFragment.onProgress(text);
|
||||
walletFragment.setProgress(text);
|
||||
}
|
||||
});
|
||||
} catch (ClassCastException ex) {
|
||||
@@ -540,10 +540,10 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
public void onProgress(final int n) {
|
||||
try {
|
||||
final WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.TAG);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
walletFragment.onProgress(n);
|
||||
walletFragment.setProgress(n);
|
||||
}
|
||||
});
|
||||
} catch (ClassCastException ex) {
|
||||
|
@@ -49,7 +49,7 @@ import java.util.List;
|
||||
public class WalletFragment extends Fragment
|
||||
implements TransactionInfoAdapter.OnInteractionListener,
|
||||
AsyncExchangeRate.Listener {
|
||||
private static final String TAG = "WalletFragment";
|
||||
public static final String TAG = "WalletFragment";
|
||||
private TransactionInfoAdapter adapter;
|
||||
private NumberFormat formatter = NumberFormat.getInstance();
|
||||
|
||||
@@ -258,27 +258,26 @@ public class WalletFragment extends Fragment
|
||||
}
|
||||
}
|
||||
|
||||
public void setProgressText(final String text) {
|
||||
private String syncText = null;
|
||||
|
||||
public void setProgress(final String text) {
|
||||
syncText = text;
|
||||
tvProgress.setText(text);
|
||||
}
|
||||
|
||||
public void onProgress(final String text) {
|
||||
if (text != null) {
|
||||
setProgressText(text);
|
||||
pbProgress.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
pbProgress.setVisibility(View.INVISIBLE);
|
||||
setProgressText(getString(R.string.status_working));
|
||||
onProgress(-1);
|
||||
}
|
||||
}
|
||||
private int syncProgress = -1;
|
||||
|
||||
public void onProgress(final int n) {
|
||||
if (n >= 0) {
|
||||
public void setProgress(final int n) {
|
||||
syncProgress = n;
|
||||
if (n > 100) {
|
||||
pbProgress.setIndeterminate(true);
|
||||
pbProgress.setVisibility(View.VISIBLE);
|
||||
} else if (n >= 0) {
|
||||
pbProgress.setIndeterminate(false);
|
||||
pbProgress.setProgress(n);
|
||||
} else {
|
||||
pbProgress.setIndeterminate(true);
|
||||
pbProgress.setVisibility(View.VISIBLE);
|
||||
} else { // <0
|
||||
pbProgress.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +300,6 @@ public class WalletFragment extends Fragment
|
||||
Log.d(TAG, "updateStatus()");
|
||||
if (walletTitle == null) {
|
||||
setActivityTitle(wallet);
|
||||
onProgress(100); // of loading
|
||||
}
|
||||
long balance = wallet.getBalance();
|
||||
unlockedBalance = wallet.getUnlockedBalance();
|
||||
@@ -309,8 +307,6 @@ public class WalletFragment extends Fragment
|
||||
double amountXmr = Double.parseDouble(Helper.getDisplayAmount(balance - unlockedBalance)); // assume this cannot fail!
|
||||
String unconfirmed = Helper.getFormattedAmount(amountXmr, true);
|
||||
tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed));
|
||||
//tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount,
|
||||
// Helper.getDisplayAmount(balance - unlockedBalance, Helper.DISPLAY_DIGITS_SHORT)));
|
||||
String sync = "";
|
||||
if (!activityCallback.hasBoundService())
|
||||
throw new IllegalStateException("WalletService not bound.");
|
||||
@@ -324,16 +320,18 @@ public class WalletFragment extends Fragment
|
||||
firstBlock = wallet.getBlockChainHeight();
|
||||
}
|
||||
int x = 100 - Math.round(100f * n / (1f * daemonHeight - firstBlock));
|
||||
//onProgress(getString(R.string.status_syncing) + " " + sync);
|
||||
if (x == 0) x = -1;
|
||||
onProgress(x);
|
||||
if (x == 0) x = 101; // indeterminate
|
||||
setProgress(x);
|
||||
ivSynced.setVisibility(View.GONE);
|
||||
} else {
|
||||
sync = getString(R.string.status_synced) + formatter.format(wallet.getBlockChainHeight());
|
||||
ivSynced.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
sync = getString(R.string.status_wallet_connecting);
|
||||
setProgress(101);
|
||||
}
|
||||
setProgressText(sync);
|
||||
setProgress(sync);
|
||||
// TODO show connected status somewhere
|
||||
}
|
||||
|
||||
@@ -387,6 +385,8 @@ public class WalletFragment extends Fragment
|
||||
Log.d(TAG, "onResume()");
|
||||
activityCallback.setTitle(walletTitle, walletSubtitle);
|
||||
activityCallback.setToolbarButton(Toolbar.BUTTON_CLOSE);
|
||||
setProgress(syncProgress);
|
||||
setProgress(syncText);
|
||||
showReceive();
|
||||
}
|
||||
}
|
||||
|
@@ -103,6 +103,7 @@ public class WalletInfoAdapter extends RecyclerView.Adapter<WalletInfoAdapter.Vi
|
||||
final TextView tvAddress;
|
||||
final ImageButton ibOptions;
|
||||
WalletManager.WalletInfo infoItem;
|
||||
boolean popupOpen = false;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
@@ -112,10 +113,12 @@ public class WalletInfoAdapter extends RecyclerView.Adapter<WalletInfoAdapter.Vi
|
||||
ibOptions.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (popupOpen) return;
|
||||
//creating a popup menu
|
||||
PopupMenu popup = new PopupMenu(context, ibOptions);
|
||||
//inflating menu from xml resource
|
||||
popup.inflate(R.menu.list_context_menu);
|
||||
popupOpen = true;
|
||||
//adding click listener
|
||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
@@ -128,6 +131,12 @@ public class WalletInfoAdapter extends RecyclerView.Adapter<WalletInfoAdapter.Vi
|
||||
});
|
||||
//displaying the popup
|
||||
popup.show();
|
||||
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(PopupMenu menu) {
|
||||
popupOpen = false;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
@@ -481,7 +481,7 @@ public class WalletService extends Service {
|
||||
showProgress(100);
|
||||
}
|
||||
showProgress(getString(R.string.status_wallet_connecting));
|
||||
showProgress(-1);
|
||||
showProgress(101);
|
||||
// if we try to refresh the history here we get occasional segfaults!
|
||||
// doesnt matter since we update as soon as we get a new block anyway
|
||||
Log.d(TAG, "start() done");
|
||||
|
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/moneroText" android:state_enabled="false" />
|
||||
<item android:color="@color/moneroWhite" />
|
||||
</selector>
|
@@ -14,10 +14,10 @@
|
||||
<string name="donation_credits"><![CDATA[
|
||||
<b>Credits</b>
|
||||
<br/>
|
||||
m2049r, baltsar777, rehrar, anhdres,
|
||||
keejef, TheMonera, EarlOfEgo
|
||||
m2049r, baltsar777, anhdres, keejef,
|
||||
rehrar, EarlOfEgo et al.
|
||||
<br/><br/>
|
||||
<a href="www.xmrujo.com">www.xmrujo.com</a>
|
||||
<a href="https://monerujo.io/">monerujo.io</a>
|
||||
]]></string>
|
||||
|
||||
<string name="privacy_policy"><![CDATA[
|
||||
@@ -53,14 +53,14 @@
|
||||
<h2>Changes to this Privacy Policy</h2>
|
||||
<p>We may update this privacy policy from time to time. We will notify
|
||||
you of any changes by posting the new privacy policy in the app and on the
|
||||
website (www.xmrujo.com)
|
||||
website (www.monerujo.io)
|
||||
You are advised to review this privacy policy periodically for any changes.
|
||||
<p>This Privacy Policy was last updated: 2nd November, 2017.
|
||||
<p>This Privacy Policy was last updated: 10th November, 2017.
|
||||
</p>
|
||||
<h2>Contact Us</h2>
|
||||
<p>If you have any questions about our privacy policy,
|
||||
or how your data is being collected and processed,
|
||||
please e-mail privacy@xmrujo.com.
|
||||
please e-mail privacy@monerujo.io.
|
||||
</p>
|
||||
]]></string>
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
<color name="give">#FFFF6105</color>
|
||||
|
||||
<color name="moneroOrange">#cc5100</color>
|
||||
<color name="moneroWhite">#e2e2e2</color>
|
||||
<color name="moneroWhite">#ffffff</color>
|
||||
<color name="moneroBlack">#000000</color>
|
||||
<color name="moneroGray">#FD9B9B9B</color>
|
||||
|
||||
|
@@ -45,8 +45,11 @@
|
||||
<string name="status_wallet_unloaded">Wallet saved</string>
|
||||
<string name="status_wallet_unload_failed">Wallet save failed!</string>
|
||||
<string name="status_wallet_connecting">Connecting …</string>
|
||||
<string name="status_wallet_connect_failed">Daemon connection failed!\nCheck username/password</string>
|
||||
<string name="status_wallet_connect_timeout">Daemon connection timed out!\nTry again or another!</string>
|
||||
<string name="status_wallet_connect_failed">Node connection failed!\nCheck username/password</string>
|
||||
<string name="status_wallet_connect_timeout">Node connection timed out!\nTry again or another.</string>
|
||||
<string name="status_wallet_node_invalid">Node invalid!\nTry another.</string>
|
||||
<string name="status_wallet_connect_ioex">Cannot reach node!\nTry again or another.</string>
|
||||
|
||||
<string name="status_working">Working on it …</string>
|
||||
<string name="status_wallet_disconnected">Disconnected</string>
|
||||
|
||||
|
@@ -179,7 +179,7 @@
|
||||
|
||||
<style name="MoneroButton" parent="@style/Widget.AppCompat.Button">
|
||||
<item name="android:background">@drawable/button_selector</item>
|
||||
<item name="android:textColor">@color/text_color</item>
|
||||
<item name="android:textColor">@color/moneroWhite</item>
|
||||
<item name="android:textAppearance">@style/MoneroLabel</item>
|
||||
<item name="android:textAllCaps">true</item>
|
||||
</style>
|
||||
@@ -194,16 +194,13 @@
|
||||
</style>
|
||||
|
||||
<style name="MoneroButton.ReallySend">
|
||||
<item name="android:textColor">@color/white</item>
|
||||
</style>
|
||||
|
||||
<style name="MoneroButton.Take">
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:background">@color/take</item>
|
||||
</style>
|
||||
|
||||
<style name="MoneroButton.Give">
|
||||
<item name="android:textColor">@color/white</item>
|
||||
<item name="android:background">@color/give</item>
|
||||
</style>
|
||||
|
||||
|
Reference in New Issue
Block a user