From 5c1fa097a9c7566750529f00ae8fb2f86227f29d Mon Sep 17 00:00:00 2001
From: m2049r <30435443+m2049r@users.noreply.github.com>
Date: Sat, 9 Sep 2017 11:39:39 +0200
Subject: [PATCH] show alternative currency (USD/EUR) on receive uses
https://www.kraken.com/help/api#get-ticker-info
---
.../com/m2049r/xmrwallet/LoginActivity.java | 11 +-
.../com/m2049r/xmrwallet/ReceiveFragment.java | 180 ++++++++++++++++--
.../com/m2049r/xmrwallet/WalletActivity.java | 13 +-
.../xmrwallet/util/AsyncExchangeRate.java | 151 +++++++++++++++
.../com/m2049r/xmrwallet/util/Helper.java | 29 ++-
app/src/main/res/layout/receive_fragment.xml | 57 +++---
app/src/main/res/values/strings.xml | 14 +-
app/src/main/res/values/styles.xml | 12 +-
8 files changed, 414 insertions(+), 53 deletions(-)
create mode 100644 app/src/main/java/com/m2049r/xmrwallet/util/AsyncExchangeRate.java
diff --git a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java
index 463c0431..5996953b 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java
@@ -45,6 +45,7 @@ import android.widget.Toast;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.service.WalletService;
+import com.m2049r.xmrwallet.util.AsyncExchangeRate;
import com.m2049r.xmrwallet.util.Helper;
import java.io.File;
@@ -54,7 +55,8 @@ import java.io.IOException;
import java.nio.channels.FileChannel;
public class LoginActivity extends AppCompatActivity
- implements LoginFragment.Listener, GenerateFragment.Listener, GenerateReviewFragment.Listener {
+ implements LoginFragment.Listener, GenerateFragment.Listener,
+ GenerateReviewFragment.Listener, ReceiveFragment.Listener {
static final String TAG = "LoginActivity";
private static final String GENERATE_STACK = "gen";
@@ -700,6 +702,7 @@ public class LoginActivity extends AppCompatActivity
interface WalletCreator {
boolean createWallet(File aFile, String password);
+
}
@Override
@@ -778,6 +781,12 @@ public class LoginActivity extends AppCompatActivity
}
}
+ @Override
+ public void onExchange(AsyncExchangeRate.Listener listener, String currencyA, String currencyB) {
+ new AsyncExchangeRate(listener).execute(currencyA, currencyB);
+ }
+
+
Wallet.Status testWallet(String path, String password) {
Log.d(TAG, "testing wallet " + path);
Wallet aWallet = WalletManager.getInstance().openWallet(path, password);
diff --git a/app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java b/app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java
index efceac14..40459d00 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java
@@ -16,10 +16,13 @@
package com.m2049r.xmrwallet;
+import android.content.Context;
+import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.InputType;
@@ -30,10 +33,12 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
+import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
+import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
@@ -45,24 +50,73 @@ import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
+import com.m2049r.xmrwallet.util.AsyncExchangeRate;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
-public class ReceiveFragment extends Fragment {
+public class ReceiveFragment extends Fragment implements AsyncExchangeRate.Listener {
static final String TAG = "ReceiveFragment";
ProgressBar pbProgress;
TextView tvAddress;
EditText etPaymentId;
EditText etAmount;
+ TextView tvAmountB;
Button bPaymentId;
Button bGenerate;
ImageView qrCode;
EditText etDummy;
+ Spinner sCurrencyA;
+ Spinner sCurrencyB;
+
+ public interface Listener {
+ void onExchange(AsyncExchangeRate.Listener listener, String currencyA, String currencyB);
+ }
+
+ @Override
+ public void exchange(String currencyA, String currencyB, double rate) {
+ // first, make sure this is what we want
+ String enteredCurrencyA = (String) sCurrencyA.getSelectedItem();
+ String enteredCurrencyB = (String) sCurrencyB.getSelectedItem();
+ if (!currencyA.equals(enteredCurrencyA) || !currencyB.equals(enteredCurrencyB)) {
+ // something's wrong
+ Log.e(TAG, "Currencies don't match!");
+ tvAmountB.setText("");
+ return;
+ }
+ String enteredAmount = etAmount.getText().toString();
+ String xmrAmount = "";
+ if (!enteredAmount.isEmpty()) {
+ // losing precision using double here doesn't matter
+ double amountA = Double.parseDouble(enteredAmount);
+ double amountB = amountA * rate;
+ Log.d(TAG, "exchange A=" + amountA + " B=" + amountB);
+ if (enteredCurrencyA.equals("XMR")) {
+ String validatedAmountA = Helper.getDisplayAmount(Wallet.getAmountFromString(enteredAmount));
+ xmrAmount = validatedAmountA; // take what was entered in XMR
+ etAmount.setText(xmrAmount); // display what we stick into the QR code
+ String displayB = String.format(Locale.US, "%.2f", amountB);
+ tvAmountB.setText(displayB);
+ } else if (enteredCurrencyB.equals("XMR")) {
+ xmrAmount = Wallet.getDisplayAmount(Wallet.getAmountFromDouble(amountB));
+ // cut off at 5 decimals
+ xmrAmount = xmrAmount.substring(0, xmrAmount.length() - (12 - 5));
+ tvAmountB.setText(xmrAmount);
+ } else { // no XMR currency
+ tvAmountB.setText("");
+ return; // and no qr code
+ }
+ } else {
+ tvAmountB.setText("");
+ }
+ generateQr(xmrAmount);
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -72,15 +126,21 @@ public class ReceiveFragment extends Fragment {
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
tvAddress = (TextView) view.findViewById(R.id.tvAddress);
etPaymentId = (EditText) view.findViewById(R.id.etPaymentId);
- etAmount = (EditText) view.findViewById(R.id.etAmount);
+ etAmount = (EditText) view.findViewById(R.id.etAmountA);
+ tvAmountB = (TextView) view.findViewById(R.id.tvAmountB);
bPaymentId = (Button) view.findViewById(R.id.bPaymentId);
qrCode = (ImageView) view.findViewById(R.id.qrCode);
bGenerate = (Button) view.findViewById(R.id.bGenerate);
etDummy = (EditText) view.findViewById(R.id.etDummy);
+ sCurrencyA = (Spinner) view.findViewById(R.id.sCurrencyA);
+ sCurrencyB = (Spinner) view.findViewById(R.id.sCurrencyB);
+
etPaymentId.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
+ loadPrefs();
+
etPaymentId.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_NEXT)) {
@@ -117,7 +177,7 @@ public class ReceiveFragment extends Fragment {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
if (paymentIdOk() && amountOk()) {
Helper.hideKeyboard(getActivity());
- generateQr();
+ startExchange();
}
return true;
}
@@ -127,6 +187,7 @@ public class ReceiveFragment extends Fragment {
etAmount.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable editable) {
+ tvAmountB.setText("");
qrCode.setImageBitmap(getMoneroLogo());
if (paymentIdOk() && amountOk()) {
bGenerate.setEnabled(true);
@@ -150,7 +211,7 @@ public class ReceiveFragment extends Fragment {
etPaymentId.setText((Wallet.generatePaymentId()));
etPaymentId.setSelection(etPaymentId.getText().length());
if (paymentIdOk() && amountOk()) {
- generateQr();
+ startExchange();
}
}
});
@@ -160,11 +221,42 @@ public class ReceiveFragment extends Fragment {
public void onClick(View v) {
if (paymentIdOk() && amountOk()) {
Helper.hideKeyboard(getActivity());
- generateQr();
+ startExchange();
}
}
});
+ sCurrencyA.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parentView, View selectedItemView, int position, long id) {
+ if (position != 0) {
+ sCurrencyB.setSelection(0, true);
+ }
+ startExchange();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parentView) {
+ // nothing (yet?)
+ }
+ });
+
+ sCurrencyB.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parentView, View selectedItemView, int position, long id) {
+ if (position != 0) {
+ sCurrencyA.setSelection(0, true);
+ }
+ tvAmountB.setText("");
+ startExchange();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parentView) {
+ // nothing (yet?)
+ }
+ });
+
showProgress();
qrCode.setImageBitmap(getMoneroLogo());
@@ -180,12 +272,26 @@ public class ReceiveFragment extends Fragment {
return view;
}
+ void startExchange() {
+ if (paymentIdOk() && amountOk() && tvAddress.getText().length() > 0) {
+ String enteredCurrencyA = (String) sCurrencyA.getSelectedItem();
+ String enteredCurrencyB = (String) sCurrencyB.getSelectedItem();
+ String enteredAmount = etAmount.getText().toString();
+ tvAmountB.setText("");
+ if (!enteredAmount.isEmpty()) { // start conversion
+ listenerCallback.onExchange(ReceiveFragment.this, enteredCurrencyA, enteredCurrencyB);
+ } else {
+ generateQr("");
+ }
+ }
+ }
+
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
if (paymentIdOk() && amountOk() && tvAddress.getText().length() > 0) {
- generateQr();
+ startExchange();
}
}
@@ -196,7 +302,7 @@ public class ReceiveFragment extends Fragment {
bPaymentId.setEnabled(true);
bGenerate.setEnabled(true);
hideProgress();
- generateQr();
+ startExchange();
}
private void show(String walletPath, String password) {
@@ -245,12 +351,13 @@ public class ReceiveFragment extends Fragment {
return paymentId.isEmpty() || Wallet.isPaymentIdValid(paymentId);
}
- private void generateQr() {
+ private void generateQr(String xmrAmount) {
+ Log.d(TAG, "AMOUNT=" + xmrAmount);
String address = tvAddress.getText().toString();
String paymentId = etPaymentId.getText().toString();
- String enteredAmount = etAmount.getText().toString();
+// String enteredAmount = etAmount.getText().toString();
// that's a lot of converting ...
- String amount = (enteredAmount.isEmpty() ? enteredAmount : Helper.getDisplayAmount(Wallet.getAmountFromString(enteredAmount)));
+ //String amount = (xmrAmount.isEmpty() ? xmrAmount : Helper.getDisplayAmount(Wallet.getAmountFromString(xmrAmount)));
StringBuffer sb = new StringBuffer();
sb.append(ScannerFragment.QR_SCHEME).append(address);
boolean first = true;
@@ -261,18 +368,17 @@ public class ReceiveFragment extends Fragment {
}
sb.append(ScannerFragment.QR_PAYMENTID).append('=').append(paymentId);
}
- if (!amount.isEmpty()) {
+ if (!xmrAmount.isEmpty()) {
if (first) {
sb.append("?");
} else {
sb.append("&");
}
- sb.append(ScannerFragment.QR_AMOUNT).append('=').append(amount);
+ sb.append(ScannerFragment.QR_AMOUNT).append('=').append(xmrAmount);
}
String text = sb.toString();
Bitmap qr = generate(text, 500, 500);
if (qr != null) {
- etAmount.setText(amount);
qrCode.setImageBitmap(qr);
etDummy.requestFocus();
bGenerate.setEnabled(false);
@@ -346,4 +452,52 @@ public class ReceiveFragment extends Fragment {
pbProgress.setVisibility(View.GONE);
}
+ Listener listenerCallback = null;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ if (context instanceof Listener) {
+ this.listenerCallback = (Listener) context;
+ } else {
+ throw new ClassCastException(context.toString()
+ + " must implement Listener");
+ }
+ }
+
+ static final String PREF_CURRENCY_A = "PREF_CURRENCY_A";
+ static final String PREF_CURRENCY_B = "PREF_CURRENCY_B";
+
+ void loadPrefs() {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
+ int currencyA = sharedPreferences.getInt(PREF_CURRENCY_A, 0);
+ int currencyB = sharedPreferences.getInt(PREF_CURRENCY_B, 0);
+
+ if (currencyA * currencyB != 0) { // make sure one of them is 0 (=XMR)
+ currencyA = 0;
+ }
+ // in case we change the currency lists in the future
+ if (currencyA >= sCurrencyA.getCount()) currencyA = 0;
+ if (currencyB >= sCurrencyB.getCount()) currencyB = 0;
+ sCurrencyA.setSelection(currencyA);
+ sCurrencyB.setSelection(currencyB);
+ }
+
+ void savePrefs() {
+ int currencyA = sCurrencyA.getSelectedItemPosition();
+ int currencyB = sCurrencyB.getSelectedItemPosition();
+
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putInt(PREF_CURRENCY_A, currencyA);
+ editor.putInt(PREF_CURRENCY_B, currencyB);
+ editor.apply();
+ }
+
+ @Override
+ public void onPause() {
+ Log.d(TAG, "onPause()");
+ savePrefs();
+ super.onPause();
+ }
}
diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
index 2ebed53c..7704d48d 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
@@ -17,6 +17,7 @@
package com.m2049r.xmrwallet;
import android.app.AlertDialog;
+import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
@@ -24,6 +25,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
@@ -42,17 +44,22 @@ import com.m2049r.xmrwallet.model.TransactionInfo;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.service.WalletService;
+import com.m2049r.xmrwallet.util.AsyncExchangeRate;
import com.m2049r.xmrwallet.util.BarcodeData;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.TxData;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class WalletActivity extends AppCompatActivity implements WalletFragment.Listener,
WalletService.Observer, SendFragment.Listener, TxFragment.Listener,
GenerateReviewFragment.ListenerWithWallet,
- ScannerFragment.Listener {
+ ScannerFragment.Listener, ReceiveFragment.Listener {
private static final String TAG = "WalletActivity";
public static final String REQUEST_ID = "id";
@@ -741,4 +748,8 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
Log.d(TAG, "ReceiveFragment placed");
}
+ @Override
+ public void onExchange(AsyncExchangeRate.Listener listener, String currencyA, String currencyB) {
+ new AsyncExchangeRate(listener).execute(currencyA, currencyB);
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/AsyncExchangeRate.java b/app/src/main/java/com/m2049r/xmrwallet/util/AsyncExchangeRate.java
new file mode 100644
index 00000000..0c724d1a
--- /dev/null
+++ b/app/src/main/java/com/m2049r/xmrwallet/util/AsyncExchangeRate.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017 m2049r
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.m2049r.xmrwallet.util;
+
+import android.os.AsyncTask;
+import android.util.Log;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class AsyncExchangeRate extends AsyncTask {
+ static final String TAG = "AsyncGetExchangeRate";
+
+ static final long TIME_REFRESH_INTERVAL = 60000; // refresh exchange rate max every minute
+
+ static protected long RateTime = 0;
+ static protected double Rate = 0;
+ static protected String Fiat = null;
+
+ public interface Listener {
+ void exchange(String currencyA, String currencyB, double rate);
+ }
+
+ Listener listener;
+
+ public AsyncExchangeRate(Listener listener) {
+ super();
+ this.listener = listener;
+ }
+
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ boolean inverse = false;
+ String currencyA = null;
+ String currencyB = null;
+
+ @Override
+ protected Boolean doInBackground(String... params) {
+ if (params.length != 2) return false;
+ Log.d(TAG, "Getting " + params[0]);
+ currencyA = params[0];
+ currencyB = params[1];
+
+ String fiat = null;
+ if (currencyA.equals("XMR")) {
+ fiat = currencyB;
+ inverse = false;
+ }
+ if (currencyB.equals("XMR")) {
+ fiat = currencyA;
+ inverse = true;
+ }
+
+ if (currencyA.equals(currencyB)) {
+ Fiat = null;
+ Rate = 1;
+ RateTime = System.currentTimeMillis();
+ return true;
+ }
+
+ if (fiat == null) {
+ Fiat = null;
+ Rate = 0;
+ RateTime = 0;
+ return false;
+ }
+
+ if (!fiat.equals(Fiat)) { // new currency - reset all
+ Fiat = fiat;
+ Rate = 0;
+ RateTime = 0;
+ }
+
+ if (System.currentTimeMillis() > RateTime + TIME_REFRESH_INTERVAL) {
+ Log.d(TAG, "Fetching " + Fiat);
+ String closePrice = getExchangeRate(Fiat);
+ if (closePrice != null) {
+ try {
+ Rate = Double.parseDouble(closePrice);
+ RateTime = System.currentTimeMillis();
+ return true;
+ } catch (NumberFormatException ex) {
+ Rate = 0;
+ Log.e(TAG, ex.getLocalizedMessage());
+ return false;
+ }
+ } else {
+ Rate = 0;
+ Log.e(TAG, "exchange url failed");
+ return false;
+ }
+ }
+ return true; // no change but still valid
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ super.onPostExecute(result);
+ if (result) {
+ Log.d(TAG, "yay! = " + Rate);
+ if (listener != null) {
+ listener.exchange(currencyA, currencyB, inverse ? (1 / Rate) : Rate);
+ }
+ } else {
+ Log.d(TAG, "nay!");
+ }
+ }
+
+ String getExchangeRate(String fiat) {
+ String jsonResponse =
+ Helper.getUrl("https://api.kraken.com/0/public/Ticker?pair=XMR" + fiat);
+ if (jsonResponse == null) return null;
+ try {
+ JSONObject response = new JSONObject(jsonResponse);
+ JSONArray errors = response.getJSONArray("error");
+ Log.e(TAG, "errors=" + errors.toString());
+ if (errors.length() == 0) {
+ JSONObject result = response.getJSONObject("result");
+ JSONObject pair = result.getJSONObject("XXMRZ" + fiat);
+ JSONArray close = pair.getJSONArray("c");
+ String closePrice = close.getString(0);
+ Log.d(TAG, "closePrice=" + closePrice);
+ return closePrice;
+ }
+ } catch (JSONException ex) {
+ Log.e(TAG, ex.getLocalizedMessage());
+ }
+ return null;
+ }
+
+ // "https://api.kraken.com/0/public/Ticker?pair=XMREUR"
+}
\ No newline at end of file
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 23458cb6..9c876d88 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java
@@ -35,13 +35,10 @@ import android.view.inputmethod.InputMethodManager;
import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.model.Wallet;
-import com.m2049r.xmrwallet.model.WalletManager;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
@@ -193,4 +190,30 @@ public class Helper {
return bitmap;
}
+ static public String getUrl(String httpsUrl) {
+ HttpsURLConnection urlConnection = null;
+ try {
+ URL url = new URL(httpsUrl);
+ urlConnection = (HttpsURLConnection) url.openConnection();
+ InputStreamReader in = new InputStreamReader(urlConnection.getInputStream());
+ StringBuffer sb = new StringBuffer();
+ final int BUFFER_SIZE = 512;
+ char[] buffer = new char[BUFFER_SIZE];
+ int length = in.read(buffer, 0, BUFFER_SIZE);
+ while (length >= 0) {
+ sb.append(buffer, 0, length);
+ length = in.read(buffer, 0, BUFFER_SIZE);
+ }
+ return sb.toString();
+ } catch (MalformedURLException ex) {
+ Log.e(TAG, "A " + ex.getLocalizedMessage());
+ } catch (IOException ex) {
+ Log.e(TAG, "B " + ex.getLocalizedMessage());
+ } finally {
+ if (urlConnection != null) {
+ urlConnection.disconnect();
+ }
+ }
+ return null;
+ }
}
diff --git a/app/src/main/res/layout/receive_fragment.xml b/app/src/main/res/layout/receive_fragment.xml
index 5e88ef32..8d110439 100644
--- a/app/src/main/res/layout/receive_fragment.xml
+++ b/app/src/main/res/layout/receive_fragment.xml
@@ -35,26 +35,17 @@
android:orientation="horizontal"
android:weightSum="10">
-
-
+ android:textAlignment="center" />
Date
- p+ %1$s unconfirmed
+ + %1$s unconfirmed
%1$s XMR
Transactions
Daemon connected!
@@ -177,9 +177,9 @@
Show me the QR Code
Generate
PaymentID
- (optional)
- Amount
- XMR (optional)
+ Payment ID (optional)
+ Amount
+ XMR
Could not open wallet!
Sensitive data will now be shown.\nLook over your shoulder!
@@ -205,4 +205,10 @@
- Medium Priority
- High Priority
+
+
+ - XMR
+ - EUR
+ - USD
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 9b99ba40..3181df2c 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -17,7 +17,7 @@
@@ -48,13 +47,16 @@
- ?colorPrimary
-
+
+
+