mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-06 19:00:30 +02:00
Compare commits
9 Commits
v1.0.1
...
v1.1.2-alp
Author | SHA1 | Date | |
---|---|---|---|
![]() |
03c5569f91 | ||
![]() |
7b1e6a89ba | ||
![]() |
ff8a3ee7c8 | ||
![]() |
dcbaa35b57 | ||
![]() |
3466116e2a | ||
![]() |
59e87e2bfe | ||
![]() |
e8b749af3b | ||
![]() |
f282f01edd | ||
![]() |
f16afdbb19 |
10
.idea/libraries/constraint_layout_1_0_2.xml
generated
10
.idea/libraries/constraint_layout_1_0_2.xml
generated
@@ -1,10 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="constraint-layout-1.0.2">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="file://$USER_HOME$/.android/build-cache/983cd9976ef510b2538361561f2ee91f1200f245/output/res" />
|
|
||||||
<root url="jar://$USER_HOME$/.android/build-cache/983cd9976ef510b2538361561f2ee91f1200f245/output/jars/classes.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
@@ -1,9 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="constraint-layout-solver-1.0.2">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/extras/m2repository/com/android/support/constraint/constraint-layout-solver/1.0.2/constraint-layout-solver-1.0.2.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
10
.idea/libraries/core_1_9_8.xml
generated
10
.idea/libraries/core_1_9_8.xml
generated
@@ -1,10 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="core-1.9.8">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.android/build-cache/db7eb580bfa6467818ef12c5f1fa42273b50aa3a/output/jars/classes.jar!/" />
|
|
||||||
<root url="file://$USER_HOME$/.android/build-cache/db7eb580bfa6467818ef12c5f1fa42273b50aa3a/output/res" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
11
.idea/libraries/core_3_3_0.xml
generated
11
.idea/libraries/core_3_3_0.xml
generated
@@ -1,11 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="core-3.3.0">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.zxing/core/3.3.0/73c49077166faa4c3c0059c5f583d1d7bd1475fe/core-3.3.0.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.zxing/core/3.3.0/39d966e052e28fc7d83793b02e0af97ccf955745/core-3.3.0-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
10
.idea/libraries/zxing_1_9_8.xml
generated
10
.idea/libraries/zxing_1_9_8.xml
generated
@@ -1,10 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="zxing-1.9.8">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.android/build-cache/8d8f2e0e10c7af73321454f6fa481e8e5438e654/output/jars/classes.jar!/" />
|
|
||||||
<root url="file://$USER_HOME$/.android/build-cache/8d8f2e0e10c7af73321454f6fa481e8e5438e654/output/res" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
@@ -3,13 +3,13 @@ apply plugin: 'witness'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 25
|
compileSdkVersion 25
|
||||||
buildToolsVersion "25.0.2"
|
buildToolsVersion '26.0.2'
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 24
|
versionCode 29
|
||||||
versionName "1.0.1"
|
versionName "1.1.2-alpha"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
|
@@ -215,7 +215,7 @@ std::vector<std::string> java2cpp(JNIEnv *env, jobject arrayList) {
|
|||||||
for (jint i = 0; i < len; i++) {
|
for (jint i = 0; i < len; i++) {
|
||||||
jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList,
|
jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList,
|
||||||
java_util_ArrayList_get, i));
|
java_util_ArrayList_get, i));
|
||||||
const char *pchars = env->GetStringUTFChars(element, JNI_FALSE);
|
const char *pchars = env->GetStringUTFChars(element, NULL);
|
||||||
result.emplace_back(pchars);
|
result.emplace_back(pchars);
|
||||||
env->ReleaseStringUTFChars(element, pchars);
|
env->ReleaseStringUTFChars(element, pchars);
|
||||||
env->DeleteLocalRef(element);
|
env->DeleteLocalRef(element);
|
||||||
@@ -254,9 +254,9 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletJ(JNIEnv *env, jobject
|
|||||||
jstring path, jstring password,
|
jstring path, jstring password,
|
||||||
jstring language,
|
jstring language,
|
||||||
jboolean isTestNet) {
|
jboolean isTestNet) {
|
||||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
const char *_password = env->GetStringUTFChars(password, JNI_FALSE);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
const char *_language = env->GetStringUTFChars(language, JNI_FALSE);
|
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWallet(
|
Bitmonero::WalletManagerFactory::getWalletManager()->createWallet(
|
||||||
@@ -275,8 +275,8 @@ JNIEXPORT jlong JNICALL
|
|||||||
Java_com_m2049r_xmrwallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring password,
|
jstring path, jstring password,
|
||||||
jboolean isTestNet) {
|
jboolean isTestNet) {
|
||||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
const char *_password = env->GetStringUTFChars(password, JNI_FALSE);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->openWallet(
|
Bitmonero::WalletManagerFactory::getWalletManager()->openWallet(
|
||||||
@@ -294,8 +294,8 @@ Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobje
|
|||||||
jstring path, jstring mnemonic,
|
jstring path, jstring mnemonic,
|
||||||
jboolean isTestNet,
|
jboolean isTestNet,
|
||||||
jlong restoreHeight) {
|
jlong restoreHeight) {
|
||||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
const char *_mnemonic = env->GetStringUTFChars(mnemonic, JNI_FALSE);
|
const char *_mnemonic = env->GetStringUTFChars(mnemonic, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->recoveryWallet(
|
Bitmonero::WalletManagerFactory::getWalletManager()->recoveryWallet(
|
||||||
@@ -317,11 +317,11 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env,
|
|||||||
jstring addressString,
|
jstring addressString,
|
||||||
jstring viewKeyString,
|
jstring viewKeyString,
|
||||||
jstring spendKeyString) {
|
jstring spendKeyString) {
|
||||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
const char *_language = env->GetStringUTFChars(language, JNI_FALSE);
|
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||||
const char *_addressString = env->GetStringUTFChars(addressString, JNI_FALSE);
|
const char *_addressString = env->GetStringUTFChars(addressString, NULL);
|
||||||
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, JNI_FALSE);
|
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, NULL);
|
||||||
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, JNI_FALSE);
|
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet =
|
Bitmonero::Wallet *wallet =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
|
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
|
||||||
@@ -344,7 +344,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env,
|
|||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_walletExists(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_walletExists(JNIEnv *env, jobject instance,
|
||||||
jstring path) {
|
jstring path) {
|
||||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
bool exists =
|
bool exists =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->walletExists(std::string(_path));
|
Bitmonero::WalletManagerFactory::getWalletManager()->walletExists(std::string(_path));
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
@@ -356,8 +356,8 @@ Java_com_m2049r_xmrwallet_model_WalletManager_verifyWalletPassword(JNIEnv *env,
|
|||||||
jstring keys_file_name,
|
jstring keys_file_name,
|
||||||
jstring password,
|
jstring password,
|
||||||
jboolean watch_only) {
|
jboolean watch_only) {
|
||||||
const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, JNI_FALSE);
|
const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, NULL);
|
||||||
const char *_password = env->GetStringUTFChars(password, JNI_FALSE);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
bool passwordOk =
|
bool passwordOk =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->verifyWalletPassword(
|
Bitmonero::WalletManagerFactory::getWalletManager()->verifyWalletPassword(
|
||||||
std::string(_keys_file_name), std::string(_password), watch_only);
|
std::string(_keys_file_name), std::string(_password), watch_only);
|
||||||
@@ -370,7 +370,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_verifyWalletPassword(JNIEnv *env,
|
|||||||
JNIEXPORT jobject JNICALL
|
JNIEXPORT jobject JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_findWallets(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_findWallets(JNIEnv *env, jobject instance,
|
||||||
jstring path) {
|
jstring path) {
|
||||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
std::vector<std::string> walletPaths =
|
std::vector<std::string> walletPaths =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->findWallets(std::string(_path));
|
Bitmonero::WalletManagerFactory::getWalletManager()->findWallets(std::string(_path));
|
||||||
env->ReleaseStringUTFChars(path, _path);
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
@@ -388,7 +388,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_getErrorString(JNIEnv *env, jobjec
|
|||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_setDaemonAddressJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_setDaemonAddressJ(JNIEnv *env, jobject instance,
|
||||||
jstring address) {
|
jstring address) {
|
||||||
const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
|
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->setDaemonAddress(std::string(_address));
|
Bitmonero::WalletManagerFactory::getWalletManager()->setDaemonAddress(std::string(_address));
|
||||||
env->ReleaseStringUTFChars(address, _address);
|
env->ReleaseStringUTFChars(address, _address);
|
||||||
}
|
}
|
||||||
@@ -440,7 +440,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_startMining(JNIEnv *env, jobject i
|
|||||||
jstring address,
|
jstring address,
|
||||||
jboolean background_mining,
|
jboolean background_mining,
|
||||||
jboolean ignore_battery) {
|
jboolean ignore_battery) {
|
||||||
const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
|
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||||
bool success =
|
bool success =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->startMining(std::string(_address),
|
Bitmonero::WalletManagerFactory::getWalletManager()->startMining(std::string(_address),
|
||||||
background_mining,
|
background_mining,
|
||||||
@@ -458,7 +458,7 @@ JNIEXPORT jstring JNICALL
|
|||||||
Java_com_m2049r_xmrwallet_model_WalletManager_resolveOpenAlias(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_resolveOpenAlias(JNIEnv *env, jobject instance,
|
||||||
jstring address,
|
jstring address,
|
||||||
jboolean dnssec_valid) {
|
jboolean dnssec_valid) {
|
||||||
const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
|
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||||
bool _dnssec_valid = (bool) dnssec_valid;
|
bool _dnssec_valid = (bool) dnssec_valid;
|
||||||
std::string resolvedAlias =
|
std::string resolvedAlias =
|
||||||
Bitmonero::WalletManagerFactory::getWalletManager()->resolveOpenAlias(
|
Bitmonero::WalletManagerFactory::getWalletManager()->resolveOpenAlias(
|
||||||
@@ -510,7 +510,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getSeedLanguage(JNIEnv *env, jobject inst
|
|||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_setSeedLanguage(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_Wallet_setSeedLanguage(JNIEnv *env, jobject instance,
|
||||||
jstring language) {
|
jstring language) {
|
||||||
const char *_language = env->GetStringUTFChars(language, JNI_FALSE);
|
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
wallet->setSeedLanguage(std::string(_language));
|
wallet->setSeedLanguage(std::string(_language));
|
||||||
env->ReleaseStringUTFChars(language, _language);
|
env->ReleaseStringUTFChars(language, _language);
|
||||||
@@ -531,7 +531,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getErrorString(JNIEnv *env, jobject insta
|
|||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_setPassword(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_Wallet_setPassword(JNIEnv *env, jobject instance,
|
||||||
jstring password) {
|
jstring password) {
|
||||||
const char *_password = env->GetStringUTFChars(password, JNI_FALSE);
|
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
bool success = wallet->setPassword(std::string(_password));
|
bool success = wallet->setPassword(std::string(_password));
|
||||||
env->ReleaseStringUTFChars(password, _password);
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
@@ -562,7 +562,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_isTestNet(JNIEnv *env, jobject instance)
|
|||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_getIntegratedAddress(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_Wallet_getIntegratedAddress(JNIEnv *env, jobject instance,
|
||||||
jstring payment_id) {
|
jstring payment_id) {
|
||||||
const char *_payment_id = env->GetStringUTFChars(payment_id, JNI_FALSE);
|
const char *_payment_id = env->GetStringUTFChars(payment_id, NULL);
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
std::string address = wallet->integratedAddress(_payment_id);
|
std::string address = wallet->integratedAddress(_payment_id);
|
||||||
env->ReleaseStringUTFChars(payment_id, _payment_id);
|
env->ReleaseStringUTFChars(payment_id, _payment_id);
|
||||||
@@ -584,7 +584,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getSecretSpendKey(JNIEnv *env, jobject in
|
|||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_store(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_Wallet_store(JNIEnv *env, jobject instance,
|
||||||
jstring path) {
|
jstring path) {
|
||||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
bool success = wallet->store(std::string(_path));
|
bool success = wallet->store(std::string(_path));
|
||||||
if (!success) {
|
if (!success) {
|
||||||
@@ -607,9 +607,9 @@ Java_com_m2049r_xmrwallet_model_Wallet_initJ(JNIEnv *env, jobject instance,
|
|||||||
jstring daemon_address,
|
jstring daemon_address,
|
||||||
jlong upper_transaction_size_limit,
|
jlong upper_transaction_size_limit,
|
||||||
jstring daemon_username, jstring daemon_password) {
|
jstring daemon_username, jstring daemon_password) {
|
||||||
const char *_daemon_address = env->GetStringUTFChars(daemon_address, JNI_FALSE);
|
const char *_daemon_address = env->GetStringUTFChars(daemon_address, NULL);
|
||||||
const char *_daemon_username = env->GetStringUTFChars(daemon_username, JNI_FALSE);
|
const char *_daemon_username = env->GetStringUTFChars(daemon_username, NULL);
|
||||||
const char *_daemon_password = env->GetStringUTFChars(daemon_password, JNI_FALSE);
|
const char *_daemon_password = env->GetStringUTFChars(daemon_password, NULL);
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
bool status = wallet->init(_daemon_address, upper_transaction_size_limit, _daemon_username,
|
bool status = wallet->init(_daemon_address, upper_transaction_size_limit, _daemon_username,
|
||||||
_daemon_password);
|
_daemon_password);
|
||||||
@@ -691,7 +691,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getDisplayAmount(JNIEnv *env, jobject cla
|
|||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_getAmountFromString(JNIEnv *env, jobject clazz,
|
Java_com_m2049r_xmrwallet_model_Wallet_getAmountFromString(JNIEnv *env, jobject clazz,
|
||||||
jstring amount) {
|
jstring amount) {
|
||||||
const char *_amount = env->GetStringUTFChars(amount, JNI_FALSE);
|
const char *_amount = env->GetStringUTFChars(amount, NULL);
|
||||||
uint64_t x = Bitmonero::Wallet::amountFromString(_amount);
|
uint64_t x = Bitmonero::Wallet::amountFromString(_amount);
|
||||||
env->ReleaseStringUTFChars(amount, _amount);
|
env->ReleaseStringUTFChars(amount, _amount);
|
||||||
return x;
|
return x;
|
||||||
@@ -711,7 +711,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_generatePaymentId(JNIEnv *env, jobject cl
|
|||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_isPaymentIdValid(JNIEnv *env, jobject clazz,
|
Java_com_m2049r_xmrwallet_model_Wallet_isPaymentIdValid(JNIEnv *env, jobject clazz,
|
||||||
jstring payment_id) {
|
jstring payment_id) {
|
||||||
const char *_payment_id = env->GetStringUTFChars(payment_id, JNI_FALSE);
|
const char *_payment_id = env->GetStringUTFChars(payment_id, NULL);
|
||||||
bool isValid = Bitmonero::Wallet::paymentIdValid(_payment_id);
|
bool isValid = Bitmonero::Wallet::paymentIdValid(_payment_id);
|
||||||
env->ReleaseStringUTFChars(payment_id, _payment_id);
|
env->ReleaseStringUTFChars(payment_id, _payment_id);
|
||||||
return isValid;
|
return isValid;
|
||||||
@@ -720,7 +720,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_isPaymentIdValid(JNIEnv *env, jobject cla
|
|||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_isAddressValid(JNIEnv *env, jobject clazz,
|
Java_com_m2049r_xmrwallet_model_Wallet_isAddressValid(JNIEnv *env, jobject clazz,
|
||||||
jstring address, jboolean isTestNet) {
|
jstring address, jboolean isTestNet) {
|
||||||
const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
|
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||||
bool isValid = Bitmonero::Wallet::addressValid(_address, isTestNet);
|
bool isValid = Bitmonero::Wallet::addressValid(_address, isTestNet);
|
||||||
env->ReleaseStringUTFChars(address, _address);
|
env->ReleaseStringUTFChars(address, _address);
|
||||||
return isValid;
|
return isValid;
|
||||||
@@ -732,7 +732,7 @@ JNIEXPORT jstring JNICALL
|
|||||||
Java_com_m2049r_xmrwallet_model_Wallet_getPaymentIdFromAddress(JNIEnv *env, jobject clazz,
|
Java_com_m2049r_xmrwallet_model_Wallet_getPaymentIdFromAddress(JNIEnv *env, jobject clazz,
|
||||||
jstring address,
|
jstring address,
|
||||||
jboolean isTestNet) {
|
jboolean isTestNet) {
|
||||||
const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
|
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||||
std::string payment_id = Bitmonero::Wallet::paymentIdFromAddress(_address, isTestNet);
|
std::string payment_id = Bitmonero::Wallet::paymentIdFromAddress(_address, isTestNet);
|
||||||
env->ReleaseStringUTFChars(address, _address);
|
env->ReleaseStringUTFChars(address, _address);
|
||||||
return env->NewStringUTF(payment_id.c_str());
|
return env->NewStringUTF(payment_id.c_str());
|
||||||
@@ -776,8 +776,8 @@ Java_com_m2049r_xmrwallet_model_Wallet_createTransactionJ(JNIEnv *env, jobject i
|
|||||||
jlong amount, jint mixin_count,
|
jlong amount, jint mixin_count,
|
||||||
jint priority) {
|
jint priority) {
|
||||||
|
|
||||||
const char *_dst_addr = env->GetStringUTFChars(dst_addr, JNI_FALSE);
|
const char *_dst_addr = env->GetStringUTFChars(dst_addr, NULL);
|
||||||
const char *_payment_id = env->GetStringUTFChars(payment_id, JNI_FALSE);
|
const char *_payment_id = env->GetStringUTFChars(payment_id, NULL);
|
||||||
Bitmonero::PendingTransaction::Priority _priority =
|
Bitmonero::PendingTransaction::Priority _priority =
|
||||||
static_cast<Bitmonero::PendingTransaction::Priority>(priority);
|
static_cast<Bitmonero::PendingTransaction::Priority>(priority);
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
@@ -862,8 +862,8 @@ JNIEXPORT jboolean JNICALL
|
|||||||
Java_com_m2049r_xmrwallet_model_Wallet_setUserNote(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_Wallet_setUserNote(JNIEnv *env, jobject instance,
|
||||||
jstring txid, jstring note) {
|
jstring txid, jstring note) {
|
||||||
|
|
||||||
const char *_txid = env->GetStringUTFChars(txid, JNI_FALSE);
|
const char *_txid = env->GetStringUTFChars(txid, NULL);
|
||||||
const char *_note = env->GetStringUTFChars(note, JNI_FALSE);
|
const char *_note = env->GetStringUTFChars(note, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
|
|
||||||
@@ -879,7 +879,7 @@ JNIEXPORT jstring JNICALL
|
|||||||
Java_com_m2049r_xmrwallet_model_Wallet_getUserNote(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_Wallet_getUserNote(JNIEnv *env, jobject instance,
|
||||||
jstring txid) {
|
jstring txid) {
|
||||||
|
|
||||||
const char *_txid = env->GetStringUTFChars(txid, JNI_FALSE);
|
const char *_txid = env->GetStringUTFChars(txid, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
|
|
||||||
@@ -893,7 +893,7 @@ JNIEXPORT jstring JNICALL
|
|||||||
Java_com_m2049r_xmrwallet_model_Wallet_getTxKey(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_Wallet_getTxKey(JNIEnv *env, jobject instance,
|
||||||
jstring txid) {
|
jstring txid) {
|
||||||
|
|
||||||
const char *_txid = env->GetStringUTFChars(txid, JNI_FALSE);
|
const char *_txid = env->GetStringUTFChars(txid, NULL);
|
||||||
|
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
|
|
||||||
@@ -1015,7 +1015,7 @@ JNIEXPORT jboolean JNICALL
|
|||||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_commit(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_PendingTransaction_commit(JNIEnv *env, jobject instance,
|
||||||
jstring filename, jboolean overwrite) {
|
jstring filename, jboolean overwrite) {
|
||||||
|
|
||||||
const char *_filename = env->GetStringUTFChars(filename, JNI_FALSE);
|
const char *_filename = env->GetStringUTFChars(filename, NULL);
|
||||||
|
|
||||||
Bitmonero::PendingTransaction *tx = getHandle<Bitmonero::PendingTransaction>(env, instance);
|
Bitmonero::PendingTransaction *tx = getHandle<Bitmonero::PendingTransaction>(env, instance);
|
||||||
bool success = tx->commit(_filename, overwrite);
|
bool success = tx->commit(_filename, overwrite);
|
||||||
@@ -1060,4 +1060,3 @@ Java_com_m2049r_xmrwallet_model_PendingTransaction_getTxCount(JNIEnv *env, jobje
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 253 KiB |
File diff suppressed because it is too large
Load Diff
@@ -28,12 +28,17 @@ import android.view.MenuInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||||
|
|
||||||
public class GenerateReviewFragment extends Fragment {
|
public class GenerateReviewFragment extends Fragment {
|
||||||
@@ -42,6 +47,8 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
static final public String VIEW_TYPE_ACCEPT = "accept";
|
static final public String VIEW_TYPE_ACCEPT = "accept";
|
||||||
static final public String VIEW_TYPE_WALLET = "wallet";
|
static final public String VIEW_TYPE_WALLET = "wallet";
|
||||||
|
|
||||||
|
ScrollView scrollview;
|
||||||
|
|
||||||
ProgressBar pbProgress;
|
ProgressBar pbProgress;
|
||||||
TextView tvWalletName;
|
TextView tvWalletName;
|
||||||
TextView tvWalletPassword;
|
TextView tvWalletPassword;
|
||||||
@@ -49,14 +56,18 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
TextView tvWalletMnemonic;
|
TextView tvWalletMnemonic;
|
||||||
TextView tvWalletViewKey;
|
TextView tvWalletViewKey;
|
||||||
TextView tvWalletSpendKey;
|
TextView tvWalletSpendKey;
|
||||||
|
ImageButton bCopyAddress;
|
||||||
|
LinearLayout llAdvancedInfo;
|
||||||
|
Button bAdvancedInfo;
|
||||||
Button bAccept;
|
Button bAccept;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.gen_review_fragment, container, false);
|
View view = inflater.inflate(R.layout.fragment_review, container, false);
|
||||||
|
|
||||||
|
scrollview = (ScrollView) view.findViewById(R.id.scrollview);
|
||||||
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
||||||
tvWalletName = (TextView) view.findViewById(R.id.tvWalletName);
|
tvWalletName = (TextView) view.findViewById(R.id.tvWalletName);
|
||||||
tvWalletPassword = (TextView) view.findViewById(R.id.tvWalletPassword);
|
tvWalletPassword = (TextView) view.findViewById(R.id.tvWalletPassword);
|
||||||
@@ -64,26 +75,15 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
tvWalletViewKey = (TextView) view.findViewById(R.id.tvWalletViewKey);
|
tvWalletViewKey = (TextView) view.findViewById(R.id.tvWalletViewKey);
|
||||||
tvWalletSpendKey = (TextView) view.findViewById(R.id.tvWalletSpendKey);
|
tvWalletSpendKey = (TextView) view.findViewById(R.id.tvWalletSpendKey);
|
||||||
tvWalletMnemonic = (TextView) view.findViewById(R.id.tvWalletMnemonic);
|
tvWalletMnemonic = (TextView) view.findViewById(R.id.tvWalletMnemonic);
|
||||||
|
bCopyAddress = (ImageButton) view.findViewById(R.id.bCopyAddress);
|
||||||
|
bAdvancedInfo = (Button) view.findViewById(R.id.bAdvancedInfo);
|
||||||
|
llAdvancedInfo = (LinearLayout) view.findViewById(R.id.llAdvancedInfo);
|
||||||
|
|
||||||
bAccept = (Button) view.findViewById(R.id.bAccept);
|
bAccept = (Button) view.findViewById(R.id.bAccept);
|
||||||
|
|
||||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
boolean testnet = WalletManager.getInstance().isTestNet();
|
||||||
tvWalletMnemonic.setTextIsSelectable(testnet);
|
tvWalletMnemonic.setTextIsSelectable(testnet);
|
||||||
tvWalletSpendKey.setTextIsSelectable(testnet);
|
tvWalletSpendKey.setTextIsSelectable(testnet);
|
||||||
if (!testnet) {
|
|
||||||
tvWalletMnemonic.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Toast.makeText(getActivity(), getString(R.string.message_noselect_seed), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tvWalletSpendKey.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Toast.makeText(getActivity(), getString(R.string.message_noselect_key), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bAccept.setOnClickListener(new View.OnClickListener() {
|
bAccept.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -91,6 +91,36 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
acceptWallet();
|
acceptWallet();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
view.findViewById(R.id.bCopyViewKey).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
copyViewKey();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
bCopyAddress.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
copyAddress();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
view.findViewById(R.id.bCopySeed).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
nocopy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
view.findViewById(R.id.bCopySepndKey).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
nocopy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
showAdvancedInfo();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
showProgress();
|
showProgress();
|
||||||
|
|
||||||
@@ -103,6 +133,31 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void copyViewKey() {
|
||||||
|
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_viewkey), tvWalletViewKey.getText().toString());
|
||||||
|
Toast.makeText(getActivity(), getString(R.string.message_copy_viewkey), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyAddress() {
|
||||||
|
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_address), tvWalletAddress.getText().toString());
|
||||||
|
Toast.makeText(getActivity(), getString(R.string.message_copy_address), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nocopy() {
|
||||||
|
Toast.makeText(getActivity(), getString(R.string.message_nocopy), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void showAdvancedInfo() {
|
||||||
|
llAdvancedInfo.setVisibility(View.VISIBLE);
|
||||||
|
bAdvancedInfo.setVisibility(View.GONE);
|
||||||
|
scrollview.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
scrollview.fullScroll(ScrollView.FOCUS_DOWN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
String type;
|
String type;
|
||||||
|
|
||||||
private void acceptWallet() {
|
private void acceptWallet() {
|
||||||
@@ -148,7 +203,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
address = wallet.getAddress();
|
address = wallet.getAddress();
|
||||||
seed = wallet.getSeed();
|
seed = wallet.getSeed();
|
||||||
viewKey = wallet.getSecretViewKey();
|
viewKey = wallet.getSecretViewKey();
|
||||||
spendKey = isWatchOnly ? getActivity().getString(R.string.watchonly_label) : wallet.getSecretSpendKey();
|
spendKey = isWatchOnly ? getActivity().getString(R.string.label_watchonly) : wallet.getSecretSpendKey();
|
||||||
isWatchOnly = wallet.isWatchOnly();
|
isWatchOnly = wallet.isWatchOnly();
|
||||||
if (closeWallet) wallet.close();
|
if (closeWallet) wallet.close();
|
||||||
return true;
|
return true;
|
||||||
@@ -157,6 +212,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Boolean result) {
|
protected void onPostExecute(Boolean result) {
|
||||||
super.onPostExecute(result);
|
super.onPostExecute(result);
|
||||||
|
if (!isAdded()) return; // never mind
|
||||||
tvWalletName.setText(name);
|
tvWalletName.setText(name);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (type.equals(GenerateReviewFragment.VIEW_TYPE_ACCEPT)) {
|
if (type.equals(GenerateReviewFragment.VIEW_TYPE_ACCEPT)) {
|
||||||
@@ -168,9 +224,14 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
tvWalletMnemonic.setText(seed);
|
tvWalletMnemonic.setText(seed);
|
||||||
tvWalletViewKey.setText(viewKey);
|
tvWalletViewKey.setText(viewKey);
|
||||||
tvWalletSpendKey.setText(spendKey);
|
tvWalletSpendKey.setText(spendKey);
|
||||||
|
bAdvancedInfo.setVisibility(View.VISIBLE);
|
||||||
|
bCopyAddress.setEnabled(true);
|
||||||
|
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
||||||
|
activityCallback.setTitle(name, getString(R.string.details_title));
|
||||||
|
activityCallback.setToolbarButton(
|
||||||
|
GenerateReviewFragment.VIEW_TYPE_ACCEPT.equals(type) ? Toolbar.BUTTON_NONE : Toolbar.BUTTON_BACK);
|
||||||
} else {
|
} else {
|
||||||
// TODO show proper error message
|
// TODO show proper error message and/or end the fragment?
|
||||||
// TODO end the fragment
|
|
||||||
tvWalletAddress.setText(status.toString());
|
tvWalletAddress.setText(status.toString());
|
||||||
tvWalletMnemonic.setText(status.toString());
|
tvWalletMnemonic.setText(status.toString());
|
||||||
tvWalletViewKey.setText(status.toString());
|
tvWalletViewKey.setText(status.toString());
|
||||||
@@ -180,38 +241,55 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateReviewFragment.Listener acceptCallback = null;
|
Listener activityCallback = null;
|
||||||
GenerateReviewFragment.ListenerWithWallet walletCallback = null;
|
AcceptListener acceptCallback = null;
|
||||||
|
ListenerWithWallet walletCallback = null;
|
||||||
|
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
|
void setTitle(String title, String subtitle);
|
||||||
|
|
||||||
|
void setToolbarButton(int type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface AcceptListener {
|
||||||
void onAccept(String name, String password);
|
void onAccept(String name, String password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ListenerWithWallet {
|
public interface ListenerWithWallet {
|
||||||
Wallet getWallet();
|
Wallet getWallet();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
if (context instanceof GenerateReviewFragment.Listener) {
|
if (context instanceof Listener) {
|
||||||
this.acceptCallback = (GenerateReviewFragment.Listener) context;
|
this.activityCallback = (Listener) context;
|
||||||
} else if (context instanceof GenerateReviewFragment.ListenerWithWallet) {
|
}
|
||||||
this.walletCallback = (GenerateReviewFragment.ListenerWithWallet) context;
|
if (context instanceof AcceptListener) {
|
||||||
} else {
|
this.acceptCallback = (AcceptListener) context;
|
||||||
throw new ClassCastException(context.toString()
|
}
|
||||||
+ " must implement Listener");
|
if (context instanceof ListenerWithWallet) {
|
||||||
|
this.walletCallback = (ListenerWithWallet) context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
Log.d(TAG, "onResume()");
|
||||||
|
String name = tvWalletName.getText().toString();
|
||||||
|
if (name.isEmpty()) name = null;
|
||||||
|
activityCallback.setTitle(name, getString(R.string.details_title));
|
||||||
|
activityCallback.setToolbarButton(
|
||||||
|
GenerateReviewFragment.VIEW_TYPE_ACCEPT.equals(type) ? Toolbar.BUTTON_NONE : Toolbar.BUTTON_BACK);
|
||||||
|
}
|
||||||
|
|
||||||
public void showProgress() {
|
public void showProgress() {
|
||||||
pbProgress.setIndeterminate(true);
|
|
||||||
pbProgress.setVisibility(View.VISIBLE);
|
pbProgress.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideProgress() {
|
public void hideProgress() {
|
||||||
pbProgress.setVisibility(View.INVISIBLE);
|
pbProgress.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean backOk() {
|
boolean backOk() {
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,6 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
import com.m2049r.xmrwallet.util.BarcodeData;
|
|
||||||
|
|
||||||
import me.dm7.barcodescanner.zxing.ZXingScannerView;
|
import me.dm7.barcodescanner.zxing.ZXingScannerView;
|
||||||
|
|
||||||
@@ -64,7 +63,6 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleResult(Result rawResult) {
|
public void handleResult(Result rawResult) {
|
||||||
//Log.d(TAG, rawResult.getBarcodeFormat().toString() + "/" + rawResult.getText());
|
|
||||||
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE) &&
|
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE) &&
|
||||||
(rawResult.getText().startsWith(QR_SCHEME))) {
|
(rawResult.getText().startsWith(QR_SCHEME))) {
|
||||||
if (activityCallback.onAddressScanned(rawResult.getText())) {
|
if (activityCallback.onAddressScanned(rawResult.getText())) {
|
||||||
@@ -101,7 +99,6 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
|||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
//Log.d(TAG, "attaching scan");
|
|
||||||
if (context instanceof Listener) {
|
if (context instanceof Listener) {
|
||||||
this.activityCallback = (Listener) context;
|
this.activityCallback = (Listener) context;
|
||||||
} else {
|
} else {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -16,19 +16,22 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.content.ClipData;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Transfer;
|
import com.m2049r.xmrwallet.model.Transfer;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
@@ -64,14 +67,13 @@ public class TxFragment extends Fragment {
|
|||||||
TextView tvTxFee;
|
TextView tvTxFee;
|
||||||
TextView tvTxTransfers;
|
TextView tvTxTransfers;
|
||||||
TextView etTxNotes;
|
TextView etTxNotes;
|
||||||
Button bCopy;
|
|
||||||
Button bTxNotes;
|
Button bTxNotes;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
|
||||||
View view = inflater.inflate(R.layout.tx_fragment, container, false);
|
View view = inflater.inflate(R.layout.fragment_tx_info, container, false);
|
||||||
|
|
||||||
tvTxTimestamp = (TextView) view.findViewById(R.id.tvTxTimestamp);
|
tvTxTimestamp = (TextView) view.findViewById(R.id.tvTxTimestamp);
|
||||||
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
||||||
@@ -83,18 +85,10 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
||||||
tvTxTransfers = (TextView) view.findViewById(R.id.tvTxTransfers);
|
tvTxTransfers = (TextView) view.findViewById(R.id.tvTxTransfers);
|
||||||
etTxNotes = (TextView) view.findViewById(R.id.etTxNotes);
|
etTxNotes = (TextView) view.findViewById(R.id.etTxNotes);
|
||||||
bCopy = (Button) view.findViewById(R.id.bCopy);
|
|
||||||
bTxNotes = (Button) view.findViewById(R.id.bTxNotes);
|
bTxNotes = (Button) view.findViewById(R.id.bTxNotes);
|
||||||
|
|
||||||
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
|
||||||
bCopy.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
copyToClipboard();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
bTxNotes.setOnClickListener(new View.OnClickListener() {
|
bTxNotes.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
@@ -119,28 +113,35 @@ public class TxFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyToClipboard() {
|
void shareTxInfo() {
|
||||||
if (this.info == null) return;
|
if (this.info == null) return;
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append(getString(R.string.tx_address)).append(": ");
|
|
||||||
sb.append(activityCallback.getWalletAddress()).append("\n");
|
sb.append(getString(R.string.tx_timestamp)).append(":\n");
|
||||||
sb.append(getString(R.string.tx_id)).append(": ");
|
sb.append(TS_FORMATTER.format(new Date(info.timestamp * 1000))).append("\n\n");
|
||||||
sb.append(info.hash).append("\n");
|
|
||||||
sb.append(getString(R.string.tx_key)).append(": ");
|
sb.append(getString(R.string.tx_amount)).append(":\n");
|
||||||
sb.append(info.txKey.isEmpty() ? "-" : info.txKey).append("\n");
|
|
||||||
sb.append(getString(R.string.tx_paymentId)).append(": ");
|
|
||||||
sb.append(info.paymentId).append("\n");
|
|
||||||
sb.append(getString(R.string.tx_amount)).append(": ");
|
|
||||||
sb.append((info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-"));
|
sb.append((info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-"));
|
||||||
sb.append(Wallet.getDisplayAmount(info.amount)).append("\n");
|
sb.append(Wallet.getDisplayAmount(info.amount)).append("\n");
|
||||||
sb.append(getString(R.string.tx_fee)).append(": ");
|
sb.append(getString(R.string.tx_fee)).append(":\n");
|
||||||
sb.append(Wallet.getDisplayAmount(info.fee)).append("\n");
|
sb.append(Wallet.getDisplayAmount(info.fee)).append("\n\n");
|
||||||
sb.append(getString(R.string.tx_notes)).append(": ");
|
|
||||||
|
sb.append(getString(R.string.tx_notes)).append(":\n");
|
||||||
String oneLineNotes = info.notes.replace("\n", " ; ");
|
String oneLineNotes = info.notes.replace("\n", " ; ");
|
||||||
sb.append(oneLineNotes.isEmpty() ? "-" : oneLineNotes).append("\n");
|
sb.append(oneLineNotes.isEmpty() ? "-" : oneLineNotes).append("\n\n");
|
||||||
sb.append(getString(R.string.tx_timestamp)).append(": ");
|
|
||||||
sb.append(TS_FORMATTER.format(new Date(info.timestamp * 1000))).append("\n");
|
sb.append(getString(R.string.tx_destination)).append(":\n");
|
||||||
sb.append(getString(R.string.tx_blockheight)).append(": ");
|
sb.append(tvDestination.getText()).append("\n\n");
|
||||||
|
|
||||||
|
sb.append(getString(R.string.tx_paymentId)).append(":\n");
|
||||||
|
sb.append(info.paymentId).append("\n\n");
|
||||||
|
|
||||||
|
sb.append(getString(R.string.tx_id)).append(":\n");
|
||||||
|
sb.append(info.hash).append("\n");
|
||||||
|
sb.append(getString(R.string.tx_key)).append(":\n");
|
||||||
|
sb.append(info.txKey.isEmpty() ? "-" : info.txKey).append("\n\n");
|
||||||
|
|
||||||
|
sb.append(getString(R.string.tx_blockheight)).append(":\n");
|
||||||
if (info.isFailed) {
|
if (info.isFailed) {
|
||||||
sb.append(getString(R.string.tx_failed)).append("\n");
|
sb.append(getString(R.string.tx_failed)).append("\n");
|
||||||
} else if (info.isPending) {
|
} else if (info.isPending) {
|
||||||
@@ -148,7 +149,9 @@ public class TxFragment extends Fragment {
|
|||||||
} else {
|
} else {
|
||||||
sb.append(info.blockheight).append("\n");
|
sb.append(info.blockheight).append("\n");
|
||||||
}
|
}
|
||||||
sb.append(getString(R.string.tx_transfers)).append(": ");
|
sb.append("\n");
|
||||||
|
|
||||||
|
sb.append(getString(R.string.tx_transfers)).append(":\n");
|
||||||
if (info.transfers != null) {
|
if (info.transfers != null) {
|
||||||
boolean comma = false;
|
boolean comma = false;
|
||||||
for (Transfer transfer : info.transfers) {
|
for (Transfer transfer : info.transfers) {
|
||||||
@@ -163,12 +166,14 @@ public class TxFragment extends Fragment {
|
|||||||
} else {
|
} else {
|
||||||
sb.append("-");
|
sb.append("-");
|
||||||
}
|
}
|
||||||
sb.append("\n");
|
sb.append("\n\n");
|
||||||
ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
|
//Helper.clipBoardCopy(getActivity(), getString(R.string.tx_copy_label), sb.toString());
|
||||||
ClipData clip = ClipData.newPlainText(getString(R.string.tx_copy_label), sb.toString());
|
//Toast.makeText(getActivity(), getString(R.string.tx_copy_message), Toast.LENGTH_SHORT).show();
|
||||||
clipboardManager.setPrimaryClip(clip);
|
Intent sendIntent = new Intent();
|
||||||
Toast.makeText(getActivity(), getString(R.string.tx_copy_message), Toast.LENGTH_SHORT).show();
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
//Log.d(TAG, sb.toString());
|
sendIntent.putExtra(Intent.EXTRA_TEXT, sb.toString());
|
||||||
|
sendIntent.setType("text/plain");
|
||||||
|
startActivity(Intent.createChooser(sendIntent, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionInfo info = null;
|
TransactionInfo info = null;
|
||||||
@@ -176,17 +181,24 @@ public class TxFragment extends Fragment {
|
|||||||
void loadNotes(TransactionInfo info) {
|
void loadNotes(TransactionInfo info) {
|
||||||
if (info.notes == null) {
|
if (info.notes == null) {
|
||||||
info.notes = activityCallback.getTxNotes(info.hash);
|
info.notes = activityCallback.getTxNotes(info.hash);
|
||||||
//Log.d(TAG, "NOTES:" + info.notes + ":");
|
|
||||||
}
|
}
|
||||||
etTxNotes.setText(info.notes);
|
etTxNotes.setText(info.notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setTxColour(int clr) {
|
||||||
|
tvTxAmount.setTextColor(clr);
|
||||||
|
tvTxFee.setTextColor(clr);
|
||||||
|
}
|
||||||
|
|
||||||
private void show(TransactionInfo info) {
|
private void show(TransactionInfo info) {
|
||||||
if (info.txKey == null) {
|
if (info.txKey == null) {
|
||||||
info.txKey = activityCallback.getTxKey(info.hash);
|
info.txKey = activityCallback.getTxKey(info.hash);
|
||||||
//Log.d(TAG, "TXKEY:" + info.txKey + ":");
|
|
||||||
}
|
}
|
||||||
loadNotes(info);
|
loadNotes(info);
|
||||||
|
|
||||||
|
activityCallback.setSubtitle(getString(R.string.tx_title));
|
||||||
|
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||||
|
|
||||||
tvTxTimestamp.setText(TS_FORMATTER.format(new Date(info.timestamp * 1000)));
|
tvTxTimestamp.setText(TS_FORMATTER.format(new Date(info.timestamp * 1000)));
|
||||||
tvTxId.setText(info.hash);
|
tvTxId.setText(info.hash);
|
||||||
tvTxKey.setText(info.txKey.isEmpty() ? "-" : info.txKey);
|
tvTxKey.setText(info.txKey.isEmpty() ? "-" : info.txKey);
|
||||||
@@ -199,8 +211,30 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxBlockheight.setText("" + info.blockheight);
|
tvTxBlockheight.setText("" + info.blockheight);
|
||||||
}
|
}
|
||||||
String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
|
String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
|
||||||
|
|
||||||
tvTxAmount.setText(sign + Wallet.getDisplayAmount(info.amount));
|
tvTxAmount.setText(sign + Wallet.getDisplayAmount(info.amount));
|
||||||
tvTxFee.setText(Wallet.getDisplayAmount(info.fee));
|
if ((info.fee > 0)) {
|
||||||
|
String fee = Wallet.getDisplayAmount(info.fee);
|
||||||
|
if (info.isPending) {
|
||||||
|
tvTxFee.setText(getString(R.string.tx_list_fee_pending, fee));
|
||||||
|
} else {
|
||||||
|
tvTxFee.setText(getString(R.string.tx_list_fee, fee));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tvTxFee.setText(null);
|
||||||
|
tvTxFee.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if (info.isFailed) {
|
||||||
|
tvTxAmount.setText(getString(R.string.tx_list_amount_failed, Wallet.getDisplayAmount(info.amount)));
|
||||||
|
tvTxFee.setText(getString(R.string.tx_list_failed_text));
|
||||||
|
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_failed));
|
||||||
|
} else if (info.isPending) {
|
||||||
|
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_pending));
|
||||||
|
} else if (info.direction == TransactionInfo.Direction.Direction_In) {
|
||||||
|
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_green));
|
||||||
|
} else {
|
||||||
|
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_red));
|
||||||
|
}
|
||||||
Set<String> destinations = new HashSet<>();
|
Set<String> destinations = new HashSet<>();
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
StringBuffer dstSb = new StringBuffer();
|
StringBuffer dstSb = new StringBuffer();
|
||||||
@@ -232,10 +266,21 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxTransfers.setText(sb.toString());
|
tvTxTransfers.setText(sb.toString());
|
||||||
tvDestination.setText(dstSb.toString());
|
tvDestination.setText(dstSb.toString());
|
||||||
this.info = info;
|
this.info = info;
|
||||||
bCopy.setEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TxFragment.Listener activityCallback;
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
inflater.inflate(R.menu.tx_info_menu, menu);
|
||||||
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
|
}
|
||||||
|
|
||||||
|
Listener activityCallback;
|
||||||
|
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
String getWalletAddress();
|
String getWalletAddress();
|
||||||
@@ -246,6 +291,10 @@ public class TxFragment extends Fragment {
|
|||||||
|
|
||||||
void onSetNote(String txId, String notes);
|
void onSetNote(String txId, String notes);
|
||||||
|
|
||||||
|
void setToolbarButton(int type);
|
||||||
|
|
||||||
|
void setSubtitle(String subtitle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@ import android.support.v4.app.DialogFragment;
|
|||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
@@ -43,6 +44,7 @@ import java.io.InputStreamReader;
|
|||||||
* http://speakman.net.nz
|
* http://speakman.net.nz
|
||||||
*/
|
*/
|
||||||
public class HelpFragment extends DialogFragment {
|
public class HelpFragment extends DialogFragment {
|
||||||
|
static final String TAG = "HelpFragment";
|
||||||
private static final String FRAGMENT_TAG = "com.m2049r.xmrwallet.dialog.HelpFragment";
|
private static final String FRAGMENT_TAG = "com.m2049r.xmrwallet.dialog.HelpFragment";
|
||||||
private static final String HELP_ID = "HELP_ID";
|
private static final String HELP_ID = "HELP_ID";
|
||||||
|
|
||||||
@@ -67,7 +69,6 @@ public class HelpFragment extends DialogFragment {
|
|||||||
if (prev != null) {
|
if (prev != null) {
|
||||||
ft.remove(prev);
|
ft.remove(prev);
|
||||||
}
|
}
|
||||||
ft.addToBackStack(null);
|
|
||||||
|
|
||||||
// Create and show the dialog.
|
// Create and show the dialog.
|
||||||
DialogFragment newFragment = HelpFragment.newInstance(helpResourceId);
|
DialogFragment newFragment = HelpFragment.newInstance(helpResourceId);
|
||||||
@@ -100,7 +101,7 @@ public class HelpFragment extends DialogFragment {
|
|||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
View content = LayoutInflater.from(getActivity()).inflate(R.layout.help_fragment, null);
|
View content = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_help, null);
|
||||||
webView = (WebView) content.findViewById(R.id.helpFragmentWebView);
|
webView = (WebView) content.findViewById(R.id.helpFragmentWebView);
|
||||||
progress = (ProgressBar) content.findViewById(R.id.helpFragmentProgress);
|
progress = (ProgressBar) content.findViewById(R.id.helpFragmentProgress);
|
||||||
|
|
||||||
@@ -136,8 +137,8 @@ public class HelpFragment extends DialogFragment {
|
|||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
bufferedReader.close();
|
bufferedReader.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException ex) {
|
||||||
// TODO You may want to include some logging here.
|
Log.e(TAG, ex.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@@ -16,22 +16,17 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet.dialog;
|
package com.m2049r.xmrwallet.dialog;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
//TODO If you don't support Android 2.x, you should use the non-support version!
|
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
@@ -41,11 +36,17 @@ import android.widget.TextView;
|
|||||||
import com.m2049r.xmrwallet.BuildConfig;
|
import com.m2049r.xmrwallet.BuildConfig;
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Adam Speakman on 24/09/13.
|
* Created by Adam Speakman on 24/09/13.
|
||||||
* http://speakman.net.nz
|
* http://speakman.net.nz
|
||||||
*/
|
*/
|
||||||
public class LicensesFragment extends DialogFragment {
|
public class LicensesFragment extends DialogFragment {
|
||||||
|
static final String TAG = "LicensesFragment";
|
||||||
int versionCode = BuildConfig.VERSION_CODE;
|
int versionCode = BuildConfig.VERSION_CODE;
|
||||||
String versionName = BuildConfig.VERSION_NAME;
|
String versionName = BuildConfig.VERSION_NAME;
|
||||||
|
|
||||||
@@ -102,7 +103,7 @@ public class LicensesFragment extends DialogFragment {
|
|||||||
@SuppressLint("InflateParams")
|
@SuppressLint("InflateParams")
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
View content = LayoutInflater.from(getActivity()).inflate(R.layout.licenses_fragment, null);
|
View content = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_licenses, null);
|
||||||
mWebView = (WebView) content.findViewById(R.id.licensesFragmentWebView);
|
mWebView = (WebView) content.findViewById(R.id.licensesFragmentWebView);
|
||||||
mIndeterminateProgress = (ProgressBar) content.findViewById(R.id.licensesFragmentIndeterminateProgress);
|
mIndeterminateProgress = (ProgressBar) content.findViewById(R.id.licensesFragmentIndeterminateProgress);
|
||||||
|
|
||||||
@@ -140,8 +141,8 @@ public class LicensesFragment extends DialogFragment {
|
|||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
bufferedReader.close();
|
bufferedReader.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException ex) {
|
||||||
// TODO You may want to include some logging here.
|
Log.e(TAG, ex.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* 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,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// based on from https://stackoverflow.com/a/45325876 (which did not work for me)
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.layout;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.design.widget.TextInputLayout;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
public class CTextInputLayout extends TextInputLayout {
|
||||||
|
public CTextInputLayout(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CTextInputLayout(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBaseline() {
|
||||||
|
EditText editText = getEditText();
|
||||||
|
return editText.getBaseline() - (getMeasuredHeight() - editText.getMeasuredHeight());
|
||||||
|
}
|
||||||
|
}
|
399
app/src/main/java/com/m2049r/xmrwallet/layout/ExchangeView.java
Normal file
399
app/src/main/java/com/m2049r/xmrwallet/layout/ExchangeView.java
Normal file
File diff suppressed because it is too large
Load Diff
155
app/src/main/java/com/m2049r/xmrwallet/layout/Toolbar.java
Normal file
155
app/src/main/java/com/m2049r/xmrwallet/layout/Toolbar.java
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// based on https://code.tutsplus.com/tutorials/creating-compound-views-on-android--cms-22889
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.layout;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.R;
|
||||||
|
|
||||||
|
public class Toolbar extends android.support.v7.widget.Toolbar {
|
||||||
|
static final String TAG = "Toolbar";
|
||||||
|
|
||||||
|
public interface OnButtonListener {
|
||||||
|
void onButton(int type);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnButtonListener onButtonListener;
|
||||||
|
|
||||||
|
public void setOnButtonListener(OnButtonListener listener) {
|
||||||
|
onButtonListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageView toolbarImage;
|
||||||
|
TextView toolbarTitle;
|
||||||
|
TextView toolbarSubtitle;
|
||||||
|
Button bDonate;
|
||||||
|
|
||||||
|
public Toolbar(Context context) {
|
||||||
|
super(context);
|
||||||
|
initializeViews(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Toolbar(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
initializeViews(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Toolbar(Context context,
|
||||||
|
AttributeSet attrs,
|
||||||
|
int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
initializeViews(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inflates the views in the layout.
|
||||||
|
*
|
||||||
|
* @param context the current context for the view.
|
||||||
|
*/
|
||||||
|
private void initializeViews(Context context) {
|
||||||
|
LayoutInflater inflater = (LayoutInflater) context
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
inflater.inflate(R.layout.view_toolbar, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFinishInflate() {
|
||||||
|
super.onFinishInflate();
|
||||||
|
toolbarImage = (ImageView) findViewById(R.id.toolbarImage);
|
||||||
|
toolbarTitle = (TextView) findViewById(R.id.toolbarTitle);
|
||||||
|
toolbarSubtitle = (TextView) findViewById(R.id.toolbarSubtitle);
|
||||||
|
bDonate = (Button) findViewById(R.id.bDonate);
|
||||||
|
bDonate.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (onButtonListener != null) {
|
||||||
|
onButtonListener.onButton(buttonType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title, String subtitle) {
|
||||||
|
setTitle(title);
|
||||||
|
setSubtitle(subtitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
toolbarTitle.setText(title);
|
||||||
|
if (title != null) {
|
||||||
|
toolbarImage.setVisibility(View.INVISIBLE);
|
||||||
|
toolbarTitle.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
toolbarImage.setVisibility(View.VISIBLE);
|
||||||
|
toolbarTitle.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static int BUTTON_NONE = 0;
|
||||||
|
public final static int BUTTON_BACK = 1;
|
||||||
|
public final static int BUTTON_CLOSE = 2;
|
||||||
|
public final static int BUTTON_DONATE = 3;
|
||||||
|
|
||||||
|
int buttonType = BUTTON_DONATE;
|
||||||
|
|
||||||
|
public void setButton(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case BUTTON_BACK:
|
||||||
|
Log.d(TAG, "BUTTON_BACK");
|
||||||
|
bDonate.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_arrow_back_white_24dp, 0, 0, 0);
|
||||||
|
bDonate.setText(null);
|
||||||
|
bDonate.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
case BUTTON_CLOSE:
|
||||||
|
Log.d(TAG, "BUTTON_CLOSE");
|
||||||
|
bDonate.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_close_white_24dp, 0, 0, 0);
|
||||||
|
bDonate.setText(R.string.label_close);
|
||||||
|
bDonate.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
case BUTTON_DONATE:
|
||||||
|
Log.d(TAG, "BUTTON_DONATE");
|
||||||
|
bDonate.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_favorite_white_24dp, 0, 0, 0);
|
||||||
|
bDonate.setText(R.string.label_donate);
|
||||||
|
bDonate.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
case BUTTON_NONE:
|
||||||
|
default:
|
||||||
|
Log.d(TAG, "BUTTON_NONE");
|
||||||
|
bDonate.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||||
|
bDonate.setText(null);
|
||||||
|
bDonate.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
buttonType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubtitle(String subtitle) {
|
||||||
|
toolbarSubtitle.setText(subtitle);
|
||||||
|
if (subtitle != null) {
|
||||||
|
toolbarSubtitle.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
toolbarSubtitle.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -17,7 +17,6 @@
|
|||||||
package com.m2049r.xmrwallet.layout;
|
package com.m2049r.xmrwallet.layout;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -28,13 +27,12 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
@@ -69,7 +67,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
outboundColour = ContextCompat.getColor(context, R.color.tx_red);
|
outboundColour = ContextCompat.getColor(context, R.color.tx_red);
|
||||||
pendingColour = ContextCompat.getColor(context, R.color.tx_pending);
|
pendingColour = ContextCompat.getColor(context, R.color.tx_pending);
|
||||||
failedColour = ContextCompat.getColor(context, R.color.tx_failed);
|
failedColour = ContextCompat.getColor(context, R.color.tx_failed);
|
||||||
this.infoItems = new ArrayList<>();
|
infoItems = new ArrayList<>();
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
TimeZone tz = cal.getTimeZone(); //get the local time zone.
|
TimeZone tz = cal.getTimeZone(); //get the local time zone.
|
||||||
@@ -79,7 +77,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
View view = LayoutInflater.from(parent.getContext())
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.transaction_item, parent, false);
|
.inflate(R.layout.item_transaction, parent, false);
|
||||||
return new ViewHolder(view);
|
return new ViewHolder(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,22 +97,8 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
this.infoItems.clear();
|
this.infoItems.clear();
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
Log.d(TAG, "setInfos " + data.size());
|
Log.d(TAG, "setInfos " + data.size());
|
||||||
// sort by block height
|
infoItems.addAll(data);
|
||||||
Collections.sort(data, new Comparator<TransactionInfo>() {
|
Collections.sort(infoItems);
|
||||||
@Override
|
|
||||||
public int compare(TransactionInfo o1, TransactionInfo o2) {
|
|
||||||
long b1 = o1.timestamp;
|
|
||||||
long b2 = o2.timestamp;
|
|
||||||
if (b1 > b2) {
|
|
||||||
return -1;
|
|
||||||
} else if (b1 < b2) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return o1.hash.compareTo(o2.hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.infoItems.addAll(data);
|
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "setInfos null");
|
Log.d(TAG, "setInfos null");
|
||||||
}
|
}
|
||||||
@@ -147,36 +131,41 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
|||||||
|
|
||||||
void bind(int position) {
|
void bind(int position) {
|
||||||
this.infoItem = infoItems.get(position);
|
this.infoItem = infoItems.get(position);
|
||||||
String displayAmount = Wallet.getDisplayAmount(infoItem.amount);
|
|
||||||
// TODO fix this with i8n code but cryptonote::print_money always uses '.' for decimal point
|
long realAmount = infoItem.amount;
|
||||||
String amount = displayAmount.substring(0, displayAmount.length() - (12 - 5));
|
if (infoItem.isPending) {
|
||||||
this.tvAmount.setText(amount);
|
realAmount = realAmount - infoItem.fee;
|
||||||
|
}
|
||||||
|
|
||||||
|
String displayAmount = Helper.getDisplayAmount(realAmount, Helper.DISPLAY_DIGITS_INFO);
|
||||||
|
if (infoItem.direction == TransactionInfo.Direction.Direction_Out) {
|
||||||
|
this.tvAmount.setText(context.getString(R.string.tx_list_amount_negative, displayAmount));
|
||||||
|
} else {
|
||||||
|
this.tvAmount.setText(context.getString(R.string.tx_list_amount_positive, displayAmount));
|
||||||
|
}
|
||||||
|
|
||||||
if ((infoItem.fee > 0)) {
|
if ((infoItem.fee > 0)) {
|
||||||
String feeAmount = Wallet.getDisplayAmount(infoItem.fee);
|
String fee = Helper.getDisplayAmount(infoItem.fee, 5);
|
||||||
String fee = feeAmount.substring(0, feeAmount.length() - (12 - 5));
|
this.tvFee.setText(context.getString(R.string.tx_list_fee, fee));
|
||||||
if (infoItem.isPending) {
|
|
||||||
this.tvFee.setText(context.getString(R.string.tx_list_fee_pending, fee));
|
|
||||||
} else {
|
|
||||||
this.tvFee.setText(context.getString(R.string.tx_list_fee, fee));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.tvFee.setText("");
|
this.tvFee.setText("");
|
||||||
}
|
}
|
||||||
if (infoItem.isFailed) {
|
if (infoItem.isFailed) {
|
||||||
this.tvAmount.setText(context.getString(R.string.tx_list_amount_failed, amount));
|
this.tvAmount.setText(context.getString(R.string.tx_list_amount_failed, displayAmount));
|
||||||
|
this.tvFee.setText(context.getString(R.string.tx_list_failed_text));
|
||||||
setTxColour(failedColour);
|
setTxColour(failedColour);
|
||||||
} else if (infoItem.isPending) {
|
} else if (infoItem.isPending) {
|
||||||
setTxColour(pendingColour);
|
setTxColour(pendingColour);
|
||||||
if (infoItem.direction == TransactionInfo.Direction.Direction_Out) {
|
|
||||||
this.tvAmount.setText(context.getString(R.string.tx_list_amount_negative, amount));
|
|
||||||
}
|
|
||||||
} else if (infoItem.direction == TransactionInfo.Direction.Direction_In) {
|
} else if (infoItem.direction == TransactionInfo.Direction.Direction_In) {
|
||||||
setTxColour(inboundColour);
|
setTxColour(inboundColour);
|
||||||
} else {
|
} else {
|
||||||
setTxColour(outboundColour);
|
setTxColour(outboundColour);
|
||||||
}
|
}
|
||||||
this.tvPaymentId.setText(infoItem.paymentId.equals("0000000000000000") ? "" : infoItem.paymentId);
|
if ((infoItem.notes == null) || (infoItem.notes.isEmpty())) {
|
||||||
|
this.tvPaymentId.setText(infoItem.paymentId.equals("0000000000000000") ? "" : infoItem.paymentId);
|
||||||
|
} else {
|
||||||
|
this.tvPaymentId.setText(infoItem.notes);
|
||||||
|
}
|
||||||
this.tvDateTime.setText(getDateTime(infoItem.timestamp));
|
this.tvDateTime.setText(getDateTime(infoItem.timestamp));
|
||||||
|
|
||||||
itemView.setOnClickListener(this);
|
itemView.setOnClickListener(this);
|
||||||
|
@@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* 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.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;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.R;
|
||||||
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
public interface OnInteractionListener {
|
||||||
|
void onInteraction(View view, WalletManager.WalletInfo item);
|
||||||
|
|
||||||
|
boolean onContextInteraction(MenuItem item, WalletManager.WalletInfo infoItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<WalletManager.WalletInfo> infoItems;
|
||||||
|
private final OnInteractionListener listener;
|
||||||
|
|
||||||
|
Context context;
|
||||||
|
|
||||||
|
public WalletInfoAdapter(Context context, OnInteractionListener listener) {
|
||||||
|
this.context = context;
|
||||||
|
this.infoItems = new ArrayList<>();
|
||||||
|
this.listener = listener;
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
TimeZone tz = cal.getTimeZone(); //get the local time zone.
|
||||||
|
DATETIME_FORMATTER.setTimeZone(tz);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.item_wallet, parent, false);
|
||||||
|
return new ViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(final ViewHolder holder, int position) {
|
||||||
|
holder.bind(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return infoItems.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WalletManager.WalletInfo getItem(int position) {
|
||||||
|
return infoItems.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInfos(List<WalletManager.WalletInfo> data) {
|
||||||
|
// TODO do stuff with data so we can really recycle elements (i.e. add only new tx)
|
||||||
|
// as the WalletInfo items are always recreated, we cannot recycle
|
||||||
|
infoItems.clear();
|
||||||
|
if (data != null) {
|
||||||
|
Log.d(TAG, "setInfos " + data.size());
|
||||||
|
infoItems.addAll(data);
|
||||||
|
Collections.sort(infoItems);
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "setInfos null");
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||||
|
final TextView tvName;
|
||||||
|
final TextView tvAddress;
|
||||||
|
final ImageButton ibOptions;
|
||||||
|
WalletManager.WalletInfo infoItem;
|
||||||
|
|
||||||
|
ViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
tvName = (TextView) itemView.findViewById(R.id.tvName);
|
||||||
|
tvAddress = (TextView) itemView.findViewById(R.id.tvAddress);
|
||||||
|
ibOptions = (ImageButton) itemView.findViewById(R.id.ibOptions);
|
||||||
|
ibOptions.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
//creating a popup menu
|
||||||
|
PopupMenu popup = new PopupMenu(context, ibOptions);
|
||||||
|
//inflating menu from xml resource
|
||||||
|
popup.inflate(R.menu.list_context_menu);
|
||||||
|
//adding click listener
|
||||||
|
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
if (listener != null) {
|
||||||
|
return listener.onContextInteraction(item, infoItem);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//displaying the popup
|
||||||
|
popup.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
itemView.setOnClickListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDateTime(long time) {
|
||||||
|
return DATETIME_FORMATTER.format(new Date(time * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
void bind(int position) {
|
||||||
|
infoItem = infoItems.get(position);
|
||||||
|
tvName.setText(infoItem.name);
|
||||||
|
tvAddress.setText(infoItem.address.substring(0, 16) + "...");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
if (listener != null) {
|
||||||
|
int position = getAdapterPosition(); // gets item position
|
||||||
|
if (position != RecyclerView.NO_POSITION) { // Check if an item was deleted, but the user clicked it before the UI removed it
|
||||||
|
listener.onInteraction(view, infoItems.get(position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -30,6 +30,12 @@ public class TransactionHistory {
|
|||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadNotes(Wallet wallet) {
|
||||||
|
for (TransactionInfo info : transactions) {
|
||||||
|
info.notes = wallet.getUserNote(info.hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public native int getCount();
|
public native int getCount();
|
||||||
|
|
||||||
//private native long getTransactionByIndexJ(int i);
|
//private native long getTransactionByIndexJ(int i);
|
||||||
@@ -42,6 +48,11 @@ public class TransactionHistory {
|
|||||||
|
|
||||||
private List<TransactionInfo> transactions = new ArrayList<>();
|
private List<TransactionInfo> transactions = new ArrayList<>();
|
||||||
|
|
||||||
|
public void refreshWithNotes(Wallet wallet) {
|
||||||
|
refresh();
|
||||||
|
loadNotes(wallet);
|
||||||
|
}
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
transactions = refreshJ();
|
transactions = refreshJ();
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ import java.util.Random;
|
|||||||
|
|
||||||
// this is not the TransactionInfo from the API as that is owned by the TransactionHistory
|
// this is not the TransactionInfo from the API as that is owned by the TransactionHistory
|
||||||
// this is a POJO for the TransactionInfoAdapter
|
// this is a POJO for the TransactionInfoAdapter
|
||||||
public class TransactionInfo implements Parcelable {
|
public class TransactionInfo implements Parcelable, Comparable<TransactionInfo> {
|
||||||
static final String TAG = "TransactionInfo";
|
static final String TAG = "TransactionInfo";
|
||||||
|
|
||||||
public enum Direction {
|
public enum Direction {
|
||||||
@@ -92,7 +92,6 @@ public class TransactionInfo implements Parcelable {
|
|||||||
this.confirmations = confirmations;
|
this.confirmations = confirmations;
|
||||||
this.transfers = transfers;
|
this.transfers = transfers;
|
||||||
}
|
}
|
||||||
Random rnd = new Random();
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return direction + "@" + blockheight + " " + amount;
|
return direction + "@" + blockheight + " " + amount;
|
||||||
@@ -146,4 +145,17 @@ public class TransactionInfo implements Parcelable {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(TransactionInfo another) {
|
||||||
|
long b1 = this.timestamp;
|
||||||
|
long b2 = another.timestamp;
|
||||||
|
if (b1 > b2) {
|
||||||
|
return -1;
|
||||||
|
} else if (b1 < b2) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return this.hash.compareTo(another.hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet.model;
|
package com.m2049r.xmrwallet.model;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@@ -45,36 +46,36 @@ public class WalletManager {
|
|||||||
return WalletManager.Instance;
|
return WalletManager.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WalletManager() {
|
//private Map<String, Wallet> managedWallets;
|
||||||
this.managedWallets = new HashMap<>();
|
private Wallet managedWallet = null;
|
||||||
|
|
||||||
|
public Wallet getWallet() {
|
||||||
|
return managedWallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Wallet> managedWallets;
|
private void manageWallet(Wallet wallet) {
|
||||||
|
Log.d(TAG, "Managing " + wallet.getName());
|
||||||
public Wallet getWallet(String walletId) {
|
managedWallet = wallet;
|
||||||
return managedWallets.get(walletId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void manageWallet(String walletId, Wallet wallet) {
|
private void unmanageWallet(Wallet wallet) {
|
||||||
if (getWallet(walletId) != null) {
|
if (wallet == null) {
|
||||||
throw new IllegalStateException(walletId + " already under management!");
|
throw new IllegalArgumentException("Cannot unmanage null!");
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Managing " + walletId);
|
if (getWallet() == null) {
|
||||||
managedWallets.put(walletId, wallet);
|
throw new IllegalStateException("No wallet under management!");
|
||||||
}
|
|
||||||
|
|
||||||
private void unmanageWallet(String walletId) {
|
|
||||||
if (getWallet(walletId) == null) {
|
|
||||||
throw new IllegalStateException(walletId + " not under management!");
|
|
||||||
}
|
}
|
||||||
Log.d(TAG, "Unmanaging " + walletId);
|
if (getWallet() != wallet) {
|
||||||
managedWallets.remove(walletId);
|
throw new IllegalStateException(wallet.getName() + " not under management!");
|
||||||
|
}
|
||||||
|
Log.d(TAG, "Unmanaging " + managedWallet.getName());
|
||||||
|
managedWallet = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Wallet createWallet(File aFile, String password, String language) {
|
public Wallet createWallet(File aFile, String password, String language) {
|
||||||
long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, isTestNet());
|
long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, isTestNet());
|
||||||
Wallet wallet = new Wallet(walletHandle);
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
manageWallet(wallet.getName(), wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ public class WalletManager {
|
|||||||
public Wallet openWallet(String path, String password) {
|
public Wallet openWallet(String path, String password) {
|
||||||
long walletHandle = openWalletJ(path, password, isTestNet());
|
long walletHandle = openWalletJ(path, password, isTestNet());
|
||||||
Wallet wallet = new Wallet(walletHandle);
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
manageWallet(wallet.getName(), wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,14 +92,14 @@ public class WalletManager {
|
|||||||
|
|
||||||
public Wallet recoveryWallet(File aFile, String mnemonic) {
|
public Wallet recoveryWallet(File aFile, String mnemonic) {
|
||||||
Wallet wallet = recoveryWallet(aFile, mnemonic, 0);
|
Wallet wallet = recoveryWallet(aFile, mnemonic, 0);
|
||||||
manageWallet(wallet.getName(), wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Wallet recoveryWallet(File aFile, String mnemonic, long restoreHeight) {
|
public Wallet recoveryWallet(File aFile, String mnemonic, long restoreHeight) {
|
||||||
long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), mnemonic, isTestNet(), restoreHeight);
|
long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), mnemonic, isTestNet(), restoreHeight);
|
||||||
Wallet wallet = new Wallet(walletHandle);
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
manageWallet(wallet.getName(), wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +110,7 @@ public class WalletManager {
|
|||||||
long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), language, isTestNet(), restoreHeight,
|
long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), language, isTestNet(), restoreHeight,
|
||||||
addressString, viewKeyString, spendKeyString);
|
addressString, viewKeyString, spendKeyString);
|
||||||
Wallet wallet = new Wallet(walletHandle);
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
manageWallet(wallet.getName(), wallet);
|
manageWallet(wallet);
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,13 +124,12 @@ public class WalletManager {
|
|||||||
public native boolean closeJ(Wallet wallet);
|
public native boolean closeJ(Wallet wallet);
|
||||||
|
|
||||||
public boolean close(Wallet wallet) {
|
public boolean close(Wallet wallet) {
|
||||||
String walletId = new File(wallet.getFilename()).getName();
|
unmanageWallet(wallet);
|
||||||
unmanageWallet(walletId);
|
|
||||||
boolean closed = closeJ(wallet);
|
boolean closed = closeJ(wallet);
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
// in case we could not close it
|
// in case we could not close it
|
||||||
// we unmanage it
|
// we manage it again
|
||||||
manageWallet(walletId, wallet);
|
manageWallet(wallet);
|
||||||
}
|
}
|
||||||
return closed;
|
return closed;
|
||||||
}
|
}
|
||||||
@@ -144,10 +144,20 @@ public class WalletManager {
|
|||||||
|
|
||||||
//public native List<String> findWallets(String path); // this does not work - some error in boost
|
//public native List<String> findWallets(String path); // this does not work - some error in boost
|
||||||
|
|
||||||
public class WalletInfo {
|
public class WalletInfo implements Comparable<WalletInfo> {
|
||||||
public File path;
|
public File path;
|
||||||
public String name;
|
public String name;
|
||||||
public String address;
|
public String address;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(WalletInfo another) {
|
||||||
|
int n = name.toLowerCase().compareTo(another.name.toLowerCase());
|
||||||
|
if (n != 0) {
|
||||||
|
return n;
|
||||||
|
} else { // wallet names are the same
|
||||||
|
return address.compareTo(another.address);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public WalletInfo getWalletInfo(File wallet) {
|
public WalletInfo getWalletInfo(File wallet) {
|
||||||
|
@@ -70,20 +70,11 @@ public class WalletService extends Service {
|
|||||||
private MyWalletListener listener = null;
|
private MyWalletListener listener = null;
|
||||||
|
|
||||||
private class MyWalletListener implements WalletListener {
|
private class MyWalletListener implements WalletListener {
|
||||||
private Wallet wallet;
|
|
||||||
boolean updated = true;
|
boolean updated = true;
|
||||||
|
|
||||||
Wallet getWallet() {
|
|
||||||
return wallet;
|
|
||||||
}
|
|
||||||
|
|
||||||
MyWalletListener(Wallet aWallet) {
|
|
||||||
if (aWallet == null) throw new IllegalArgumentException("Cannot open wallet!");
|
|
||||||
this.wallet = aWallet;
|
|
||||||
}
|
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
Log.d(TAG, "MyWalletListener.start()");
|
Log.d(TAG, "MyWalletListener.start()");
|
||||||
|
Wallet wallet = getWallet();
|
||||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||||
//acquireWakeLock();
|
//acquireWakeLock();
|
||||||
wallet.setListener(this);
|
wallet.setListener(this);
|
||||||
@@ -92,6 +83,7 @@ public class WalletService extends Service {
|
|||||||
|
|
||||||
void stop() {
|
void stop() {
|
||||||
Log.d(TAG, "MyWalletListener.stop()");
|
Log.d(TAG, "MyWalletListener.stop()");
|
||||||
|
Wallet wallet = getWallet();
|
||||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||||
wallet.pauseRefresh();
|
wallet.pauseRefresh();
|
||||||
wallet.setListener(null);
|
wallet.setListener(null);
|
||||||
@@ -115,6 +107,7 @@ public class WalletService extends Service {
|
|||||||
int lastTxCount = 0;
|
int lastTxCount = 0;
|
||||||
|
|
||||||
public void newBlock(long height) {
|
public void newBlock(long height) {
|
||||||
|
Wallet wallet = getWallet();
|
||||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||||
// don't flood with an update for every block ...
|
// don't flood with an update for every block ...
|
||||||
if (lastBlockTime < System.currentTimeMillis() - 2000) {
|
if (lastBlockTime < System.currentTimeMillis() - 2000) {
|
||||||
@@ -141,18 +134,20 @@ public class WalletService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updated() {
|
public void updated() {
|
||||||
Log.d(TAG, "updated() " + wallet.getBalance());
|
Log.d(TAG, "updated()");
|
||||||
|
Wallet wallet = getWallet();
|
||||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshed() {
|
public void refreshed() {
|
||||||
|
Log.d(TAG, "refreshed()");
|
||||||
|
Wallet wallet = getWallet();
|
||||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||||
Log.d(TAG, "refreshed() " + wallet.getName() + " " + wallet.getBalance() + " sync=" + wallet.isSynchronized() + " with observer " + observer);
|
|
||||||
if (updated) {
|
if (updated) {
|
||||||
if (observer != null) {
|
if (observer != null) {
|
||||||
updateDaemonState(wallet, 0);
|
updateDaemonState(wallet, 0);
|
||||||
wallet.getHistory().refresh();
|
wallet.getHistory().refreshWithNotes(wallet);
|
||||||
if (observer != null) {
|
if (observer != null) {
|
||||||
updated = !observer.onRefreshed(wallet, true);
|
updated = !observer.onRefreshed(wallet, true);
|
||||||
}
|
}
|
||||||
@@ -253,8 +248,7 @@ public class WalletService extends Service {
|
|||||||
|
|
||||||
//
|
//
|
||||||
public Wallet getWallet() {
|
public Wallet getWallet() {
|
||||||
if (listener == null) throw new IllegalStateException("no listener");
|
return WalletManager.getInstance().getWallet();
|
||||||
return listener.getWallet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
@@ -303,7 +297,7 @@ public class WalletService extends Service {
|
|||||||
boolean rc = myWallet.store();
|
boolean rc = myWallet.store();
|
||||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
Log.d(TAG, "Wallet store failed: " + myWallet.getErrorString());
|
Log.w(TAG, "Wallet store failed: " + myWallet.getErrorString());
|
||||||
}
|
}
|
||||||
if (observer != null) observer.onWalletStored(rc);
|
if (observer != null) observer.onWalletStored(rc);
|
||||||
} else if (cmd.equals(REQUEST_CMD_TX)) {
|
} else if (cmd.equals(REQUEST_CMD_TX)) {
|
||||||
@@ -315,7 +309,7 @@ public class WalletService extends Service {
|
|||||||
PendingTransaction.Status status = pendingTransaction.getStatus();
|
PendingTransaction.Status status = pendingTransaction.getStatus();
|
||||||
Log.d(TAG, "transaction status " + status);
|
Log.d(TAG, "transaction status " + status);
|
||||||
if (status != PendingTransaction.Status.Status_Ok) {
|
if (status != PendingTransaction.Status.Status_Ok) {
|
||||||
Log.d(TAG, "Create Transaction failed: " + pendingTransaction.getErrorString());
|
Log.w(TAG, "Create Transaction failed: " + pendingTransaction.getErrorString());
|
||||||
}
|
}
|
||||||
if (observer != null) {
|
if (observer != null) {
|
||||||
observer.onCreatedTransaction(pendingTransaction);
|
observer.onCreatedTransaction(pendingTransaction);
|
||||||
@@ -329,7 +323,7 @@ public class WalletService extends Service {
|
|||||||
PendingTransaction.Status status = pendingTransaction.getStatus();
|
PendingTransaction.Status status = pendingTransaction.getStatus();
|
||||||
Log.d(TAG, "transaction status " + status);
|
Log.d(TAG, "transaction status " + status);
|
||||||
if (status != PendingTransaction.Status.Status_Ok) {
|
if (status != PendingTransaction.Status.Status_Ok) {
|
||||||
Log.d(TAG, "Create Transaction failed: " + pendingTransaction.getErrorString());
|
Log.w(TAG, "Create Transaction failed: " + pendingTransaction.getErrorString());
|
||||||
}
|
}
|
||||||
if (observer != null) {
|
if (observer != null) {
|
||||||
observer.onCreatedTransaction(pendingTransaction);
|
observer.onCreatedTransaction(pendingTransaction);
|
||||||
@@ -358,7 +352,7 @@ public class WalletService extends Service {
|
|||||||
boolean rc = myWallet.store();
|
boolean rc = myWallet.store();
|
||||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
Log.d(TAG, "Wallet store failed: " + myWallet.getErrorString());
|
Log.w(TAG, "Wallet store failed: " + myWallet.getErrorString());
|
||||||
}
|
}
|
||||||
if (observer != null) observer.onWalletStored(rc);
|
if (observer != null) observer.onWalletStored(rc);
|
||||||
listener.updated = true;
|
listener.updated = true;
|
||||||
@@ -378,7 +372,7 @@ public class WalletService extends Service {
|
|||||||
boolean rc = myWallet.store();
|
boolean rc = myWallet.store();
|
||||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + rc);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
Log.d(TAG, "Wallet store failed: " + myWallet.getErrorString());
|
Log.w(TAG, "Wallet store failed: " + myWallet.getErrorString());
|
||||||
}
|
}
|
||||||
if (observer != null) observer.onWalletStored(rc);
|
if (observer != null) observer.onWalletStored(rc);
|
||||||
}
|
}
|
||||||
@@ -441,10 +435,15 @@ public class WalletService extends Service {
|
|||||||
// start ID so we know which request we're stopping when we finish the job
|
// start ID so we know which request we're stopping when we finish the job
|
||||||
Message msg = mServiceHandler.obtainMessage();
|
Message msg = mServiceHandler.obtainMessage();
|
||||||
msg.arg2 = START_SERVICE;
|
msg.arg2 = START_SERVICE;
|
||||||
msg.setData(intent.getExtras());
|
if (intent != null) {
|
||||||
mServiceHandler.sendMessage(msg);
|
msg.setData(intent.getExtras());
|
||||||
//Log.d(TAG, "onStartCommand() message sent");
|
mServiceHandler.sendMessage(msg);
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
|
} else {
|
||||||
|
// process restart - don't do anything - let system kill it again
|
||||||
|
stop();
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -466,9 +465,8 @@ public class WalletService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean start(String walletName, String walletPassword) {
|
private boolean start(String walletName, String walletPassword) {
|
||||||
startNotfication();
|
|
||||||
// if there is an listener it is always started / syncing
|
|
||||||
Log.d(TAG, "start()");
|
Log.d(TAG, "start()");
|
||||||
|
startNotfication();
|
||||||
showProgress(getString(R.string.status_wallet_loading));
|
showProgress(getString(R.string.status_wallet_loading));
|
||||||
showProgress(10);
|
showProgress(10);
|
||||||
if (listener == null) {
|
if (listener == null) {
|
||||||
@@ -478,7 +476,7 @@ public class WalletService extends Service {
|
|||||||
if (aWallet != null) aWallet.close();
|
if (aWallet != null) aWallet.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
listener = new MyWalletListener(aWallet);
|
listener = new MyWalletListener();
|
||||||
listener.start();
|
listener.start();
|
||||||
showProgress(100);
|
showProgress(100);
|
||||||
}
|
}
|
||||||
@@ -496,10 +494,6 @@ public class WalletService extends Service {
|
|||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.stop();
|
listener.stop();
|
||||||
Wallet myWallet = getWallet();
|
Wallet myWallet = getWallet();
|
||||||
// if (!myWallet.isSynchronized()) { // save only if NOT synced (to continue later)
|
|
||||||
// Log.d(TAG, "stop() saving");
|
|
||||||
// myWallet.store();
|
|
||||||
// }
|
|
||||||
Log.d(TAG, "stop() closing");
|
Log.d(TAG, "stop() closing");
|
||||||
myWallet.close();
|
myWallet.close();
|
||||||
Log.d(TAG, "stop() closed");
|
Log.d(TAG, "stop() closed");
|
||||||
@@ -511,17 +505,12 @@ public class WalletService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Wallet loadWallet(String walletName, String walletPassword) {
|
private Wallet loadWallet(String walletName, String walletPassword) {
|
||||||
//String path = Helper.getWalletPath(getApplicationContext(), walletName);
|
|
||||||
//Log.d(TAG, "open wallet " + path);
|
|
||||||
Wallet wallet = openWallet(walletName, walletPassword);
|
Wallet wallet = openWallet(walletName, walletPassword);
|
||||||
//Log.d(TAG, "wallet opened: " + wallet);
|
|
||||||
if (wallet != null) {
|
if (wallet != null) {
|
||||||
//Log.d(TAG, wallet.getStatus().toString());
|
|
||||||
Log.d(TAG, "Using daemon " + WalletManager.getInstance().getDaemonAddress());
|
Log.d(TAG, "Using daemon " + WalletManager.getInstance().getDaemonAddress());
|
||||||
showProgress(55);
|
showProgress(55);
|
||||||
wallet.init(0);
|
wallet.init(0);
|
||||||
showProgress(90);
|
showProgress(90);
|
||||||
//Log.d(TAG, wallet.getConnectionStatus().toString());
|
|
||||||
}
|
}
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
@@ -561,6 +550,5 @@ public class WalletService extends Service {
|
|||||||
.setContentIntent(pendingIntent)
|
.setContentIntent(pendingIntent)
|
||||||
.build();
|
.build();
|
||||||
startForeground(NOTIFICATION_ID, notification);
|
startForeground(NOTIFICATION_ID, notification);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,8 @@ package com.m2049r.xmrwallet.util;
|
|||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
@@ -40,7 +42,9 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
@@ -48,6 +52,9 @@ public class Helper {
|
|||||||
static private final String TAG = "Helper";
|
static private final String TAG = "Helper";
|
||||||
static private final String WALLET_DIR = "monerujo";
|
static private final String WALLET_DIR = "monerujo";
|
||||||
|
|
||||||
|
static public int DISPLAY_DIGITS_INFO = 5;
|
||||||
|
static public int DISPLAY_DIGITS_SHORT = 5;
|
||||||
|
|
||||||
static public File getStorageRoot(Context context) {
|
static public File getStorageRoot(Context context) {
|
||||||
if (!isExternalStorageWritable()) {
|
if (!isExternalStorageWritable()) {
|
||||||
String msg = context.getString(R.string.message_strorage_not_writable);
|
String msg = context.getString(R.string.message_strorage_not_writable);
|
||||||
@@ -73,7 +80,7 @@ public class Helper {
|
|||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||||
if (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
if (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
== PackageManager.PERMISSION_DENIED) {
|
== PackageManager.PERMISSION_DENIED) {
|
||||||
Log.d(TAG, "Permission denied to WRITE_EXTERNAL_STORAGE - requesting it");
|
Log.w(TAG, "Permission denied to WRITE_EXTERNAL_STORAGE - requesting it");
|
||||||
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
|
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
|
||||||
context.requestPermissions(permissions, PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
|
context.requestPermissions(permissions, PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
|
||||||
return false;
|
return false;
|
||||||
@@ -91,7 +98,7 @@ public class Helper {
|
|||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||||
if (context.checkSelfPermission(Manifest.permission.CAMERA)
|
if (context.checkSelfPermission(Manifest.permission.CAMERA)
|
||||||
== PackageManager.PERMISSION_DENIED) {
|
== PackageManager.PERMISSION_DENIED) {
|
||||||
Log.d(TAG, "Permission denied for CAMERA - requesting it");
|
Log.w(TAG, "Permission denied for CAMERA - requesting it");
|
||||||
String[] permissions = {Manifest.permission.CAMERA};
|
String[] permissions = {Manifest.permission.CAMERA};
|
||||||
context.requestPermissions(permissions, PERMISSIONS_REQUEST_CAMERA);
|
context.requestPermissions(permissions, PERMISSIONS_REQUEST_CAMERA);
|
||||||
return false;
|
return false;
|
||||||
@@ -103,13 +110,8 @@ public class Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static public String getWalletPath(Context context, String aWalletName) {
|
|
||||||
// return getWalletFile(context, aWalletName).getAbsolutePath();
|
|
||||||
// }
|
|
||||||
|
|
||||||
static public File getWalletFile(Context context, String aWalletName) {
|
static public File getWalletFile(Context context, String aWalletName) {
|
||||||
File walletDir = getStorageRoot(context);
|
File walletDir = getStorageRoot(context);
|
||||||
//d(TAG, "walletdir=" + walletDir.getAbsolutePath());
|
|
||||||
File f = new File(walletDir, aWalletName);
|
File f = new File(walletDir, aWalletName);
|
||||||
Log.d(TAG, "wallet = " + f.getAbsolutePath() + " size=" + f.length());
|
Log.d(TAG, "wallet = " + f.getAbsolutePath() + " size=" + f.length());
|
||||||
return f;
|
return f;
|
||||||
@@ -127,6 +129,7 @@ public class Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static public void hideKeyboard(Activity act) {
|
static public void hideKeyboard(Activity act) {
|
||||||
|
if (act == null) return;
|
||||||
if (act.getCurrentFocus() == null) {
|
if (act.getCurrentFocus() == null) {
|
||||||
act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
||||||
} else {
|
} else {
|
||||||
@@ -145,19 +148,38 @@ public class Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static public String getDisplayAmount(long amount) {
|
static public String getDisplayAmount(long amount) {
|
||||||
String s = Wallet.getDisplayAmount(amount);
|
return getDisplayAmount(amount, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public String getDisplayAmount(long amount, int maxDecimals) {
|
||||||
|
return getDisplayAmount(Wallet.getDisplayAmount(amount), maxDecimals);
|
||||||
|
}
|
||||||
|
|
||||||
|
// amountString must have '.' as decimal point
|
||||||
|
static public String getDisplayAmount(String amountString, int maxDecimals) {
|
||||||
int lastZero = 0;
|
int lastZero = 0;
|
||||||
int decimal = 0;
|
int decimal = 0;
|
||||||
for (int i = s.length() - 1; i >= 0; i--) {
|
for (int i = amountString.length() - 1; i >= 0; i--) {
|
||||||
if ((lastZero == 0) && (s.charAt(i) != '0')) lastZero = i + 1;
|
if ((lastZero == 0) && (amountString.charAt(i) != '0')) lastZero = i + 1;
|
||||||
// TODO i18n
|
// TODO i18n
|
||||||
if (s.charAt(i) == '.') {
|
if (amountString.charAt(i) == '.') {
|
||||||
decimal = i;
|
decimal = i + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int cutoff = Math.max(lastZero, decimal + 2);
|
int cutoff = Math.min(Math.max(lastZero, decimal + 2), decimal + maxDecimals);
|
||||||
return s.substring(0, cutoff);
|
return amountString.substring(0, cutoff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public String getFormattedAmount(double amount, boolean isXmr) {
|
||||||
|
// at this point selection is XMR in case of error
|
||||||
|
String displayB;
|
||||||
|
if (isXmr) { // not XMR
|
||||||
|
displayB = String.format(Locale.US, "%,.5f", amount);
|
||||||
|
} else { // XMR
|
||||||
|
displayB = String.format(Locale.US, "%,.2f", amount);
|
||||||
|
}
|
||||||
|
return displayB;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public Bitmap getBitmap(Context context, int drawableId) {
|
static public Bitmap getBitmap(Context context, int drawableId) {
|
||||||
@@ -180,11 +202,15 @@ public class Helper {
|
|||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final int HTTP_TIMEOUT = 5000;
|
||||||
|
|
||||||
static public String getUrl(String httpsUrl) {
|
static public String getUrl(String httpsUrl) {
|
||||||
HttpsURLConnection urlConnection = null;
|
HttpsURLConnection urlConnection = null;
|
||||||
try {
|
try {
|
||||||
URL url = new URL(httpsUrl);
|
URL url = new URL(httpsUrl);
|
||||||
urlConnection = (HttpsURLConnection) url.openConnection();
|
urlConnection = (HttpsURLConnection) url.openConnection();
|
||||||
|
urlConnection.setConnectTimeout(HTTP_TIMEOUT);
|
||||||
|
urlConnection.setReadTimeout(HTTP_TIMEOUT);
|
||||||
InputStreamReader in = new InputStreamReader(urlConnection.getInputStream());
|
InputStreamReader in = new InputStreamReader(urlConnection.getInputStream());
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
final int BUFFER_SIZE = 512;
|
final int BUFFER_SIZE = 512;
|
||||||
@@ -195,6 +221,8 @@ public class Helper {
|
|||||||
length = in.read(buffer, 0, BUFFER_SIZE);
|
length = in.read(buffer, 0, BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
} catch (SocketTimeoutException ex) {
|
||||||
|
Log.w(TAG, "C " + ex.getLocalizedMessage());
|
||||||
} catch (MalformedURLException ex) {
|
} catch (MalformedURLException ex) {
|
||||||
Log.e(TAG, "A " + ex.getLocalizedMessage());
|
Log.e(TAG, "A " + ex.getLocalizedMessage());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@@ -206,4 +234,10 @@ public class Helper {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public void clipBoardCopy(Context context, String label, String text) {
|
||||||
|
ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText(label, text);
|
||||||
|
clipboardManager.setPrimaryClip(clip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet.util;
|
package com.m2049r.xmrwallet.util;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user