mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-04 17:28:42 +02:00
Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bafe05117b | ||
![]() |
4b7c181040 | ||
![]() |
a3721ae784 | ||
![]() |
ae62c528aa | ||
![]() |
e6522769d0 | ||
![]() |
cab93e8c5e | ||
![]() |
ac78ecb298 | ||
![]() |
51876f788f | ||
![]() |
82c32d4442 | ||
![]() |
22b4905828 | ||
![]() |
0cb8ece336 | ||
![]() |
d2429da044 | ||
![]() |
92d867fbaa | ||
![]() |
a5e3986eb9 | ||
![]() |
8f7f4ee9f9 | ||
![]() |
c23597066a | ||
![]() |
dab5e08910 | ||
![]() |
c35deab283 | ||
![]() |
7c36ccfd9c | ||
![]() |
402d51ec6e | ||
![]() |
ca58211676 | ||
![]() |
97c6ba5334 | ||
![]() |
f1f2f250be | ||
![]() |
7b19e9a2bd | ||
![]() |
ed8010c92c | ||
![]() |
41580e5519 | ||
![]() |
1875e2df62 | ||
![]() |
347123d961 | ||
![]() |
f5ad07c2b0 | ||
![]() |
62695af9c6 | ||
![]() |
3b1c3d564b | ||
![]() |
b28a140b48 | ||
![]() |
75bba4a091 |
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 25
|
||||
versionCode 39
|
||||
versionName "1.2"
|
||||
versionCode 51
|
||||
versionName "1.2.11"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
@@ -43,28 +43,39 @@ dependencies {
|
||||
compile 'com.android.support:cardview-v7:25.4.0'
|
||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||
compile 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||
|
||||
compile "com.squareup.okhttp3:okhttp:$rootProject.ext.okHttpVersion"
|
||||
compile "com.jakewharton.timber:timber:$rootProject.ext.timberVersion"
|
||||
|
||||
testCompile "junit:junit:$rootProject.ext.junitVersion"
|
||||
testCompile "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
||||
testCompile "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
|
||||
testCompile 'org.json:json:20140107'
|
||||
testCompile 'net.jodah:concurrentunit:0.4.2'
|
||||
}
|
||||
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'com.android.support:appcompat-v7:70551e62660db15b790c5275f56b9de4dd9407d1494d07c8f3dd5698f3638677',
|
||||
'com.android.support:design:3f409bf2019967ffc344cfaf11e52131fac982468a1707aaeb25bf3c52838966',
|
||||
'com.android.support:appcompat-v7:70551e62660db15b790c5275f56b9de4dd9407d1494d07c8f3dd5698f3638677',
|
||||
'com.android.support:transition:848270144fb180efd2bf928a00ed176dbbc5290badfd638390ffba90088df8b3',
|
||||
'me.dm7.barcodescanner:zxing:d43973c9527c23fa8e6d338c6a2c458e373ce1ac6bcaa3bc41d11ae49116000d',
|
||||
'me.dm7.barcodescanner:core:a5c8a704089b58029db166172ed8e55d756877d010a85a0b1c94fdc96ffb8f9a',
|
||||
'com.android.support:support-v4:ee44c481a1f4d6978568e223e8125379b52b2ececdd53450e09ebae144bd377d',
|
||||
'com.android.support:recyclerview-v7:a2fe121f9d01ed8980e97095b4a3fe9700a0aa0a7d4b0f8c594f765ad8455a0d',
|
||||
'com.android.support:cardview-v7:f3fbbe1fcfdbec7333c6a2c516c5fd511a909d1975271818e268d6fe297d8c70',
|
||||
'com.android.support.constraint:constraint-layout:b0c688cc2b7172608f8153a689d746da40f71e52d7e2fe2bfd9df2f92db77085',
|
||||
'me.dm7.barcodescanner:zxing:d43973c9527c23fa8e6d338c6a2c458e373ce1ac6bcaa3bc41d11ae49116000d',
|
||||
'com.android.support:support-annotations:a774272036941b4e912eb426d70c848bde7f06a3bf5fb491f75a427dc6595270',
|
||||
'com.android.support:support-vector-drawable:077009d13882ee96f061e4bc2dbe7cce7ae1762d8297592a787ff741afbfb1f2',
|
||||
'com.android.support:animated-vector-drawable:628ab1d56a6ee4cbedf32617af8b2a1fe02964ed0628e8f898cc09ddba6e1835',
|
||||
'com.android.support:transition:848270144fb180efd2bf928a00ed176dbbc5290badfd638390ffba90088df8b3',
|
||||
'com.android.support:support-compat:54019c63614ce08b02d7b9605490cd2b29ba5b2505f394a9517450b5f72b30ca',
|
||||
'com.android.support:support-vector-drawable:077009d13882ee96f061e4bc2dbe7cce7ae1762d8297592a787ff741afbfb1f2',
|
||||
'com.android.support:support-fragment:316d35d4d2d2902057efad104a73e4bdb50bee260a7075678185b8cd71170945',
|
||||
'com.android.support:support-core-ui:e72ae29b823889686cff6fcb948d6745c2baf6d4c2af4fdffa1ec1e42e3833a3',
|
||||
'com.android.support:support-media-compat:566a161d9cb0083ef62a53e46b71ce5b3d455b8635b1a0a4ae28d96d4b583de8',
|
||||
'com.android.support:support-core-utils:34b8437dfa95ff28d29cf57ffa3b1354a9fa9bfe4059f0fd5ce2f5e4326a1748',
|
||||
'com.android.support:support-core-ui:e72ae29b823889686cff6fcb948d6745c2baf6d4c2af4fdffa1ec1e42e3833a3',
|
||||
'com.android.support:support-fragment:316d35d4d2d2902057efad104a73e4bdb50bee260a7075678185b8cd71170945',
|
||||
'com.android.support:support-compat:54019c63614ce08b02d7b9605490cd2b29ba5b2505f394a9517450b5f72b30ca',
|
||||
'com.android.support:support-annotations:a774272036941b4e912eb426d70c848bde7f06a3bf5fb491f75a427dc6595270',
|
||||
'com.android.support.constraint:constraint-layout-solver:8c62525a9bc5cff5633a96cb9b32fffeccaf41b8841aa87fc22607070dea9b8d',
|
||||
'me.dm7.barcodescanner:core:a5c8a704089b58029db166172ed8e55d756877d010a85a0b1c94fdc96ffb8f9a',
|
||||
'com.google.zxing:core:bba7724e02a997cec38213af77133ee8e24b0d5cf5fa7ecbc16a4fa93f11ee0d',
|
||||
'com.squareup.okio:okio:734269c3ebc5090e3b23566db558f421f0b4027277c79ad5d176b8ec168bb850',
|
||||
'com.squareup.okhttp3:okhttp:7265adbd6f028aade307f58569d814835cd02bc9beffb70c25f72c9de50d61c4',
|
||||
]
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:name=".XmrWalletApplication"
|
||||
android:theme="@style/MyMaterialTheme">
|
||||
|
||||
<activity
|
||||
|
@@ -22,7 +22,6 @@ import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@@ -33,15 +32,16 @@ import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class GenerateFragment extends Fragment {
|
||||
static final String TAG = "GenerateFragment";
|
||||
|
||||
static final String TYPE = "type";
|
||||
static final String TYPE_NEW = "new";
|
||||
@@ -366,7 +366,7 @@ public class GenerateFragment extends Fragment {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.d(TAG, "onResume()");
|
||||
Timber.d("onResume()");
|
||||
activityCallback.setTitle(getString(R.string.generate_title) + " - " + getType());
|
||||
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||
|
||||
@@ -383,7 +383,7 @@ public class GenerateFragment extends Fragment {
|
||||
case TYPE_VIEWONLY:
|
||||
return getString(R.string.generate_wallet_type_view);
|
||||
default:
|
||||
Log.e(TAG, "unknown type " + type);
|
||||
Timber.e("unknown type %s", type);
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,6 @@ import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@@ -35,14 +34,15 @@ import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class GenerateReviewFragment extends Fragment {
|
||||
static final String TAG = "GenerateReviewFragment";
|
||||
static final public String VIEW_TYPE_DETAILS = "details";
|
||||
static final public String VIEW_TYPE_ACCEPT = "accept";
|
||||
static final public String VIEW_TYPE_WALLET = "wallet";
|
||||
@@ -264,7 +264,7 @@ public class GenerateReviewFragment extends Fragment {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.d(TAG, "onResume()");
|
||||
Timber.d("onResume()");
|
||||
String name = tvWalletName.getText().toString();
|
||||
if (name.isEmpty()) name = null;
|
||||
activityCallback.setTitle(name, getString(R.string.details_title));
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,6 @@ import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@@ -44,20 +43,21 @@ import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.layout.DropDownEditText;
|
||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.NodeList;
|
||||
import com.m2049r.xmrwallet.widget.DropDownEditText;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInteractionListener,
|
||||
View.OnClickListener {
|
||||
private static final String TAG = "LoginFragment";
|
||||
|
||||
private WalletInfoAdapter adapter;
|
||||
|
||||
@@ -112,7 +112,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
Log.d(TAG, "onPause()");
|
||||
Timber.d("onPause()");
|
||||
savePrefs();
|
||||
super.onPause();
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.d(TAG, "onResume()");
|
||||
Timber.d("onResume()");
|
||||
activityCallback.setTitle(null);
|
||||
activityCallback.setToolbarButton(Toolbar.BUTTON_DONATE);
|
||||
activityCallback.showNet(isTestnet());
|
||||
@@ -129,7 +129,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
Log.d(TAG, "onCreateView");
|
||||
Timber.d("onCreateView");
|
||||
View view = inflater.inflate(R.layout.fragment_login, container, false);
|
||||
|
||||
ivGunther = (ImageView) view.findViewById(R.id.ivGunther);
|
||||
@@ -262,7 +262,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
}
|
||||
|
||||
public void loadList() {
|
||||
Log.d(TAG, "loadList()");
|
||||
Timber.d("loadList()");
|
||||
WalletManager mgr = WalletManager.getInstance();
|
||||
List<WalletManager.WalletInfo> walletInfos =
|
||||
mgr.findWallets(activityCallback.getStorageRoot());
|
||||
@@ -315,7 +315,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
}
|
||||
|
||||
public boolean onTestnetMenuItem() {
|
||||
boolean lastState = testnet;//item.isChecked();
|
||||
boolean lastState = testnet;
|
||||
setNet(!lastState, true); // set and save
|
||||
return !lastState;
|
||||
}
|
||||
@@ -336,7 +336,6 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
|
||||
private static final String PREF_DAEMON_TESTNET = "daemon_testnet";
|
||||
private static final String PREF_DAEMON_MAINNET = "daemon_mainnet";
|
||||
//private static final String PREF_TESTNET = "testnet";
|
||||
|
||||
private static final String PREF_DAEMONLIST_MAINNET =
|
||||
"node.moneroworld.com:18089;node.xmrbackb.one;node.xmr.be";
|
||||
@@ -360,7 +359,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
}
|
||||
|
||||
void savePrefs(boolean usePreviousState) {
|
||||
Log.d(TAG, "SAVE / " + usePreviousState);
|
||||
Timber.d("SAVE / %s", usePreviousState);
|
||||
// save the daemon address for the net
|
||||
boolean testnet = isTestnet() ^ usePreviousState;
|
||||
String daemon = getDaemon();
|
||||
@@ -372,7 +371,6 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
|
||||
SharedPreferences sharedPref = activityCallback.getPrefs();
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
//editor.putBoolean(PREF_TESTNET, testnet);
|
||||
editor.putString(PREF_DAEMON_MAINNET, daemonMainNet.toString());
|
||||
editor.putString(PREF_DAEMON_TESTNET, daemonTestNet.toString());
|
||||
editor.apply();
|
||||
@@ -383,7 +381,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
}
|
||||
|
||||
void setDaemon(NodeList nodeList) {
|
||||
Log.d(TAG, "setDaemon() " + nodeList.toString());
|
||||
Timber.d("setDaemon() %s", nodeList.toString());
|
||||
String[] nodes = nodeList.getNodes().toArray(new String[0]);
|
||||
nodeAdapter.clear();
|
||||
nodeAdapter.addAll(nodes);
|
||||
|
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public interface OnBackPressedListener {
|
||||
boolean onBackPressed();
|
||||
}
|
@@ -19,6 +19,7 @@ package com.m2049r.xmrwallet;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
@@ -26,7 +27,6 @@ import android.support.v4.app.Fragment;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -46,31 +46,31 @@ import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.qrcode.QRCodeWriter;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
import com.m2049r.xmrwallet.layout.ExchangeView;
|
||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||
import com.m2049r.xmrwallet.widget.ExchangeView;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class ReceiveFragment extends Fragment {
|
||||
static final String TAG = "ReceiveFragment";
|
||||
|
||||
private ProgressBar pbProgress;
|
||||
private TextView tvAddress;
|
||||
private TextInputLayout etPaymentId;
|
||||
private ExchangeView evAmount;
|
||||
private Button bPaymentId;
|
||||
private Button bGenerate;
|
||||
private TextView tvQrCode;
|
||||
private ImageView qrCode;
|
||||
private ImageView qrCodeFull;
|
||||
private EditText etDummy;
|
||||
private ImageButton bCopyAddress;
|
||||
|
||||
//String name;
|
||||
|
||||
public interface Listener {
|
||||
void setToolbarButton(int type);
|
||||
|
||||
@@ -91,7 +91,8 @@ public class ReceiveFragment extends Fragment {
|
||||
evAmount = (ExchangeView) view.findViewById(R.id.evAmount);
|
||||
bPaymentId = (Button) view.findViewById(R.id.bPaymentId);
|
||||
qrCode = (ImageView) view.findViewById(R.id.qrCode);
|
||||
bGenerate = (Button) view.findViewById(R.id.bGenerate);
|
||||
tvQrCode = (TextView) view.findViewById(R.id.tvQrCode);
|
||||
qrCodeFull = (ImageView) view.findViewById(R.id.qrCodeFull);
|
||||
etDummy = (EditText) view.findViewById(R.id.etDummy);
|
||||
bCopyAddress = (ImageButton) view.findViewById(R.id.bCopyAddress);
|
||||
|
||||
@@ -108,7 +109,7 @@ public class ReceiveFragment extends Fragment {
|
||||
evAmount.setOnNewAmountListener(new ExchangeView.OnNewAmountListener() {
|
||||
@Override
|
||||
public void onNewAmount(String xmr) {
|
||||
Log.d(TAG, "new amount = " + xmr);
|
||||
Timber.d("new amount = %s", xmr);
|
||||
generateQr();
|
||||
}
|
||||
});
|
||||
@@ -116,8 +117,10 @@ public class ReceiveFragment extends Fragment {
|
||||
evAmount.setOnFailedExchangeListener(new ExchangeView.OnFailedExchangeListener() {
|
||||
@Override
|
||||
public void onFailedExchange() {
|
||||
clearQR();
|
||||
Toast.makeText(getActivity(), getString(R.string.message_exchange_failed), Toast.LENGTH_LONG).show();
|
||||
if (isAdded()) {
|
||||
clearQR();
|
||||
Toast.makeText(getActivity(), getString(R.string.message_exchange_failed), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -146,7 +149,6 @@ public class ReceiveFragment extends Fragment {
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
|
||||
bPaymentId.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -158,22 +160,33 @@ public class ReceiveFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
bGenerate.setOnClickListener(new View.OnClickListener() {
|
||||
qrCode.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (checkPaymentId()) {
|
||||
if (qrValid) {
|
||||
qrCodeFull.setImageBitmap(((BitmapDrawable) qrCode.getDrawable()).getBitmap());
|
||||
qrCodeFull.setVisibility(View.VISIBLE);
|
||||
} else if (checkPaymentId()) {
|
||||
evAmount.doExchange();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
qrCodeFull.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
qrCodeFull.setImageBitmap(null);
|
||||
qrCodeFull.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
showProgress();
|
||||
clearQR();
|
||||
|
||||
Bundle b = getArguments();
|
||||
String address = b.getString("address");
|
||||
String walletName = b.getString("name");
|
||||
Log.d(TAG, "address=" + address + "/name=" + walletName);
|
||||
Timber.d("%s/%s", address, walletName);
|
||||
if (address == null) {
|
||||
String path = b.getString("path");
|
||||
String password = b.getString("password");
|
||||
@@ -193,14 +206,17 @@ public class ReceiveFragment extends Fragment {
|
||||
|
||||
void clearQR() {
|
||||
if (qrValid) {
|
||||
qrCode.setImageBitmap(getMoneroLogo());
|
||||
qrCode.setImageBitmap(null);
|
||||
qrValid = false;
|
||||
if (isLoaded)
|
||||
tvQrCode.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
void setQR(Bitmap qr) {
|
||||
qrCode.setImageBitmap(qr);
|
||||
qrValid = true;
|
||||
tvQrCode.setVisibility(View.INVISIBLE);
|
||||
Helper.hideKeyboard(getActivity());
|
||||
etDummy.requestFocus();
|
||||
}
|
||||
@@ -208,20 +224,21 @@ public class ReceiveFragment extends Fragment {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.d(TAG, "onResume()");
|
||||
Timber.d("onResume()");
|
||||
listenerCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||
listenerCallback.setSubtitle(getString(R.string.receive_title));
|
||||
generateQr();
|
||||
}
|
||||
|
||||
private boolean isLoaded = false;
|
||||
|
||||
private void show(String name, String address) {
|
||||
Log.d(TAG, "name=" + name);
|
||||
Timber.d("name=%s", name);
|
||||
isLoaded = true;
|
||||
listenerCallback.setTitle(name);
|
||||
tvAddress.setText(address);
|
||||
etPaymentId.setEnabled(true);
|
||||
//etAmount.setEnabled(true);
|
||||
bPaymentId.setEnabled(true);
|
||||
bGenerate.setEnabled(true);
|
||||
bCopyAddress.setEnabled(true);
|
||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||
hideProgress();
|
||||
@@ -276,14 +293,14 @@ public class ReceiveFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void generateQr() {
|
||||
Log.d(TAG, "GENQR");
|
||||
Timber.d("GENQR");
|
||||
String address = tvAddress.getText().toString();
|
||||
String paymentId = etPaymentId.getEditText().getText().toString();
|
||||
String xmrAmount = evAmount.getAmount();
|
||||
Log.d(TAG, xmrAmount + "/" + paymentId + "/" + address);
|
||||
Timber.d("%s/%s/%s", xmrAmount, paymentId, address);
|
||||
if ((xmrAmount == null) || !Wallet.isAddressValid(address, WalletManager.getInstance().isTestNet())) {
|
||||
clearQR();
|
||||
Log.d(TAG, "CLEARQR");
|
||||
Timber.d("CLEARQR");
|
||||
return;
|
||||
}
|
||||
StringBuffer sb = new StringBuffer();
|
||||
@@ -305,10 +322,11 @@ public class ReceiveFragment extends Fragment {
|
||||
sb.append(ScannerFragment.QR_AMOUNT).append('=').append(xmrAmount);
|
||||
}
|
||||
String text = sb.toString();
|
||||
Bitmap qr = generate(text, 500, 500);
|
||||
int size = Math.min(qrCode.getHeight(), qrCode.getWidth());
|
||||
Bitmap qr = generate(text, size, size);
|
||||
if (qr != null) {
|
||||
setQR(qr);
|
||||
Log.d(TAG, "SETQR");
|
||||
Timber.d("SETQR");
|
||||
etDummy.requestFocus();
|
||||
Helper.hideKeyboard(getActivity());
|
||||
}
|
||||
@@ -339,7 +357,6 @@ public class ReceiveFragment extends Fragment {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO check if we can sensibly cache some of this
|
||||
private Bitmap addLogo(Bitmap qrBitmap) {
|
||||
Bitmap logo = getMoneroLogo();
|
||||
int qrWidth = qrBitmap.getWidth();
|
||||
@@ -393,12 +410,9 @@ public class ReceiveFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
static final String PREF_CURRENCY_A = "PREF_CURRENCY_A";
|
||||
static final String PREF_CURRENCY_B = "PREF_CURRENCY_B";
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
Log.d(TAG, "onPause()");
|
||||
Timber.d("onPause()");
|
||||
super.onPause();
|
||||
}
|
||||
}
|
||||
|
@@ -20,7 +20,6 @@ import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -30,21 +29,21 @@ import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.Result;
|
||||
|
||||
import me.dm7.barcodescanner.zxing.ZXingScannerView;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class ScannerFragment extends Fragment implements ZXingScannerView.ResultHandler {
|
||||
static final String TAG = "ScannerFragment";
|
||||
|
||||
private Listener activityCallback;
|
||||
private OnScannedListener onScannedListener;
|
||||
|
||||
public interface Listener {
|
||||
boolean onAddressScanned(String uri);
|
||||
public interface OnScannedListener {
|
||||
boolean onScanned(String uri);
|
||||
}
|
||||
|
||||
private ZXingScannerView mScannerView;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
Log.d(TAG, "onCreateView");
|
||||
Timber.d("onCreateView");
|
||||
mScannerView = new ZXingScannerView(getActivity());
|
||||
return mScannerView;
|
||||
}
|
||||
@@ -52,7 +51,7 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.d(TAG, "onResume");
|
||||
Timber.d("onResume");
|
||||
mScannerView.setResultHandler(this);
|
||||
mScannerView.startCamera();
|
||||
}
|
||||
@@ -63,9 +62,8 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
|
||||
@Override
|
||||
public void handleResult(Result rawResult) {
|
||||
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE) &&
|
||||
(rawResult.getText().startsWith(QR_SCHEME))) {
|
||||
if (activityCallback.onAddressScanned(rawResult.getText())) {
|
||||
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE)) {
|
||||
if (onScannedListener.onScanned(rawResult.getText())) {
|
||||
return;
|
||||
} else {
|
||||
Toast.makeText(getActivity(), getString(R.string.send_qr_address_invalid), Toast.LENGTH_SHORT).show();
|
||||
@@ -91,7 +89,7 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
Log.d(TAG, "onPause");
|
||||
Timber.d("onPause");
|
||||
mScannerView.stopCamera();
|
||||
super.onPause();
|
||||
}
|
||||
@@ -99,11 +97,11 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof Listener) {
|
||||
this.activityCallback = (Listener) context;
|
||||
if (context instanceof OnScannedListener) {
|
||||
this.onScannedListener = (OnScannedListener) context;
|
||||
} else {
|
||||
throw new ClassCastException(context.toString()
|
||||
+ " must implement Listener");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
app/src/main/java/com/m2049r/xmrwallet/SecureActivity.java
Normal file
35
app/src/main/java/com/m2049r/xmrwallet/SecureActivity.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams;
|
||||
|
||||
public abstract class SecureActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// set FLAG_SECURE to prevent screenshots in Release Mode
|
||||
if (!BuildConfig.DEBUG) {
|
||||
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||
import com.m2049r.xmrwallet.widget.ExchangeTextView;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.widget.NumberPadView;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class SendAmountWizardFragment extends SendWizardFragment {
|
||||
|
||||
public static SendAmountWizardFragment newInstance(Listener listener) {
|
||||
SendAmountWizardFragment instance = new SendAmountWizardFragment();
|
||||
instance.setSendListener(listener);
|
||||
return instance;
|
||||
}
|
||||
|
||||
Listener sendListener;
|
||||
|
||||
public SendAmountWizardFragment setSendListener(Listener listener) {
|
||||
this.sendListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
SendFragment.Listener getActivityCallback();
|
||||
|
||||
void setAmount(final long amount);
|
||||
|
||||
BarcodeData popBarcodeData();
|
||||
}
|
||||
|
||||
private TextView tvFunds;
|
||||
private ExchangeTextView evAmount;
|
||||
//private Button bSendAll;
|
||||
private NumberPadView numberPad;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
Timber.d("onCreateView() %s", (String.valueOf(savedInstanceState)));
|
||||
|
||||
sendListener = (Listener) getParentFragment();
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_send_amount, container, false);
|
||||
|
||||
tvFunds = (TextView) view.findViewById(R.id.tvFunds);
|
||||
|
||||
evAmount = (ExchangeTextView) view.findViewById(R.id.evAmount);
|
||||
numberPad = (NumberPadView) view.findViewById(R.id.numberPad);
|
||||
numberPad.setListener(evAmount);
|
||||
|
||||
/*
|
||||
bSendAll = (Button) view.findViewById(R.id.bSendAll);
|
||||
bSendAll.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// TODO: send all - figure out how to display this
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
Helper.hideKeyboard(getActivity());
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onValidateFields() {
|
||||
if (!evAmount.validate(maxFunds)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sendListener != null) {
|
||||
String xmr = evAmount.getAmount();
|
||||
if (xmr != null) {
|
||||
sendListener.setAmount(Wallet.getAmountFromString(xmr));
|
||||
} else {
|
||||
sendListener.setAmount(0L);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
double maxFunds = 0;
|
||||
|
||||
@Override
|
||||
public void onResumeFragment() {
|
||||
super.onResumeFragment();
|
||||
Timber.d("onResumeFragment()");
|
||||
Helper.hideKeyboard(getActivity());
|
||||
final long funds = getTotalFunds();
|
||||
maxFunds = 1.0 * funds / 1000000000000L;
|
||||
tvFunds.setText(getString(R.string.send_available,
|
||||
Wallet.getDisplayAmount(funds)));
|
||||
// getAmount is null if exchange is in progress
|
||||
if ((evAmount.getAmount() != null) && evAmount.getAmount().isEmpty()) {
|
||||
final BarcodeData data = sendListener.popBarcodeData();
|
||||
if ((data != null) && (data.amount != null)) {
|
||||
evAmount.setAmount(data.amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long getTotalFunds() {
|
||||
return sendListener.getActivityCallback().getTotalFunds();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class SendSettingsWizardFragment extends SendWizardFragment {
|
||||
|
||||
public static SendSettingsWizardFragment newInstance(Listener listener) {
|
||||
SendSettingsWizardFragment instance = new SendSettingsWizardFragment();
|
||||
instance.setSendListener(listener);
|
||||
return instance;
|
||||
}
|
||||
|
||||
Listener sendListener;
|
||||
|
||||
public SendSettingsWizardFragment setSendListener(Listener listener) {
|
||||
this.sendListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
|
||||
void setPriority(final PendingTransaction.Priority priority);
|
||||
|
||||
void setMixin(final int mixin);
|
||||
|
||||
void setNotes(final String notes);
|
||||
}
|
||||
|
||||
final static int Mixins[] = {4, 7, 12, 25}; // must match the layout XML
|
||||
final static PendingTransaction.Priority Priorities[] =
|
||||
{PendingTransaction.Priority.Priority_Default,
|
||||
PendingTransaction.Priority.Priority_Low,
|
||||
PendingTransaction.Priority.Priority_Medium,
|
||||
PendingTransaction.Priority.Priority_High}; // must match the layout XML
|
||||
|
||||
private Spinner sMixin;
|
||||
private Spinner sPriority;
|
||||
private EditText etNotes;
|
||||
private EditText etDummy;
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
Timber.d("onCreateView() %s", (String.valueOf(savedInstanceState)));
|
||||
|
||||
View view = inflater.inflate(
|
||||
R.layout.fragment_send_settings, container, false);
|
||||
|
||||
sMixin = (Spinner) view.findViewById(R.id.sMixin);
|
||||
sPriority = (Spinner) view.findViewById(R.id.sPriority);
|
||||
|
||||
etNotes = (EditText) view.findViewById(R.id.etNotes);
|
||||
etNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||
etNotes.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)) {
|
||||
etDummy.requestFocus();
|
||||
Helper.hideKeyboard(getActivity());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
etDummy = (EditText) view.findViewById(R.id.etDummy);
|
||||
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onValidateFields() {
|
||||
if (sendListener != null) {
|
||||
int mixin = Mixins[sMixin.getSelectedItemPosition()];
|
||||
int priorityIndex = sPriority.getSelectedItemPosition();
|
||||
PendingTransaction.Priority priority = Priorities[priorityIndex];
|
||||
sendListener.setPriority(priority);
|
||||
sendListener.setMixin(mixin);
|
||||
String notes = etNotes.getText().toString();
|
||||
sendListener.setNotes(notes);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResumeFragment() {
|
||||
super.onResumeFragment();
|
||||
Timber.d("onResumeFragment()");
|
||||
Helper.hideKeyboard(getActivity());
|
||||
etDummy.requestFocus();
|
||||
}
|
||||
}
|
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.data.PendingTx;
|
||||
import com.m2049r.xmrwallet.data.TxData;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class SendSuccessWizardFragment extends SendWizardFragment {
|
||||
|
||||
public static SendSuccessWizardFragment newInstance(Listener listener) {
|
||||
SendSuccessWizardFragment instance = new SendSuccessWizardFragment();
|
||||
instance.setSendListener(listener);
|
||||
return instance;
|
||||
}
|
||||
|
||||
Listener sendListener;
|
||||
|
||||
public SendSuccessWizardFragment setSendListener(Listener listener) {
|
||||
this.sendListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
String getNotes();
|
||||
|
||||
TxData getTxData();
|
||||
|
||||
PendingTx getCommittedTx();
|
||||
|
||||
void enableDone();
|
||||
}
|
||||
|
||||
ImageButton bCopyAddress;
|
||||
private TextView tvTxId;
|
||||
private TextView tvTxAddress;
|
||||
private TextView tvTxPaymentId;
|
||||
private TextView tvTxNotes;
|
||||
private TextView tvTxAmount;
|
||||
private TextView tvTxFee;
|
||||
private TextView tvTxTotal;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
Timber.d("onCreateView() %s", (String.valueOf(savedInstanceState)));
|
||||
|
||||
View view = inflater.inflate(
|
||||
R.layout.fragment_send_success, container, false);
|
||||
|
||||
bCopyAddress = (ImageButton) view.findViewById(R.id.bCopyAddress);
|
||||
bCopyAddress.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
copyAddress();
|
||||
}
|
||||
});
|
||||
|
||||
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
||||
tvTxAddress = (TextView) view.findViewById(R.id.tvTxAddress);
|
||||
tvTxPaymentId = (TextView) view.findViewById(R.id.tvTxPaymentId);
|
||||
tvTxNotes = (TextView) view.findViewById(R.id.tvTxNotes);
|
||||
tvTxAmount = ((TextView) view.findViewById(R.id.tvTxAmount));
|
||||
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
||||
tvTxTotal = (TextView) view.findViewById(R.id.tvTxTotal);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onValidateFields() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPauseFragment() {
|
||||
super.onPauseFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResumeFragment() {
|
||||
super.onResumeFragment();
|
||||
Timber.d("onResumeFragment()");
|
||||
Helper.hideKeyboard(getActivity());
|
||||
|
||||
final TxData txData = sendListener.getTxData();
|
||||
tvTxAddress.setText(txData.getDestinationAddress());
|
||||
String paymentId = txData.getPaymentId();
|
||||
if ((paymentId != null) && (!paymentId.isEmpty())) {
|
||||
tvTxPaymentId.setText(txData.getPaymentId());
|
||||
} else {
|
||||
tvTxPaymentId.setText("-");
|
||||
}
|
||||
String notes = sendListener.getNotes();
|
||||
if ((notes != null) && (!notes.isEmpty())) {
|
||||
tvTxNotes.setText(sendListener.getNotes());
|
||||
} else {
|
||||
tvTxNotes.setText("-");
|
||||
}
|
||||
|
||||
final PendingTx committedTx = sendListener.getCommittedTx();
|
||||
if (committedTx != null) {
|
||||
tvTxId.setText(committedTx.txId);
|
||||
bCopyAddress.setEnabled(true);
|
||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||
tvTxAmount.setText(Wallet.getDisplayAmount(committedTx.amount));
|
||||
tvTxFee.setText(Wallet.getDisplayAmount(committedTx.fee));
|
||||
//tvTxDust.setText(Wallet.getDisplayAmount(pendingTransaction.getDust()));
|
||||
tvTxTotal.setText(Wallet.getDisplayAmount(
|
||||
committedTx.fee + committedTx.amount));
|
||||
}
|
||||
sendListener.enableDone();
|
||||
}
|
||||
|
||||
void copyAddress() {
|
||||
Helper.clipBoardCopy(getActivity(), getString(R.string.label_send_txid), tvTxId.getText().toString());
|
||||
Toast.makeText(getActivity(), getString(R.string.message_copy_address), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import com.m2049r.xmrwallet.layout.SpendViewPager;
|
||||
|
||||
abstract public class SendWizardFragment extends Fragment
|
||||
implements SpendViewPager.OnValidateFieldsListener {
|
||||
|
||||
@Override
|
||||
public boolean onValidateFields() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onPauseFragment() {
|
||||
}
|
||||
|
||||
public void onResumeFragment() {
|
||||
}
|
||||
}
|
@@ -31,10 +31,10 @@ import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Transfer;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
@@ -44,7 +44,6 @@ import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class TxFragment extends Fragment {
|
||||
static final String TAG = "TxFragment";
|
||||
|
||||
static public final String ARG_INFO = "info";
|
||||
|
||||
@@ -167,8 +166,7 @@ public class TxFragment extends Fragment {
|
||||
sb.append("-");
|
||||
}
|
||||
sb.append("\n\n");
|
||||
//Helper.clipBoardCopy(getActivity(), getString(R.string.tx_copy_label), sb.toString());
|
||||
//Toast.makeText(getActivity(), getString(R.string.tx_copy_message), Toast.LENGTH_SHORT).show();
|
||||
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, sb.toString());
|
||||
@@ -309,4 +307,4 @@ public class TxFragment extends Fragment {
|
||||
+ " must implement Listener");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2017 m2049r et al.
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class XmrWalletApplication extends Application {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.plant(new Timber.DebugTree());
|
||||
}
|
||||
}
|
||||
}
|
137
app/src/main/java/com/m2049r/xmrwallet/data/BarcodeData.java
Normal file
137
app/src/main/java/com/m2049r/xmrwallet/data/BarcodeData.java
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.data;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class BarcodeData {
|
||||
public static final String XMR_SCHEME = "monero:";
|
||||
public static final String XMR_PAYMENTID = "tx_payment_id";
|
||||
public static final String XMR_AMOUNT = "tx_amount";
|
||||
|
||||
static final String BTC_SCHEME = "bitcoin:";
|
||||
static final String BTC_AMOUNT = "amount";
|
||||
|
||||
public enum Asset {
|
||||
XMR
|
||||
}
|
||||
|
||||
public Asset asset = null;
|
||||
public String address = null;
|
||||
public String paymentId = null;
|
||||
public String amount = null;
|
||||
|
||||
public BarcodeData(Asset asset, String address) {
|
||||
this.asset = asset;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public BarcodeData(Asset asset, String address, String amount) {
|
||||
this.asset = asset;
|
||||
this.address = address;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public BarcodeData(Asset asset, String address, String paymentId, String amount) {
|
||||
this.asset = asset;
|
||||
this.address = address;
|
||||
this.paymentId = paymentId;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
static public BarcodeData fromQrCode(String qrCode) {
|
||||
// check for monero uri
|
||||
BarcodeData bcData = parseMoneroUri(qrCode);
|
||||
// check for naked monero address / integrated address
|
||||
if (bcData == null) {
|
||||
bcData = parseMoneroNaked(qrCode);
|
||||
}
|
||||
return bcData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and decode a monero scheme string. It is here because it needs to validate the data.
|
||||
*
|
||||
* @param uri String containing a monero URL
|
||||
* @return BarcodeData object or null if uri not valid
|
||||
*/
|
||||
|
||||
static public BarcodeData parseMoneroUri(String uri) {
|
||||
Timber.d("parseMoneroUri=%s", uri);
|
||||
|
||||
if (uri == null) return null;
|
||||
|
||||
if (!uri.startsWith(XMR_SCHEME)) return null;
|
||||
|
||||
String noScheme = uri.substring(XMR_SCHEME.length());
|
||||
Uri monero = Uri.parse(noScheme);
|
||||
Map<String, String> parms = new HashMap<>();
|
||||
String query = monero.getQuery();
|
||||
if (query != null) {
|
||||
String[] args = query.split("&");
|
||||
for (String arg : args) {
|
||||
String[] namevalue = arg.split("=");
|
||||
if (namevalue.length == 0) {
|
||||
continue;
|
||||
}
|
||||
parms.put(Uri.decode(namevalue[0]).toLowerCase(),
|
||||
namevalue.length > 1 ? Uri.decode(namevalue[1]) : "");
|
||||
}
|
||||
}
|
||||
String address = monero.getPath();
|
||||
String paymentId = parms.get(XMR_PAYMENTID);
|
||||
String amount = parms.get(XMR_AMOUNT);
|
||||
if (amount != null) {
|
||||
try {
|
||||
Double.parseDouble(amount);
|
||||
} catch (NumberFormatException ex) {
|
||||
Timber.d(ex.getLocalizedMessage());
|
||||
return null; // we have an amount but its not a number!
|
||||
}
|
||||
}
|
||||
if ((paymentId != null) && !Wallet.isPaymentIdValid(paymentId)) {
|
||||
Timber.d("paymentId invalid");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Wallet.isAddressValid(address)) {
|
||||
Timber.d("address invalid");
|
||||
return null;
|
||||
}
|
||||
return new BarcodeData(Asset.XMR, address, paymentId, amount);
|
||||
}
|
||||
|
||||
static public BarcodeData parseMoneroNaked(String address) {
|
||||
Timber.d("parseMoneroNaked=%s", address);
|
||||
|
||||
if (address == null) return null;
|
||||
|
||||
if (!Wallet.isAddressValid(address)) {
|
||||
Timber.d("address invalid");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BarcodeData(Asset.XMR, address);
|
||||
}
|
||||
}
|
39
app/src/main/java/com/m2049r/xmrwallet/data/PendingTx.java
Normal file
39
app/src/main/java/com/m2049r/xmrwallet/data/PendingTx.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.data;
|
||||
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
|
||||
public class PendingTx {
|
||||
final public PendingTransaction.Status status;
|
||||
final public String error;
|
||||
final public long amount;
|
||||
final public long dust;
|
||||
final public long fee;
|
||||
final public String txId;
|
||||
final public long txCount;
|
||||
|
||||
public PendingTx(PendingTransaction pendingTransaction) {
|
||||
status = pendingTransaction.getStatus();
|
||||
error = pendingTransaction.getErrorString();
|
||||
amount = pendingTransaction.getAmount();
|
||||
dust = pendingTransaction.getDust();
|
||||
fee = pendingTransaction.getFee();
|
||||
txId = pendingTransaction.getFirstTxId();
|
||||
txCount = pendingTransaction.getTxCount();
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet.util;
|
||||
package com.m2049r.xmrwallet.data;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
@@ -23,6 +23,15 @@ import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
|
||||
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
|
||||
public class TxData implements Parcelable {
|
||||
|
||||
public TxData(TxData txData) {
|
||||
this.dst_addr = txData.dst_addr;
|
||||
this.paymentId = txData.paymentId;
|
||||
this.amount = txData.amount;
|
||||
this.mixin = txData.mixin;
|
||||
this.priority = txData.priority;
|
||||
}
|
||||
|
||||
public TxData(String dst_addr,
|
||||
String paymentId,
|
||||
long amount,
|
||||
@@ -35,11 +44,35 @@ public class TxData implements Parcelable {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public String dst_addr;
|
||||
public String paymentId;
|
||||
public long amount;
|
||||
public int mixin;
|
||||
public PendingTransaction.Priority priority;
|
||||
public long getFee() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public String getDestinationAddress() {
|
||||
return dst_addr;
|
||||
}
|
||||
|
||||
public String getPaymentId() {
|
||||
return paymentId;
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public int getMixin() {
|
||||
return mixin;
|
||||
}
|
||||
|
||||
public PendingTransaction.Priority getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
final private String dst_addr;
|
||||
final private String paymentId;
|
||||
final private long amount;
|
||||
final private int mixin;
|
||||
final private PendingTransaction.Priority priority;
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
@@ -87,7 +120,7 @@ public class TxData implements Parcelable {
|
||||
sb.append(",mixin:");
|
||||
sb.append(mixin);
|
||||
sb.append(",priority:");
|
||||
sb.append(priority.toString());
|
||||
sb.append(String.valueOf(priority));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* 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.layout;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class AsyncExchangeRate extends AsyncTask<String, Void, Boolean> {
|
||||
static final String TAG = "AsyncExchangeRate";
|
||||
static final long TIME_REFRESH_INTERVAL = 60000; // refresh exchange rate max every minute
|
||||
|
||||
public interface Listener {
|
||||
void exchangeFailed();
|
||||
|
||||
// callback from AsyncExchangeRate when we have a rate
|
||||
void exchange(String currencyA, String currencyB, double rate);
|
||||
}
|
||||
|
||||
static long RateTime = 0;
|
||||
static double Rate = 0;
|
||||
static String Fiat = null;
|
||||
|
||||
private final WeakReference<Listener> exchangeViewRef;
|
||||
|
||||
public AsyncExchangeRate(Listener exchangeView) {
|
||||
super();
|
||||
exchangeViewRef = new WeakReference<>(exchangeView);
|
||||
}
|
||||
|
||||
@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);
|
||||
Listener exchangeView = exchangeViewRef.get();
|
||||
if (result) {
|
||||
Log.d(TAG, "yay! = " + Rate);
|
||||
if (exchangeView != null) {
|
||||
exchangeView.exchange(currencyA, currencyB, inverse ? (1 / Rate) : Rate);
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "nay!");
|
||||
if (exchangeView != null) {
|
||||
exchangeView.exchangeFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "https://api.kraken.com/0/public/Ticker?pair=XMREUR"
|
||||
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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.layout;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.m2049r.xmrwallet.SendFragment;
|
||||
|
||||
public class SpendViewPager extends ViewPager {
|
||||
|
||||
public interface OnValidateFieldsListener {
|
||||
boolean onValidateFields();
|
||||
}
|
||||
|
||||
public SpendViewPager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SpendViewPager(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
int pos = getCurrentItem();
|
||||
if (validateFields(pos)) {
|
||||
setCurrentItem(pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void previous() {
|
||||
setCurrentItem(getCurrentItem() - 1);
|
||||
}
|
||||
|
||||
private boolean allowSwipe = true;
|
||||
|
||||
public void allowSwipe(boolean allow) {
|
||||
allowSwipe = allow;
|
||||
}
|
||||
|
||||
public boolean validateFields(int position) {
|
||||
OnValidateFieldsListener c = ((SendFragment.SpendPagerAdapter) getAdapter()).getFragment(position);
|
||||
return c.onValidateFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
if (allowSwipe) return super.onInterceptTouchEvent(event);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (allowSwipe) return super.onTouchEvent(event);
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -19,7 +19,6 @@ package com.m2049r.xmrwallet.layout;
|
||||
import android.content.Context;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -37,16 +36,12 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> {
|
||||
private static final String TAG = "TransactionInfoAdapter";
|
||||
|
||||
private final SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
|
||||
//static final int TX_RED = Color.rgb(255, 79, 65);
|
||||
//static final int TX_GREEN = Color.rgb(54, 176, 91);
|
||||
//static final int TX_PENDING = Color.rgb(72, 53, 176);
|
||||
//static final int TX_FAILED = Color.rgb(208, 0, 255);
|
||||
|
||||
private int outboundColour;
|
||||
private int inboundColour;
|
||||
private int pendingColour;
|
||||
@@ -96,11 +91,11 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||
// as the TransactionInfo items are always recreated, we cannot recycle
|
||||
this.infoItems.clear();
|
||||
if (data != null) {
|
||||
Log.d(TAG, "setInfos " + data.size());
|
||||
Timber.d("setInfos %s", data.size());
|
||||
infoItems.addAll(data);
|
||||
Collections.sort(infoItems);
|
||||
} else {
|
||||
Log.d(TAG, "setInfos null");
|
||||
Timber.d("setInfos null");
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
@@ -19,7 +19,6 @@ package com.m2049r.xmrwallet.layout;
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@@ -38,8 +37,9 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class WalletInfoAdapter extends RecyclerView.Adapter<WalletInfoAdapter.ViewHolder> {
|
||||
private static final String TAG = "WalletInfoAdapter";
|
||||
|
||||
private final SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
|
||||
@@ -89,11 +89,11 @@ public class WalletInfoAdapter extends RecyclerView.Adapter<WalletInfoAdapter.Vi
|
||||
// as the WalletInfo items are always recreated, we cannot recycle
|
||||
infoItems.clear();
|
||||
if (data != null) {
|
||||
Log.d(TAG, "setInfos " + data.size());
|
||||
Timber.d("setInfos %s", data.size());
|
||||
infoItems.addAll(data);
|
||||
Collections.sort(infoItems);
|
||||
} else {
|
||||
Log.d(TAG, "setInfos null");
|
||||
Timber.d("setInfos null");
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
@@ -19,8 +19,6 @@ package com.m2049r.xmrwallet.model;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.m2049r.xmrwallet.util.TxData;
|
||||
|
||||
public class Transfer implements Parcelable {
|
||||
public long amount;
|
||||
public String address;
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.m2049r.xmrwallet.model;
|
||||
|
||||
import android.util.Log;
|
||||
import com.m2049r.xmrwallet.data.TxData;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -154,6 +154,10 @@ public class Wallet {
|
||||
|
||||
public static native boolean isPaymentIdValid(String payment_id);
|
||||
|
||||
public static boolean isAddressValid(String address) {
|
||||
return isAddressValid(address, WalletManager.getInstance().isTestNet());
|
||||
}
|
||||
|
||||
public static native boolean isAddressValid(String address, boolean isTestNet);
|
||||
|
||||
//TODO static static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error);
|
||||
@@ -187,6 +191,15 @@ public class Wallet {
|
||||
}
|
||||
}
|
||||
|
||||
public PendingTransaction createTransaction(TxData txData) {
|
||||
return createTransaction(
|
||||
txData.getDestinationAddress(),
|
||||
txData.getPaymentId(),
|
||||
txData.getAmount(),
|
||||
txData.getMixin(),
|
||||
txData.getPriority());
|
||||
}
|
||||
|
||||
public PendingTransaction createTransaction(String dst_addr, String payment_id,
|
||||
long amount, int mixin_count,
|
||||
PendingTransaction.Priority priority) {
|
||||
|
@@ -16,21 +16,17 @@
|
||||
|
||||
package com.m2049r.xmrwallet.model;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class WalletManager {
|
||||
private final static String TAG = "WalletManager";
|
||||
|
||||
static {
|
||||
System.loadLibrary("monerujo");
|
||||
@@ -54,7 +50,7 @@ public class WalletManager {
|
||||
}
|
||||
|
||||
private void manageWallet(Wallet wallet) {
|
||||
Log.d(TAG, "Managing " + wallet.getName());
|
||||
Timber.d("Managing %s", wallet.getName());
|
||||
managedWallet = wallet;
|
||||
}
|
||||
|
||||
@@ -68,7 +64,7 @@ public class WalletManager {
|
||||
if (getWallet() != wallet) {
|
||||
throw new IllegalStateException(wallet.getName() + " not under management!");
|
||||
}
|
||||
Log.d(TAG, "Unmanaging " + managedWallet.getName());
|
||||
Timber.d("Unmanaging %s", managedWallet.getName());
|
||||
managedWallet = null;
|
||||
}
|
||||
|
||||
@@ -165,14 +161,14 @@ public class WalletManager {
|
||||
info.path = wallet.getParentFile();
|
||||
info.name = wallet.getName();
|
||||
File addressFile = new File(info.path, info.name + ".address.txt");
|
||||
//Log.d(TAG, addressFile.getAbsolutePath());
|
||||
//Timber.d(addressFile.getAbsolutePath());
|
||||
info.address = "??????";
|
||||
BufferedReader addressReader = null;
|
||||
try {
|
||||
addressReader = new BufferedReader(new FileReader(addressFile));
|
||||
info.address = addressReader.readLine();
|
||||
} catch (IOException ex) {
|
||||
Log.d(TAG, ex.getLocalizedMessage());
|
||||
Timber.d(ex.getLocalizedMessage());
|
||||
} finally {
|
||||
if (addressReader != null) {
|
||||
try {
|
||||
@@ -187,7 +183,7 @@ public class WalletManager {
|
||||
|
||||
public List<WalletInfo> findWallets(File path) {
|
||||
List<WalletInfo> wallets = new ArrayList<>();
|
||||
Log.d(TAG, "Scanning: " + path.getAbsolutePath());
|
||||
Timber.d("Scanning: %s", path.getAbsolutePath());
|
||||
File[] found = path.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String filename) {
|
||||
return filename.endsWith(".keys");
|
||||
@@ -210,14 +206,15 @@ public class WalletManager {
|
||||
|
||||
public boolean isTestNet() {
|
||||
if (daemonAddress == null) {
|
||||
return true;
|
||||
// assume testnet not explicitly initialised
|
||||
throw new IllegalStateException("use setDaemon() to initialise daemon and net first!");
|
||||
//throw new IllegalStateException("use setDaemon() to initialise daemon and net first!");
|
||||
}
|
||||
return testnet;
|
||||
}
|
||||
|
||||
public void setDaemon(String address, boolean testnet, String username, String password) {
|
||||
//Log.d(TAG, "SETDAEMON " + username + "/" + password + "/" + address);
|
||||
//Timber.d("SETDAEMON " + username + "/" + password + "/" + address);
|
||||
this.daemonAddress = address;
|
||||
this.testnet = testnet;
|
||||
this.daemonUsername = username;
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user