mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-02 15:53:04 +02:00
Compare commits
11 Commits
v1.0
...
v1.1.2-alp
Author | SHA1 | Date | |
---|---|---|---|
![]() |
03c5569f91 | ||
![]() |
7b1e6a89ba | ||
![]() |
ff8a3ee7c8 | ||
![]() |
dcbaa35b57 | ||
![]() |
3466116e2a | ||
![]() |
59e87e2bfe | ||
![]() |
e8b749af3b | ||
![]() |
f282f01edd | ||
![]() |
f16afdbb19 | ||
![]() |
ccacec9d0b | ||
![]() |
9ebacb8528 |
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 {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.2"
|
||||
buildToolsVersion '26.0.2'
|
||||
defaultConfig {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 25
|
||||
versionCode 23
|
||||
versionName "1.0"
|
||||
versionCode 29
|
||||
versionName "1.1.2-alpha"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
|
@@ -215,7 +215,7 @@ std::vector<std::string> java2cpp(JNIEnv *env, jobject arrayList) {
|
||||
for (jint i = 0; i < len; i++) {
|
||||
jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList,
|
||||
java_util_ArrayList_get, i));
|
||||
const char *pchars = env->GetStringUTFChars(element, JNI_FALSE);
|
||||
const char *pchars = env->GetStringUTFChars(element, NULL);
|
||||
result.emplace_back(pchars);
|
||||
env->ReleaseStringUTFChars(element, pchars);
|
||||
env->DeleteLocalRef(element);
|
||||
@@ -254,9 +254,9 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletJ(JNIEnv *env, jobject
|
||||
jstring path, jstring password,
|
||||
jstring language,
|
||||
jboolean isTestNet) {
|
||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
||||
const char *_password = env->GetStringUTFChars(password, JNI_FALSE);
|
||||
const char *_language = env->GetStringUTFChars(language, JNI_FALSE);
|
||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||
|
||||
Bitmonero::Wallet *wallet =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWallet(
|
||||
@@ -275,8 +275,8 @@ JNIEXPORT jlong JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject instance,
|
||||
jstring path, jstring password,
|
||||
jboolean isTestNet) {
|
||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
||||
const char *_password = env->GetStringUTFChars(password, JNI_FALSE);
|
||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||
|
||||
Bitmonero::Wallet *wallet =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->openWallet(
|
||||
@@ -294,8 +294,8 @@ Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobje
|
||||
jstring path, jstring mnemonic,
|
||||
jboolean isTestNet,
|
||||
jlong restoreHeight) {
|
||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
||||
const char *_mnemonic = env->GetStringUTFChars(mnemonic, JNI_FALSE);
|
||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||
const char *_mnemonic = env->GetStringUTFChars(mnemonic, NULL);
|
||||
|
||||
Bitmonero::Wallet *wallet =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->recoveryWallet(
|
||||
@@ -317,11 +317,11 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env,
|
||||
jstring addressString,
|
||||
jstring viewKeyString,
|
||||
jstring spendKeyString) {
|
||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
||||
const char *_language = env->GetStringUTFChars(language, JNI_FALSE);
|
||||
const char *_addressString = env->GetStringUTFChars(addressString, JNI_FALSE);
|
||||
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, JNI_FALSE);
|
||||
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, JNI_FALSE);
|
||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||
const char *_language = env->GetStringUTFChars(language, NULL);
|
||||
const char *_addressString = env->GetStringUTFChars(addressString, NULL);
|
||||
const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, NULL);
|
||||
const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, NULL);
|
||||
|
||||
Bitmonero::Wallet *wallet =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
|
||||
@@ -344,7 +344,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env,
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_walletExists(JNIEnv *env, jobject instance,
|
||||
jstring path) {
|
||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||
bool exists =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->walletExists(std::string(_path));
|
||||
env->ReleaseStringUTFChars(path, _path);
|
||||
@@ -356,8 +356,8 @@ Java_com_m2049r_xmrwallet_model_WalletManager_verifyWalletPassword(JNIEnv *env,
|
||||
jstring keys_file_name,
|
||||
jstring password,
|
||||
jboolean watch_only) {
|
||||
const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, JNI_FALSE);
|
||||
const char *_password = env->GetStringUTFChars(password, JNI_FALSE);
|
||||
const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, NULL);
|
||||
const char *_password = env->GetStringUTFChars(password, NULL);
|
||||
bool passwordOk =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->verifyWalletPassword(
|
||||
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
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_findWallets(JNIEnv *env, jobject instance,
|
||||
jstring path) {
|
||||
const char *_path = env->GetStringUTFChars(path, JNI_FALSE);
|
||||
const char *_path = env->GetStringUTFChars(path, NULL);
|
||||
std::vector<std::string> walletPaths =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->findWallets(std::string(_path));
|
||||
env->ReleaseStringUTFChars(path, _path);
|
||||
@@ -388,7 +388,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_getErrorString(JNIEnv *env, jobjec
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_setDaemonAddressJ(JNIEnv *env, jobject instance,
|
||||
jstring address) {
|
||||
const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
|
||||
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->setDaemonAddress(std::string(_address));
|
||||
env->ReleaseStringUTFChars(address, _address);
|
||||
}
|
||||
@@ -440,7 +440,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_startMining(JNIEnv *env, jobject i
|
||||
jstring address,
|
||||
jboolean background_mining,
|
||||
jboolean ignore_battery) {
|
||||
const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
|
||||
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||
bool success =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->startMining(std::string(_address),
|
||||
background_mining,
|
||||
@@ -458,7 +458,7 @@ JNIEXPORT jstring JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_resolveOpenAlias(JNIEnv *env, jobject instance,
|
||||
jstring address,
|
||||
jboolean dnssec_valid) {
|
||||
const char *_address = env->GetStringUTFChars(address, JNI_FALSE);
|
||||
const char *_address = env->GetStringUTFChars(address, NULL);
|
||||
bool _dnssec_valid = (bool) dnssec_valid;
|
||||
std::string resolvedAlias =
|
||||
Bitmonero::WalletManagerFactory::getWalletManager()->resolveOpenAlias(
|
||||
@@ -510,7 +510,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getSeedLanguage(JNIEnv *env, jobject inst
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_setSeedLanguage(JNIEnv *env, jobject instance,
|
||||
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);
|
||||
wallet->setSeedLanguage(std::string(_language));
|
||||
env->ReleaseStringUTFChars(language, _language);
|
||||
@@ -531,7 +531,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getErrorString(JNIEnv *env, jobject insta
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_setPassword(JNIEnv *env, jobject instance,
|
||||
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);
|
||||
bool success = wallet->setPassword(std::string(_password));
|
||||
env->ReleaseStringUTFChars(password, _password);
|
||||
@@ -562,7 +562,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_isTestNet(JNIEnv *env, jobject instance)
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_getIntegratedAddress(JNIEnv *env, jobject instance,
|
||||
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);
|
||||
std::string address = wallet->integratedAddress(_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
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_store(JNIEnv *env, jobject instance,
|
||||
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);
|
||||
bool success = wallet->store(std::string(_path));
|
||||
if (!success) {
|
||||
@@ -607,9 +607,9 @@ Java_com_m2049r_xmrwallet_model_Wallet_initJ(JNIEnv *env, jobject instance,
|
||||
jstring daemon_address,
|
||||
jlong upper_transaction_size_limit,
|
||||
jstring daemon_username, jstring daemon_password) {
|
||||
const char *_daemon_address = env->GetStringUTFChars(daemon_address, JNI_FALSE);
|
||||
const char *_daemon_username = env->GetStringUTFChars(daemon_username, JNI_FALSE);
|
||||
const char *_daemon_password = env->GetStringUTFChars(daemon_password, JNI_FALSE);
|
||||
const char *_daemon_address = env->GetStringUTFChars(daemon_address, NULL);
|
||||
const char *_daemon_username = env->GetStringUTFChars(daemon_username, NULL);
|
||||
const char *_daemon_password = env->GetStringUTFChars(daemon_password, NULL);
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||
bool status = wallet->init(_daemon_address, upper_transaction_size_limit, _daemon_username,
|
||||
_daemon_password);
|
||||
@@ -691,7 +691,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getDisplayAmount(JNIEnv *env, jobject cla
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_getAmountFromString(JNIEnv *env, jobject clazz,
|
||||
jstring amount) {
|
||||
const char *_amount = env->GetStringUTFChars(amount, JNI_FALSE);
|
||||
const char *_amount = env->GetStringUTFChars(amount, NULL);
|
||||
uint64_t x = Bitmonero::Wallet::amountFromString(_amount);
|
||||
env->ReleaseStringUTFChars(amount, _amount);
|
||||
return x;
|
||||
@@ -711,7 +711,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_generatePaymentId(JNIEnv *env, jobject cl
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_isPaymentIdValid(JNIEnv *env, jobject clazz,
|
||||
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);
|
||||
env->ReleaseStringUTFChars(payment_id, _payment_id);
|
||||
return isValid;
|
||||
@@ -720,7 +720,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_isPaymentIdValid(JNIEnv *env, jobject cla
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_isAddressValid(JNIEnv *env, jobject clazz,
|
||||
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);
|
||||
env->ReleaseStringUTFChars(address, _address);
|
||||
return isValid;
|
||||
@@ -732,7 +732,7 @@ JNIEXPORT jstring JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_getPaymentIdFromAddress(JNIEnv *env, jobject clazz,
|
||||
jstring address,
|
||||
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);
|
||||
env->ReleaseStringUTFChars(address, _address);
|
||||
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,
|
||||
jint priority) {
|
||||
|
||||
const char *_dst_addr = env->GetStringUTFChars(dst_addr, JNI_FALSE);
|
||||
const char *_payment_id = env->GetStringUTFChars(payment_id, JNI_FALSE);
|
||||
const char *_dst_addr = env->GetStringUTFChars(dst_addr, NULL);
|
||||
const char *_payment_id = env->GetStringUTFChars(payment_id, NULL);
|
||||
Bitmonero::PendingTransaction::Priority _priority =
|
||||
static_cast<Bitmonero::PendingTransaction::Priority>(priority);
|
||||
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,
|
||||
jstring txid, jstring note) {
|
||||
|
||||
const char *_txid = env->GetStringUTFChars(txid, JNI_FALSE);
|
||||
const char *_note = env->GetStringUTFChars(note, JNI_FALSE);
|
||||
const char *_txid = env->GetStringUTFChars(txid, NULL);
|
||||
const char *_note = env->GetStringUTFChars(note, NULL);
|
||||
|
||||
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,
|
||||
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);
|
||||
|
||||
@@ -893,7 +893,7 @@ JNIEXPORT jstring JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_getTxKey(JNIEnv *env, jobject instance,
|
||||
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);
|
||||
|
||||
@@ -1015,7 +1015,7 @@ JNIEXPORT jboolean JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_commit(JNIEnv *env, jobject instance,
|
||||
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);
|
||||
bool success = tx->commit(_filename, overwrite);
|
||||
@@ -1060,4 +1060,3 @@ Java_com_m2049r_xmrwallet_model_PendingTransaction_getTxCount(JNIEnv *env, jobje
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 253 KiB |
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
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.Result;
|
||||
import com.m2049r.xmrwallet.util.BarcodeData;
|
||||
|
||||
import me.dm7.barcodescanner.zxing.ZXingScannerView;
|
||||
|
||||
@@ -64,7 +63,6 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
|
||||
@Override
|
||||
public void handleResult(Result rawResult) {
|
||||
//Log.d(TAG, rawResult.getBarcodeFormat().toString() + "/" + rawResult.getText());
|
||||
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE) &&
|
||||
(rawResult.getText().startsWith(QR_SCHEME))) {
|
||||
if (activityCallback.onAddressScanned(rawResult.getText())) {
|
||||
@@ -101,7 +99,6 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
//Log.d(TAG, "attaching scan");
|
||||
if (context instanceof Listener) {
|
||||
this.activityCallback = (Listener) context;
|
||||
} else {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -16,19 +16,22 @@
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.InputType;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
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.Transfer;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
@@ -64,14 +67,13 @@ public class TxFragment extends Fragment {
|
||||
TextView tvTxFee;
|
||||
TextView tvTxTransfers;
|
||||
TextView etTxNotes;
|
||||
Button bCopy;
|
||||
Button bTxNotes;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
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);
|
||||
tvTxId = (TextView) view.findViewById(R.id.tvTxId);
|
||||
@@ -83,18 +85,10 @@ public class TxFragment extends Fragment {
|
||||
tvTxFee = (TextView) view.findViewById(R.id.tvTxFee);
|
||||
tvTxTransfers = (TextView) view.findViewById(R.id.tvTxTransfers);
|
||||
etTxNotes = (TextView) view.findViewById(R.id.etTxNotes);
|
||||
bCopy = (Button) view.findViewById(R.id.bCopy);
|
||||
bTxNotes = (Button) view.findViewById(R.id.bTxNotes);
|
||||
|
||||
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||
|
||||
bCopy.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
copyToClipboard();
|
||||
}
|
||||
});
|
||||
|
||||
bTxNotes.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -119,28 +113,35 @@ public class TxFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
void copyToClipboard() {
|
||||
void shareTxInfo() {
|
||||
if (this.info == null) return;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(getString(R.string.tx_address)).append(": ");
|
||||
sb.append(activityCallback.getWalletAddress()).append("\n");
|
||||
sb.append(getString(R.string.tx_id)).append(": ");
|
||||
sb.append(info.hash).append("\n");
|
||||
sb.append(getString(R.string.tx_key)).append(": ");
|
||||
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(getString(R.string.tx_timestamp)).append(":\n");
|
||||
sb.append(TS_FORMATTER.format(new Date(info.timestamp * 1000))).append("\n\n");
|
||||
|
||||
sb.append(getString(R.string.tx_amount)).append(":\n");
|
||||
sb.append((info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-"));
|
||||
sb.append(Wallet.getDisplayAmount(info.amount)).append("\n");
|
||||
sb.append(getString(R.string.tx_fee)).append(": ");
|
||||
sb.append(Wallet.getDisplayAmount(info.fee)).append("\n");
|
||||
sb.append(getString(R.string.tx_notes)).append(": ");
|
||||
sb.append(getString(R.string.tx_fee)).append(":\n");
|
||||
sb.append(Wallet.getDisplayAmount(info.fee)).append("\n\n");
|
||||
|
||||
sb.append(getString(R.string.tx_notes)).append(":\n");
|
||||
String oneLineNotes = info.notes.replace("\n", " ; ");
|
||||
sb.append(oneLineNotes.isEmpty() ? "-" : oneLineNotes).append("\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_blockheight)).append(": ");
|
||||
sb.append(oneLineNotes.isEmpty() ? "-" : oneLineNotes).append("\n\n");
|
||||
|
||||
sb.append(getString(R.string.tx_destination)).append(":\n");
|
||||
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) {
|
||||
sb.append(getString(R.string.tx_failed)).append("\n");
|
||||
} else if (info.isPending) {
|
||||
@@ -148,7 +149,9 @@ public class TxFragment extends Fragment {
|
||||
} else {
|
||||
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) {
|
||||
boolean comma = false;
|
||||
for (Transfer transfer : info.transfers) {
|
||||
@@ -163,12 +166,14 @@ public class TxFragment extends Fragment {
|
||||
} else {
|
||||
sb.append("-");
|
||||
}
|
||||
sb.append("\n");
|
||||
ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText(getString(R.string.tx_copy_label), sb.toString());
|
||||
clipboardManager.setPrimaryClip(clip);
|
||||
Toast.makeText(getActivity(), getString(R.string.tx_copy_message), Toast.LENGTH_SHORT).show();
|
||||
//Log.d(TAG, sb.toString());
|
||||
sb.append("\n\n");
|
||||
//Helper.clipBoardCopy(getActivity(), getString(R.string.tx_copy_label), sb.toString());
|
||||
//Toast.makeText(getActivity(), getString(R.string.tx_copy_message), Toast.LENGTH_SHORT).show();
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, sb.toString());
|
||||
sendIntent.setType("text/plain");
|
||||
startActivity(Intent.createChooser(sendIntent, null));
|
||||
}
|
||||
|
||||
TransactionInfo info = null;
|
||||
@@ -176,17 +181,24 @@ public class TxFragment extends Fragment {
|
||||
void loadNotes(TransactionInfo info) {
|
||||
if (info.notes == null) {
|
||||
info.notes = activityCallback.getTxNotes(info.hash);
|
||||
//Log.d(TAG, "NOTES:" + info.notes + ":");
|
||||
}
|
||||
etTxNotes.setText(info.notes);
|
||||
}
|
||||
|
||||
private void setTxColour(int clr) {
|
||||
tvTxAmount.setTextColor(clr);
|
||||
tvTxFee.setTextColor(clr);
|
||||
}
|
||||
|
||||
private void show(TransactionInfo info) {
|
||||
if (info.txKey == null) {
|
||||
info.txKey = activityCallback.getTxKey(info.hash);
|
||||
//Log.d(TAG, "TXKEY:" + info.txKey + ":");
|
||||
}
|
||||
loadNotes(info);
|
||||
|
||||
activityCallback.setSubtitle(getString(R.string.tx_title));
|
||||
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||
|
||||
tvTxTimestamp.setText(TS_FORMATTER.format(new Date(info.timestamp * 1000)));
|
||||
tvTxId.setText(info.hash);
|
||||
tvTxKey.setText(info.txKey.isEmpty() ? "-" : info.txKey);
|
||||
@@ -199,8 +211,30 @@ public class TxFragment extends Fragment {
|
||||
tvTxBlockheight.setText("" + info.blockheight);
|
||||
}
|
||||
String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
|
||||
|
||||
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<>();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuffer dstSb = new StringBuffer();
|
||||
@@ -232,10 +266,21 @@ public class TxFragment extends Fragment {
|
||||
tvTxTransfers.setText(sb.toString());
|
||||
tvDestination.setText(dstSb.toString());
|
||||
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 {
|
||||
String getWalletAddress();
|
||||
@@ -246,6 +291,10 @@ public class TxFragment extends Fragment {
|
||||
|
||||
void onSetNote(String txId, String notes);
|
||||
|
||||
void setToolbarButton(int type);
|
||||
|
||||
void setSubtitle(String subtitle);
|
||||
|
||||
}
|
||||
|
||||
@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.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
@@ -43,6 +44,7 @@ import java.io.InputStreamReader;
|
||||
* http://speakman.net.nz
|
||||
*/
|
||||
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 HELP_ID = "HELP_ID";
|
||||
|
||||
@@ -67,7 +69,6 @@ public class HelpFragment extends DialogFragment {
|
||||
if (prev != null) {
|
||||
ft.remove(prev);
|
||||
}
|
||||
ft.addToBackStack(null);
|
||||
|
||||
// Create and show the dialog.
|
||||
DialogFragment newFragment = HelpFragment.newInstance(helpResourceId);
|
||||
@@ -100,7 +101,7 @@ public class HelpFragment extends DialogFragment {
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
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);
|
||||
progress = (ProgressBar) content.findViewById(R.id.helpFragmentProgress);
|
||||
|
||||
@@ -136,8 +137,8 @@ public class HelpFragment extends DialogFragment {
|
||||
sb.append("\n");
|
||||
}
|
||||
bufferedReader.close();
|
||||
} catch (IOException e) {
|
||||
// TODO You may want to include some logging here.
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
@@ -16,22 +16,17 @@
|
||||
|
||||
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.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.AsyncTask;
|
||||
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.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
@@ -41,11 +36,17 @@ import android.widget.TextView;
|
||||
import com.m2049r.xmrwallet.BuildConfig;
|
||||
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.
|
||||
* http://speakman.net.nz
|
||||
*/
|
||||
public class LicensesFragment extends DialogFragment {
|
||||
static final String TAG = "LicensesFragment";
|
||||
int versionCode = BuildConfig.VERSION_CODE;
|
||||
String versionName = BuildConfig.VERSION_NAME;
|
||||
|
||||
@@ -102,7 +103,7 @@ public class LicensesFragment extends DialogFragment {
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
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);
|
||||
mIndeterminateProgress = (ProgressBar) content.findViewById(R.id.licensesFragmentIndeterminateProgress);
|
||||
|
||||
@@ -140,8 +141,8 @@ public class LicensesFragment extends DialogFragment {
|
||||
sb.append("\n");
|
||||
}
|
||||
bufferedReader.close();
|
||||
} catch (IOException e) {
|
||||
// TODO You may want to include some logging here.
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
@@ -28,13 +27,12 @@ import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.R;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
@@ -69,7 +67,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||
outboundColour = ContextCompat.getColor(context, R.color.tx_red);
|
||||
pendingColour = ContextCompat.getColor(context, R.color.tx_pending);
|
||||
failedColour = ContextCompat.getColor(context, R.color.tx_failed);
|
||||
this.infoItems = new ArrayList<>();
|
||||
infoItems = new ArrayList<>();
|
||||
this.listener = listener;
|
||||
Calendar cal = Calendar.getInstance();
|
||||
TimeZone tz = cal.getTimeZone(); //get the local time zone.
|
||||
@@ -79,7 +77,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.transaction_item, parent, false);
|
||||
.inflate(R.layout.item_transaction, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@@ -99,22 +97,8 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||
this.infoItems.clear();
|
||||
if (data != null) {
|
||||
Log.d(TAG, "setInfos " + data.size());
|
||||
// sort by block height
|
||||
Collections.sort(data, new Comparator<TransactionInfo>() {
|
||||
@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);
|
||||
infoItems.addAll(data);
|
||||
Collections.sort(infoItems);
|
||||
} else {
|
||||
Log.d(TAG, "setInfos null");
|
||||
}
|
||||
@@ -147,36 +131,41 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||
|
||||
void bind(int 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
|
||||
String amount = displayAmount.substring(0, displayAmount.length() - (12 - 5));
|
||||
this.tvAmount.setText(amount);
|
||||
|
||||
long realAmount = infoItem.amount;
|
||||
if (infoItem.isPending) {
|
||||
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)) {
|
||||
String feeAmount = Wallet.getDisplayAmount(infoItem.fee);
|
||||
String fee = feeAmount.substring(0, feeAmount.length() - (12 - 5));
|
||||
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));
|
||||
}
|
||||
String fee = Helper.getDisplayAmount(infoItem.fee, 5);
|
||||
this.tvFee.setText(context.getString(R.string.tx_list_fee, fee));
|
||||
} else {
|
||||
this.tvFee.setText("");
|
||||
}
|
||||
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);
|
||||
} else if (infoItem.isPending) {
|
||||
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) {
|
||||
setTxColour(inboundColour);
|
||||
} else {
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void loadNotes(Wallet wallet) {
|
||||
for (TransactionInfo info : transactions) {
|
||||
info.notes = wallet.getUserNote(info.hash);
|
||||
}
|
||||
}
|
||||
|
||||
public native int getCount();
|
||||
|
||||
//private native long getTransactionByIndexJ(int i);
|
||||
@@ -42,6 +48,11 @@ public class TransactionHistory {
|
||||
|
||||
private List<TransactionInfo> transactions = new ArrayList<>();
|
||||
|
||||
public void refreshWithNotes(Wallet wallet) {
|
||||
refresh();
|
||||
loadNotes(wallet);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
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 a POJO for the TransactionInfoAdapter
|
||||
public class TransactionInfo implements Parcelable {
|
||||
public class TransactionInfo implements Parcelable, Comparable<TransactionInfo> {
|
||||
static final String TAG = "TransactionInfo";
|
||||
|
||||
public enum Direction {
|
||||
@@ -92,7 +92,6 @@ public class TransactionInfo implements Parcelable {
|
||||
this.confirmations = confirmations;
|
||||
this.transfers = transfers;
|
||||
}
|
||||
Random rnd = new Random();
|
||||
|
||||
public String toString() {
|
||||
return direction + "@" + blockheight + " " + amount;
|
||||
@@ -146,4 +145,17 @@ public class TransactionInfo implements Parcelable {
|
||||
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;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@@ -45,36 +46,36 @@ public class WalletManager {
|
||||
return WalletManager.Instance;
|
||||
}
|
||||
|
||||
private WalletManager() {
|
||||
this.managedWallets = new HashMap<>();
|
||||
//private Map<String, Wallet> managedWallets;
|
||||
private Wallet managedWallet = null;
|
||||
|
||||
public Wallet getWallet() {
|
||||
return managedWallet;
|
||||
}
|
||||
|
||||
private Map<String, Wallet> managedWallets;
|
||||
|
||||
public Wallet getWallet(String walletId) {
|
||||
return managedWallets.get(walletId);
|
||||
private void manageWallet(Wallet wallet) {
|
||||
Log.d(TAG, "Managing " + wallet.getName());
|
||||
managedWallet = wallet;
|
||||
}
|
||||
|
||||
private void manageWallet(String walletId, Wallet wallet) {
|
||||
if (getWallet(walletId) != null) {
|
||||
throw new IllegalStateException(walletId + " already under management!");
|
||||
private void unmanageWallet(Wallet wallet) {
|
||||
if (wallet == null) {
|
||||
throw new IllegalArgumentException("Cannot unmanage null!");
|
||||
}
|
||||
Log.d(TAG, "Managing " + walletId);
|
||||
managedWallets.put(walletId, wallet);
|
||||
}
|
||||
|
||||
private void unmanageWallet(String walletId) {
|
||||
if (getWallet(walletId) == null) {
|
||||
throw new IllegalStateException(walletId + " not under management!");
|
||||
if (getWallet() == null) {
|
||||
throw new IllegalStateException("No wallet under management!");
|
||||
}
|
||||
Log.d(TAG, "Unmanaging " + walletId);
|
||||
managedWallets.remove(walletId);
|
||||
if (getWallet() != wallet) {
|
||||
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) {
|
||||
long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, isTestNet());
|
||||
Wallet wallet = new Wallet(walletHandle);
|
||||
manageWallet(wallet.getName(), wallet);
|
||||
manageWallet(wallet);
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@@ -83,7 +84,7 @@ public class WalletManager {
|
||||
public Wallet openWallet(String path, String password) {
|
||||
long walletHandle = openWalletJ(path, password, isTestNet());
|
||||
Wallet wallet = new Wallet(walletHandle);
|
||||
manageWallet(wallet.getName(), wallet);
|
||||
manageWallet(wallet);
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@@ -91,14 +92,14 @@ public class WalletManager {
|
||||
|
||||
public Wallet recoveryWallet(File aFile, String mnemonic) {
|
||||
Wallet wallet = recoveryWallet(aFile, mnemonic, 0);
|
||||
manageWallet(wallet.getName(), wallet);
|
||||
manageWallet(wallet);
|
||||
return wallet;
|
||||
}
|
||||
|
||||
public Wallet recoveryWallet(File aFile, String mnemonic, long restoreHeight) {
|
||||
long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), mnemonic, isTestNet(), restoreHeight);
|
||||
Wallet wallet = new Wallet(walletHandle);
|
||||
manageWallet(wallet.getName(), wallet);
|
||||
manageWallet(wallet);
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@@ -109,7 +110,7 @@ public class WalletManager {
|
||||
long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), language, isTestNet(), restoreHeight,
|
||||
addressString, viewKeyString, spendKeyString);
|
||||
Wallet wallet = new Wallet(walletHandle);
|
||||
manageWallet(wallet.getName(), wallet);
|
||||
manageWallet(wallet);
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@@ -123,13 +124,12 @@ public class WalletManager {
|
||||
public native boolean closeJ(Wallet wallet);
|
||||
|
||||
public boolean close(Wallet wallet) {
|
||||
String walletId = new File(wallet.getFilename()).getName();
|
||||
unmanageWallet(walletId);
|
||||
unmanageWallet(wallet);
|
||||
boolean closed = closeJ(wallet);
|
||||
if (!closed) {
|
||||
// in case we could not close it
|
||||
// we unmanage it
|
||||
manageWallet(walletId, wallet);
|
||||
// we manage it again
|
||||
manageWallet(wallet);
|
||||
}
|
||||
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 class WalletInfo {
|
||||
public class WalletInfo implements Comparable<WalletInfo> {
|
||||
public File path;
|
||||
public String name;
|
||||
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) {
|
||||
|
@@ -70,20 +70,11 @@ public class WalletService extends Service {
|
||||
private MyWalletListener listener = null;
|
||||
|
||||
private class MyWalletListener implements WalletListener {
|
||||
private Wallet wallet;
|
||||
boolean updated = true;
|
||||
|
||||
Wallet getWallet() {
|
||||
return wallet;
|
||||
}
|
||||
|
||||
MyWalletListener(Wallet aWallet) {
|
||||
if (aWallet == null) throw new IllegalArgumentException("Cannot open wallet!");
|
||||
this.wallet = aWallet;
|
||||
}
|
||||
|
||||
void start() {
|
||||
Log.d(TAG, "MyWalletListener.start()");
|
||||
Wallet wallet = getWallet();
|
||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||
//acquireWakeLock();
|
||||
wallet.setListener(this);
|
||||
@@ -92,6 +83,7 @@ public class WalletService extends Service {
|
||||
|
||||
void stop() {
|
||||
Log.d(TAG, "MyWalletListener.stop()");
|
||||
Wallet wallet = getWallet();
|
||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||
wallet.pauseRefresh();
|
||||
wallet.setListener(null);
|
||||
@@ -115,6 +107,7 @@ public class WalletService extends Service {
|
||||
int lastTxCount = 0;
|
||||
|
||||
public void newBlock(long height) {
|
||||
Wallet wallet = getWallet();
|
||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||
// don't flood with an update for every block ...
|
||||
if (lastBlockTime < System.currentTimeMillis() - 2000) {
|
||||
@@ -141,18 +134,20 @@ public class WalletService extends Service {
|
||||
}
|
||||
|
||||
public void updated() {
|
||||
Log.d(TAG, "updated() " + wallet.getBalance());
|
||||
Log.d(TAG, "updated()");
|
||||
Wallet wallet = getWallet();
|
||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||
updated = true;
|
||||
}
|
||||
|
||||
public void refreshed() {
|
||||
Log.d(TAG, "refreshed()");
|
||||
Wallet wallet = getWallet();
|
||||
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 (observer != null) {
|
||||
updateDaemonState(wallet, 0);
|
||||
wallet.getHistory().refresh();
|
||||
wallet.getHistory().refreshWithNotes(wallet);
|
||||
if (observer != null) {
|
||||
updated = !observer.onRefreshed(wallet, true);
|
||||
}
|
||||
@@ -253,8 +248,7 @@ public class WalletService extends Service {
|
||||
|
||||
//
|
||||
public Wallet getWallet() {
|
||||
if (listener == null) throw new IllegalStateException("no listener");
|
||||
return listener.getWallet();
|
||||
return WalletManager.getInstance().getWallet();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
@@ -303,7 +297,7 @@ public class WalletService extends Service {
|
||||
boolean rc = myWallet.store();
|
||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + 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);
|
||||
} else if (cmd.equals(REQUEST_CMD_TX)) {
|
||||
@@ -315,7 +309,7 @@ public class WalletService extends Service {
|
||||
PendingTransaction.Status status = pendingTransaction.getStatus();
|
||||
Log.d(TAG, "transaction status " + status);
|
||||
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) {
|
||||
observer.onCreatedTransaction(pendingTransaction);
|
||||
@@ -329,7 +323,7 @@ public class WalletService extends Service {
|
||||
PendingTransaction.Status status = pendingTransaction.getStatus();
|
||||
Log.d(TAG, "transaction status " + status);
|
||||
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) {
|
||||
observer.onCreatedTransaction(pendingTransaction);
|
||||
@@ -358,7 +352,7 @@ public class WalletService extends Service {
|
||||
boolean rc = myWallet.store();
|
||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + 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);
|
||||
listener.updated = true;
|
||||
@@ -378,7 +372,7 @@ public class WalletService extends Service {
|
||||
boolean rc = myWallet.store();
|
||||
Log.d(TAG, "wallet stored: " + myWallet.getName() + " with rc=" + 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);
|
||||
}
|
||||
@@ -441,10 +435,15 @@ public class WalletService extends Service {
|
||||
// start ID so we know which request we're stopping when we finish the job
|
||||
Message msg = mServiceHandler.obtainMessage();
|
||||
msg.arg2 = START_SERVICE;
|
||||
msg.setData(intent.getExtras());
|
||||
mServiceHandler.sendMessage(msg);
|
||||
//Log.d(TAG, "onStartCommand() message sent");
|
||||
return START_STICKY;
|
||||
if (intent != null) {
|
||||
msg.setData(intent.getExtras());
|
||||
mServiceHandler.sendMessage(msg);
|
||||
return START_STICKY;
|
||||
} else {
|
||||
// process restart - don't do anything - let system kill it again
|
||||
stop();
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -466,9 +465,8 @@ public class WalletService extends Service {
|
||||
}
|
||||
|
||||
private boolean start(String walletName, String walletPassword) {
|
||||
startNotfication();
|
||||
// if there is an listener it is always started / syncing
|
||||
Log.d(TAG, "start()");
|
||||
startNotfication();
|
||||
showProgress(getString(R.string.status_wallet_loading));
|
||||
showProgress(10);
|
||||
if (listener == null) {
|
||||
@@ -478,7 +476,7 @@ public class WalletService extends Service {
|
||||
if (aWallet != null) aWallet.close();
|
||||
return false;
|
||||
}
|
||||
listener = new MyWalletListener(aWallet);
|
||||
listener = new MyWalletListener();
|
||||
listener.start();
|
||||
showProgress(100);
|
||||
}
|
||||
@@ -496,10 +494,6 @@ public class WalletService extends Service {
|
||||
if (listener != null) {
|
||||
listener.stop();
|
||||
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");
|
||||
myWallet.close();
|
||||
Log.d(TAG, "stop() closed");
|
||||
@@ -511,17 +505,12 @@ public class WalletService extends Service {
|
||||
}
|
||||
|
||||
private Wallet loadWallet(String walletName, String walletPassword) {
|
||||
//String path = Helper.getWalletPath(getApplicationContext(), walletName);
|
||||
//Log.d(TAG, "open wallet " + path);
|
||||
Wallet wallet = openWallet(walletName, walletPassword);
|
||||
//Log.d(TAG, "wallet opened: " + wallet);
|
||||
if (wallet != null) {
|
||||
//Log.d(TAG, wallet.getStatus().toString());
|
||||
Log.d(TAG, "Using daemon " + WalletManager.getInstance().getDaemonAddress());
|
||||
showProgress(55);
|
||||
wallet.init(0);
|
||||
showProgress(90);
|
||||
//Log.d(TAG, wallet.getConnectionStatus().toString());
|
||||
}
|
||||
return wallet;
|
||||
}
|
||||
@@ -561,6 +550,5 @@ public class WalletService extends Service {
|
||||
.setContentIntent(pendingIntent)
|
||||
.build();
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,8 @@ package com.m2049r.xmrwallet.util;
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -40,7 +42,9 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
@@ -48,6 +52,9 @@ public class Helper {
|
||||
static private final String TAG = "Helper";
|
||||
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) {
|
||||
if (!isExternalStorageWritable()) {
|
||||
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 (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== 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};
|
||||
context.requestPermissions(permissions, PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
|
||||
return false;
|
||||
@@ -91,7 +98,7 @@ public class Helper {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
if (context.checkSelfPermission(Manifest.permission.CAMERA)
|
||||
== 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};
|
||||
context.requestPermissions(permissions, PERMISSIONS_REQUEST_CAMERA);
|
||||
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) {
|
||||
File walletDir = getStorageRoot(context);
|
||||
//d(TAG, "walletdir=" + walletDir.getAbsolutePath());
|
||||
File f = new File(walletDir, aWalletName);
|
||||
Log.d(TAG, "wallet = " + f.getAbsolutePath() + " size=" + f.length());
|
||||
return f;
|
||||
@@ -127,6 +129,7 @@ public class Helper {
|
||||
}
|
||||
|
||||
static public void hideKeyboard(Activity act) {
|
||||
if (act == null) return;
|
||||
if (act.getCurrentFocus() == null) {
|
||||
act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
|
||||
} else {
|
||||
@@ -145,19 +148,38 @@ public class Helper {
|
||||
}
|
||||
|
||||
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 decimal = 0;
|
||||
for (int i = s.length() - 1; i >= 0; i--) {
|
||||
if ((lastZero == 0) && (s.charAt(i) != '0')) lastZero = i + 1;
|
||||
for (int i = amountString.length() - 1; i >= 0; i--) {
|
||||
if ((lastZero == 0) && (amountString.charAt(i) != '0')) lastZero = i + 1;
|
||||
// TODO i18n
|
||||
if (s.charAt(i) == '.') {
|
||||
decimal = i;
|
||||
if (amountString.charAt(i) == '.') {
|
||||
decimal = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int cutoff = Math.max(lastZero, decimal + 2);
|
||||
return s.substring(0, cutoff);
|
||||
int cutoff = Math.min(Math.max(lastZero, decimal + 2), decimal + maxDecimals);
|
||||
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) {
|
||||
@@ -180,11 +202,15 @@ public class Helper {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
static final int HTTP_TIMEOUT = 5000;
|
||||
|
||||
static public String getUrl(String httpsUrl) {
|
||||
HttpsURLConnection urlConnection = null;
|
||||
try {
|
||||
URL url = new URL(httpsUrl);
|
||||
urlConnection = (HttpsURLConnection) url.openConnection();
|
||||
urlConnection.setConnectTimeout(HTTP_TIMEOUT);
|
||||
urlConnection.setReadTimeout(HTTP_TIMEOUT);
|
||||
InputStreamReader in = new InputStreamReader(urlConnection.getInputStream());
|
||||
StringBuffer sb = new StringBuffer();
|
||||
final int BUFFER_SIZE = 512;
|
||||
@@ -195,6 +221,8 @@ public class Helper {
|
||||
length = in.read(buffer, 0, BUFFER_SIZE);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (SocketTimeoutException ex) {
|
||||
Log.w(TAG, "C " + ex.getLocalizedMessage());
|
||||
} catch (MalformedURLException ex) {
|
||||
Log.e(TAG, "A " + ex.getLocalizedMessage());
|
||||
} catch (IOException ex) {
|
||||
@@ -206,4 +234,10 @@ public class Helper {
|
||||
}
|
||||
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;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
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