mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-12 23:40:51 +02:00
Compare commits
87 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4918f44048 | ||
![]() |
924c3fa260 | ||
![]() |
eb2b3b5675 | ||
![]() |
7a9bb22da7 | ||
![]() |
c7e745cbc3 | ||
![]() |
654caaed22 | ||
![]() |
b8c287b763 | ||
![]() |
5c1fa097a9 | ||
![]() |
80531740dd | ||
![]() |
08a62cabab | ||
![]() |
cf4d8bdbf0 | ||
![]() |
7b690a5086 | ||
![]() |
e8e5be35b3 | ||
![]() |
5dbf84d5d6 | ||
![]() |
bf64f77b10 | ||
![]() |
9b82023a9f | ||
![]() |
be54900e1f | ||
![]() |
033032639a | ||
![]() |
ab8567692f | ||
![]() |
65894664a1 | ||
![]() |
e8f53a5a2f | ||
![]() |
22e0a225b0 | ||
![]() |
e769f1a472 | ||
![]() |
b447df9ef9 | ||
![]() |
42f4e4a0e9 | ||
![]() |
466fd3bf26 | ||
![]() |
c9bbe1db3f | ||
![]() |
dec67e0675 | ||
![]() |
9cbeaa7942 | ||
![]() |
093e4bda1d | ||
![]() |
4aa7000cb3 | ||
![]() |
62844192df | ||
![]() |
855b35a6b7 | ||
![]() |
88110b702f | ||
![]() |
0013caa05f | ||
![]() |
5b3e92e91a | ||
![]() |
f8ea3cc77f | ||
![]() |
59ef2a1f8e | ||
![]() |
fae07ed716 | ||
![]() |
e662d5a9c0 | ||
![]() |
4b2d52fbe6 | ||
![]() |
ec7798cb34 | ||
![]() |
20e7d6d065 | ||
![]() |
89ada5b294 | ||
![]() |
fe80fef36e | ||
![]() |
e8331dda7a | ||
![]() |
68abaec6cb | ||
![]() |
fe84bae9ed | ||
![]() |
1289a0ada4 | ||
![]() |
93025c5e1b | ||
![]() |
e0439a1359 | ||
![]() |
93ec3865da | ||
![]() |
49e338e80d | ||
![]() |
075ddff226 | ||
![]() |
7eaf17d48e | ||
![]() |
6822aa83d8 | ||
![]() |
20dbaac4fa | ||
![]() |
726887af2e | ||
![]() |
03da2880ac | ||
![]() |
78c053f4e8 | ||
![]() |
5b38cc438c | ||
![]() |
1eac363102 | ||
![]() |
e51425bc2e | ||
![]() |
f5535dbefa | ||
![]() |
2d42a0287d | ||
![]() |
2ebb9d0650 | ||
![]() |
30792c53c0 | ||
![]() |
3846a0c391 | ||
![]() |
c66ebd654a | ||
![]() |
186ed5cd39 | ||
![]() |
e39cd1c988 | ||
![]() |
39d9c4d0c3 | ||
![]() |
e4562f07a4 | ||
![]() |
b3ea4540a1 | ||
![]() |
ea7c7d2fdb | ||
![]() |
8ff8be6f60 | ||
![]() |
b5ded700fe | ||
![]() |
a5527d4efd | ||
![]() |
a007810824 | ||
![]() |
a634cf18b1 | ||
![]() |
0b2fa08df8 | ||
![]() |
191aa6ac22 | ||
![]() |
a82a90575d | ||
![]() |
2e04046f50 | ||
![]() |
c11d577c5f | ||
![]() |
74b2dd209c | ||
![]() |
cb1d541474 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,2 +1,9 @@
|
|||||||
.gradle
|
.gradle
|
||||||
build
|
/build
|
||||||
|
*.iml
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/local.properties
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.DS_Store
|
||||||
|
2
.idea/.gitignore
generated
vendored
2
.idea/.gitignore
generated
vendored
@@ -1,2 +1,2 @@
|
|||||||
workspace.xml
|
workspace.xml
|
||||||
markdown-navigator*
|
markdown-*
|
||||||
|
10
.idea/libraries/core_1_9_8.xml
generated
Normal file
10
.idea/libraries/core_1_9_8.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<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>
|
@@ -1,11 +1,11 @@
|
|||||||
<component name="libraryTable">
|
<component name="libraryTable">
|
||||||
<library name="junit-4.12">
|
<library name="core-3.3.0">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar!/" />
|
<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>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/a6c32b40bf3d76eca54e3c601e5d1470c86fcdfa/junit-4.12-sources.jar!/" />
|
<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>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
</component>
|
</component>
|
12
.idea/libraries/espresso_core_2_2_2.xml
generated
12
.idea/libraries/espresso_core_2_2_2.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="espresso-core-2.2.2">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="file://$USER_HOME$/.android/build-cache/d505abdc89cc7d1b938ec3f95e87d4323360fa14/output/res" />
|
|
||||||
<root url="jar://$USER_HOME$/.android/build-cache/d505abdc89cc7d1b938ec3f95e87d4323360fa14/output/jars/classes.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/extras/android/m2repository/com/android/support/test/espresso/espresso-core/2.2.2/espresso-core-2.2.2-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
12
.idea/libraries/espresso_idling_resource_2_2_2.xml
generated
12
.idea/libraries/espresso_idling_resource_2_2_2.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="espresso-idling-resource-2.2.2">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.android/build-cache/0dcbbeb3c862ffabe5d9f3c1f70b25bfdf6c739e/output/jars/classes.jar!/" />
|
|
||||||
<root url="file://$USER_HOME$/.android/build-cache/0dcbbeb3c862ffabe5d9f3c1f70b25bfdf6c739e/output/res" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/extras/android/m2repository/com/android/support/test/espresso/espresso-idling-resource/2.2.2/espresso-idling-resource-2.2.2-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
@@ -1,12 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="exposed-instrumentation-api-publish-0.5">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.android/build-cache/c11e9f250159df473b4fbff8b80f455f0be2e5b5/output/jars/classes.jar!/" />
|
|
||||||
<root url="file://$USER_HOME$/.android/build-cache/c11e9f250159df473b4fbff8b80f455f0be2e5b5/output/res" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/extras/android/m2repository/com/android/support/test/exposed-instrumentation-api-publish/0.5/exposed-instrumentation-api-publish-0.5-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
11
.idea/libraries/hamcrest_core_1_3.xml
generated
11
.idea/libraries/hamcrest_core_1_3.xml
generated
@@ -1,11 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="hamcrest-core-1.3">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b/hamcrest-core-1.3-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
9
.idea/libraries/hamcrest_integration_1_3.xml
generated
9
.idea/libraries/hamcrest_integration_1_3.xml
generated
@@ -1,9 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="hamcrest-integration-1.3">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-integration/1.3/5de0c73fef18917cd85d0ab70bb23818685e4dfd/hamcrest-integration-1.3.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
9
.idea/libraries/hamcrest_library_1_3.xml
generated
9
.idea/libraries/hamcrest_library_1_3.xml
generated
@@ -1,9 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="hamcrest-library-1.3">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-library/1.3/4785a3c21320980282f9f33d0d1264a69040538f/hamcrest-library-1.3.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
9
.idea/libraries/javawriter_2_1_1.xml
generated
9
.idea/libraries/javawriter_2_1_1.xml
generated
@@ -1,9 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="javawriter-2.1.1">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup/javawriter/2.1.1/67ff45d9ae02e583d0f9b3432a5ebbe05c30c966/javawriter-2.1.1.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
9
.idea/libraries/javax_annotation_api_1_2.xml
generated
9
.idea/libraries/javax_annotation_api_1_2.xml
generated
@@ -1,9 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="javax.annotation-api-1.2">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.annotation/javax.annotation-api/1.2/479c1e06db31c432330183f5cae684163f186146/javax.annotation-api-1.2.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
9
.idea/libraries/javax_inject_1.xml
generated
9
.idea/libraries/javax_inject_1.xml
generated
@@ -1,9 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="javax.inject-1">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
9
.idea/libraries/jsr305_2_0_1.xml
generated
9
.idea/libraries/jsr305_2_0_1.xml
generated
@@ -1,9 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="jsr305-2.0.1">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/2.0.1/516c03b21d50a644d538de0f0369c620989cd8f0/jsr305-2.0.1.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
12
.idea/libraries/rules_0_5.xml
generated
12
.idea/libraries/rules_0_5.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="rules-0.5">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.android/build-cache/8f8d46a3318b85241b55e25415619e9017c0aef1/output/jars/classes.jar!/" />
|
|
||||||
<root url="file://$USER_HOME$/.android/build-cache/8f8d46a3318b85241b55e25415619e9017c0aef1/output/res" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/extras/android/m2repository/com/android/support/test/rules/0.5/rules-0.5-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
12
.idea/libraries/runner_0_5.xml
generated
12
.idea/libraries/runner_0_5.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="runner-0.5">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$USER_HOME$/.android/build-cache/a3a29c4e90c979d7576a0a7d8450261e0065a0a8/output/jars/classes.jar!/" />
|
|
||||||
<root url="file://$USER_HOME$/.android/build-cache/a3a29c4e90c979d7576a0a7d8450261e0065a0a8/output/res" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/extras/android/m2repository/com/android/support/test/runner/0.5/runner-0.5-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
10
.idea/libraries/zxing_1_9_8.xml
generated
Normal file
10
.idea/libraries/zxing_1_9_8.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<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>
|
30
README.md
30
README.md
@@ -2,19 +2,18 @@
|
|||||||
Another Android Monero Wallet
|
Another Android Monero Wallet
|
||||||
|
|
||||||
### QUICKSTART
|
### QUICKSTART
|
||||||
- Download APK (Release) and install it
|
- Download the APK for the most current release [here](https://github.com/m2049r/xmrwallet/releases) and install it
|
||||||
- Run the App and select "Generate Wallet" to create a new wallet or recover a wallet
|
- Run the App and select "Generate Wallet" to create a new wallet or recover a wallet
|
||||||
- Advanced users could copy over synced wallet files (all files) onto sdcard in directory Monerujo (created first time App is started)
|
- Advanced users can copy over synced wallet files (all files) onto sdcard in directory Monerujo (created first time App is started)
|
||||||
- see the [FAQ](doc/FAQ.md)
|
- See the [FAQ](doc/FAQ.md)
|
||||||
|
|
||||||
### Disclaimer
|
### Disclaimer
|
||||||
You may loose all your Moneroj if you use this App.
|
You may lose all your Moneroj if you use this App. Be cautious when spending on the mainnet.
|
||||||
|
|
||||||
### Random Notes
|
### Random Notes
|
||||||
- Based off monero v0.10.3.1 with pull requests #2238, #2239 and #2289 applied => so can be used in mainnet!
|
- Based off monero v0.11.0.0 with PR #2289 applied
|
||||||
- currently only android32
|
- currently only android32 (runs on 64-bit as well)
|
||||||
- ~~currently only use is checking incoming/outgoing transactions~~
|
- works on the testnet & mainnet
|
||||||
- works in testnet & mainnet
|
|
||||||
- takes forever to sync due to 32-bit architecture
|
- takes forever to sync due to 32-bit architecture
|
||||||
- use your own daemon - it's easy
|
- use your own daemon - it's easy
|
||||||
- screen stays on until first sync is complete
|
- screen stays on until first sync is complete
|
||||||
@@ -22,16 +21,14 @@ You may loose all your Moneroj if you use this App.
|
|||||||
- Monerujo means "Monero Wallet" according to https://www.reddit.com/r/Monero/comments/3exy7t/esperanto_corner/
|
- Monerujo means "Monero Wallet" according to https://www.reddit.com/r/Monero/comments/3exy7t/esperanto_corner/
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- wallet backup functions
|
|
||||||
- adjust layout so we can use bigger font sizes (maybe show only 5 decimal places instead of 12 in main view)
|
|
||||||
- review visibility of methods/classes
|
- review visibility of methods/classes
|
||||||
- more sensible error dialogs ~~(e.g. when no write permissions granted) instead of just crashing on purpose~~
|
- more sensible error dialogs
|
||||||
- check licenses of included libraries; License Dialog
|
- check licenses of included libraries; License Dialog
|
||||||
- ~~make it pretty~~ (decided to go with "form follows function")
|
|
||||||
- ~~spend monero - not so difficult with wallet api~~
|
|
||||||
|
|
||||||
### Issues
|
### Issues / Pitfalls
|
||||||
- Pending incoming transactions disappear after reload
|
- Created wallets on a private testnet are unusable because the restore height is set to that
|
||||||
|
of the "real" testnet. After creating a new wallet, make a **new** one by recovering from the seed.
|
||||||
|
The official monero client shows the same behaviour.
|
||||||
|
|
||||||
### HOW TO BUILD
|
### HOW TO BUILD
|
||||||
No need to build. Binaries are included:
|
No need to build. Binaries are included:
|
||||||
@@ -45,4 +42,5 @@ If you want to build them yourself (recommended) check out [the instructions](do
|
|||||||
Then, fire up Android Studio and build the APK.
|
Then, fire up Android Studio and build the APK.
|
||||||
|
|
||||||
### Donations
|
### Donations
|
||||||
4AdkPJoxn7JCvAby9szgnt93MSEwdnxdhaASxbTBm6x5dCwmsDep2UYN4FhStDn5i11nsJbpU7oj59ahg8gXb1Mg3viqCuk
|
- Address: 4AdkPJoxn7JCvAby9szgnt93MSEwdnxdhaASxbTBm6x5dCwmsDep2UYN4FhStDn5i11nsJbpU7oj59ahg8gXb1Mg3viqCuk
|
||||||
|
- Viewkey: b1aff2a12191723da0afbe75516f94dd8b068215f6e847d8da57aca5f1f98e0c
|
||||||
|
@@ -147,7 +147,7 @@ target_link_libraries( monerujo
|
|||||||
|
|
||||||
blockchain_db
|
blockchain_db
|
||||||
lmdb
|
lmdb
|
||||||
#easylogging # not for 0.10.3.1
|
easylogging
|
||||||
unbound
|
unbound
|
||||||
p2p
|
p2p
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'witness'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 25
|
compileSdkVersion 25
|
||||||
@@ -7,8 +8,8 @@ android {
|
|||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 6
|
versionCode 12
|
||||||
versionName "0.4.2"
|
versionName "0.7"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
@@ -35,16 +36,36 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
|
||||||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
|
||||||
exclude group: 'com.android.support', module: 'support-annotations'
|
|
||||||
})
|
|
||||||
|
|
||||||
compile 'com.android.support:appcompat-v7:25.3.1'
|
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||||
compile 'com.android.support:design:25.3.1'
|
compile 'com.android.support:design:25.3.1'
|
||||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
compile 'com.android.support:support-v4:25.3.1'
|
compile 'com.android.support:support-v4:25.3.1'
|
||||||
compile 'com.android.support:recyclerview-v7:25.3.1'
|
compile 'com.android.support:recyclerview-v7:25.3.1'
|
||||||
compile 'com.android.support:cardview-v7:25.3.1'
|
compile 'com.android.support:cardview-v7:25.3.1'
|
||||||
testCompile 'junit:junit:4.12'
|
compile 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencyVerification {
|
||||||
|
verify = [
|
||||||
|
'com.android.support:design:a3e83064fe99d0a4369f9b46d8bfbe77d0c3022fffdee4be3ac3857b87cc89e3',
|
||||||
|
'com.android.support:appcompat-v7:ac1ebbc46589195dda3e0b1becfe410bafd75bdf3edd1cd9acf04850f3895830',
|
||||||
|
'com.android.support.constraint:constraint-layout:b0c688cc2b7172608f8153a689d746da40f71e52d7e2fe2bfd9df2f92db77085',
|
||||||
|
'com.android.support:transition:36c688825a8c0e6e879e18886de83dc90673322822d5b606ee302f70fb558e16',
|
||||||
|
'me.dm7.barcodescanner:zxing:d43973c9527c23fa8e6d338c6a2c458e373ce1ac6bcaa3bc41d11ae49116000d',
|
||||||
|
'me.dm7.barcodescanner:core:a5c8a704089b58029db166172ed8e55d756877d010a85a0b1c94fdc96ffb8f9a',
|
||||||
|
'com.android.support:support-v4:07d389154bcf73b47e514964df1578136b26cba78257b8a577a3ccb54beff0ae',
|
||||||
|
'com.android.support:recyclerview-v7:375974a8724e359d97d77fa8522c614f813a3ac4583c1807f154a3f9a054b0a1',
|
||||||
|
'com.android.support:cardview-v7:defc17032ffa600a82e1c7d96bb574aa5ed64e2b57e28414a245da7d6db0c666',
|
||||||
|
'com.android.support:animated-vector-drawable:4bc46edf1946b32d518b41416d1734e915e0cbb28021de3b340527419b070691',
|
||||||
|
'com.android.support:support-vector-drawable:13728f337f36d1c02d52198a6c20724edb447a0875454d829f95cb9eb4aa293b',
|
||||||
|
'com.android.support:support-fragment:541d6393c1e024453aca2a14f31bea0c7270ff4e2a02783f3528aa426367444d',
|
||||||
|
'com.android.support:support-media-compat:cbed07d07e0e84fdb4b75712f5fd946229a8af155933c9a92e41db64d00791e0',
|
||||||
|
'com.android.support:support-core-utils:32fac02eb2c20a77fa3e3bc3ede62392a19613f72b8f8e10f5dfa84bb4c89ea1',
|
||||||
|
'com.android.support:support-core-ui:6182278a6653e6c111c888963626cbb16f2d0022571cb239760475119e0b92a8',
|
||||||
|
'com.android.support:support-compat:e02d781268dc60aab6638d8dc20156ea11ca20b962d294b85e6f1e8418cabfa7',
|
||||||
|
'com.android.support:support-annotations:aedf76962584adfaed2bd3fcaa22406461c4310237fc27e301128edaa2dba2fa',
|
||||||
|
'com.android.support.constraint:constraint-layout-solver:8c62525a9bc5cff5633a96cb9b32fffeccaf41b8841aa87fc22607070dea9b8d',
|
||||||
|
'com.google.zxing:core:bba7724e02a997cec38213af77133ee8e24b0d5cf5fa7ecbc16a4fa93f11ee0d',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -7,13 +7,14 @@
|
|||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@drawable/ic_monero_32dp"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/MyMaterialTheme">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".WalletActivity"
|
android:name=".WalletActivity"
|
||||||
|
@@ -461,12 +461,11 @@ Java_com_m2049r_xmrwallet_model_WalletManager_resolveOpenAlias(JNIEnv *env, jobj
|
|||||||
|
|
||||||
//TODO static std::tuple<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, const std::string &subdir);
|
//TODO static std::tuple<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, const std::string &subdir);
|
||||||
|
|
||||||
// actually a WalletManager function, but logically in onWalletSelected
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_WalletManager_closeJ(JNIEnv *env, jobject instance,
|
Java_com_m2049r_xmrwallet_model_WalletManager_closeJ(JNIEnv *env, jobject instance,
|
||||||
jobject walletInstance) {
|
jobject walletInstance) {
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, walletInstance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, walletInstance);
|
||||||
bool closeSuccess = Bitmonero::WalletManagerFactory::getWalletManager()->closeWallet(wallet);
|
bool closeSuccess = Bitmonero::WalletManagerFactory::getWalletManager()->closeWallet(wallet, false);
|
||||||
if (closeSuccess) {
|
if (closeSuccess) {
|
||||||
MyWalletListener *walletListener = getHandle<MyWalletListener>(env, walletInstance,
|
MyWalletListener *walletListener = getHandle<MyWalletListener>(env, walletInstance,
|
||||||
"listenerHandle");
|
"listenerHandle");
|
||||||
@@ -564,8 +563,13 @@ Java_com_m2049r_xmrwallet_model_Wallet_getIntegratedAddress(JNIEnv *env, jobject
|
|||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_getSecretViewKey(JNIEnv *env, jobject instance) {
|
Java_com_m2049r_xmrwallet_model_Wallet_getSecretViewKey(JNIEnv *env, jobject instance) {
|
||||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
//return env->NewStringUTF(wallet->secretViewKey().c_str()); // changed in head
|
return env->NewStringUTF(wallet->secretViewKey().c_str());
|
||||||
return env->NewStringUTF(wallet->privateViewKey().c_str());
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_com_m2049r_xmrwallet_model_Wallet_getSecretSpendKey(JNIEnv *env, jobject instance) {
|
||||||
|
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||||
|
return env->NewStringUTF(wallet->secretSpendKey().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
@@ -592,12 +596,16 @@ Java_com_m2049r_xmrwallet_model_Wallet_getFilename(JNIEnv *env, jobject instance
|
|||||||
JNIEXPORT jboolean JNICALL
|
JNIEXPORT jboolean JNICALL
|
||||||
Java_com_m2049r_xmrwallet_model_Wallet_initJ(JNIEnv *env, jobject instance,
|
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,
|
||||||
// const std::string &daemon_username = "", const std::string &daemon_password = "") = 0;
|
jstring daemon_username, jstring daemon_password) {
|
||||||
const char *_daemon_address = env->GetStringUTFChars(daemon_address, JNI_FALSE);
|
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);
|
||||||
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);
|
bool status = wallet->init(_daemon_address, upper_transaction_size_limit, _daemon_username, _daemon_password);
|
||||||
env->ReleaseStringUTFChars(daemon_address, _daemon_address);
|
env->ReleaseStringUTFChars(daemon_address, _daemon_address);
|
||||||
|
env->ReleaseStringUTFChars(daemon_username, _daemon_username);
|
||||||
|
env->ReleaseStringUTFChars(daemon_password, _daemon_password);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,12 +16,13 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -68,12 +69,9 @@ public class GenerateFragment extends Fragment {
|
|||||||
bGenerate = (Button) view.findViewById(R.id.bGenerate);
|
bGenerate = (Button) view.findViewById(R.id.bGenerate);
|
||||||
|
|
||||||
etWalletMnemonic.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etWalletMnemonic.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
etWalletAddress.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etWalletAddress.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
etWalletViewKey.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etWalletViewKey.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
etWalletSpendKey.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etWalletSpendKey.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
|
|
||||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
|
||||||
//etWalletMnemonic.setTextIsSelectable(testnet);
|
|
||||||
|
|
||||||
Helper.showKeyboard(getActivity());
|
Helper.showKeyboard(getActivity());
|
||||||
etWalletName.addTextChangedListener(new TextWatcher() {
|
etWalletName.addTextChangedListener(new TextWatcher() {
|
||||||
@@ -297,8 +295,12 @@ public class GenerateFragment extends Fragment {
|
|||||||
private void generateWallet() {
|
private void generateWallet() {
|
||||||
String name = etWalletName.getText().toString();
|
String name = etWalletName.getText().toString();
|
||||||
if (name.length() == 0) return;
|
if (name.length() == 0) return;
|
||||||
String walletPath = Helper.getWalletPath(getActivity(), name);
|
if (name.charAt(0)=='.') {
|
||||||
if (WalletManager.getInstance().walletExists(walletPath)) {
|
Toast.makeText(getActivity(), getString(R.string.generate_wallet_dot), Toast.LENGTH_LONG).show();
|
||||||
|
etWalletName.requestFocus();
|
||||||
|
}
|
||||||
|
File walletFile = Helper.getWalletFile(getActivity(), name);
|
||||||
|
if (WalletManager.getInstance().walletExists(walletFile)) {
|
||||||
Toast.makeText(getActivity(), getString(R.string.generate_wallet_exists), Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(), getString(R.string.generate_wallet_exists), Toast.LENGTH_LONG).show();
|
||||||
etWalletName.requestFocus();
|
etWalletName.requestFocus();
|
||||||
return;
|
return;
|
||||||
@@ -344,6 +346,13 @@ public class GenerateFragment extends Fragment {
|
|||||||
bGenerate.setVisibility(View.VISIBLE);
|
bGenerate.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
Log.d(TAG, "onResume()");
|
||||||
|
activityCallback.setTitle(getString(R.string.generate_title));
|
||||||
|
}
|
||||||
|
|
||||||
GenerateFragment.Listener activityCallback;
|
GenerateFragment.Listener activityCallback;
|
||||||
|
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
@@ -354,6 +363,9 @@ public class GenerateFragment extends Fragment {
|
|||||||
void onGenerate(String name, String password, String address, String viewKey, String spendKey, long height);
|
void onGenerate(String name, String password, String address, String viewKey, String spendKey, long height);
|
||||||
|
|
||||||
File getStorageRoot();
|
File getStorageRoot();
|
||||||
|
|
||||||
|
void setTitle(String title);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -28,15 +30,13 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
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.service.MoneroHandlerThread;
|
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class GenerateReviewFragment extends Fragment {
|
public class GenerateReviewFragment extends Fragment {
|
||||||
static final String TAG = "GenerateReviewFragment";
|
static final String TAG = "GenerateReviewFragment";
|
||||||
static final public String VIEW_DETAILS = "details";
|
static final public String VIEW_TYPE_DETAILS = "details";
|
||||||
static final public String VIEW_ACCEPT = "accept";
|
static final public String VIEW_TYPE_ACCEPT = "accept";
|
||||||
static final public String VIEW_WALLET = "wallet";
|
static final public String VIEW_TYPE_WALLET = "wallet";
|
||||||
|
|
||||||
ProgressBar pbProgress;
|
ProgressBar pbProgress;
|
||||||
TextView tvWalletName;
|
TextView tvWalletName;
|
||||||
@@ -65,6 +65,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
|
|
||||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
boolean testnet = WalletManager.getInstance().isTestNet();
|
||||||
tvWalletMnemonic.setTextIsSelectable(testnet);
|
tvWalletMnemonic.setTextIsSelectable(testnet);
|
||||||
|
tvWalletSpendKey.setTextIsSelectable(testnet);
|
||||||
|
|
||||||
bAccept.setOnClickListener(new View.OnClickListener() {
|
bAccept.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -75,19 +76,17 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
|
|
||||||
showProgress();
|
showProgress();
|
||||||
|
|
||||||
Bundle b = getArguments();
|
Bundle args = getArguments();
|
||||||
String type = b.getString("type");
|
String path = args.getString("path");
|
||||||
if (!type.equals(VIEW_WALLET)) {
|
String password = args.getString("password");
|
||||||
String name = b.getString("name");
|
this.type = args.getString("type");
|
||||||
String password = b.getString("password");
|
new AsyncShow().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR,
|
||||||
tvWalletName.setText(new File(name).getName());
|
path, password);
|
||||||
show(name, password, type);
|
|
||||||
} else {
|
|
||||||
show(walletCallback.getWallet(), null, type);
|
|
||||||
}
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String type;
|
||||||
|
|
||||||
private void acceptWallet() {
|
private void acceptWallet() {
|
||||||
String name = tvWalletName.getText().toString();
|
String name = tvWalletName.getText().toString();
|
||||||
String password = tvWalletPassword.getText().toString();
|
String password = tvWalletPassword.getText().toString();
|
||||||
@@ -95,40 +94,72 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
acceptCallback.onAccept(name, password);
|
acceptCallback.onAccept(name, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show(final String walletPath, final String password, final String type) {
|
private class AsyncShow extends AsyncTask<String, Void, Boolean> {
|
||||||
new Thread(null,
|
String password;
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
final Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
show(wallet, password, type);
|
|
||||||
wallet.close();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, "DetailsReview", MoneroHandlerThread.THREAD_STACK_SIZE).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void show(final Wallet wallet, final String password, final String type) {
|
String name;
|
||||||
if (type.equals(GenerateReviewFragment.VIEW_ACCEPT)) {
|
String address;
|
||||||
tvWalletPassword.setText(password);
|
String seed;
|
||||||
bAccept.setVisibility(View.VISIBLE);
|
String viewKey;
|
||||||
bAccept.setEnabled(true);
|
String spendKey;
|
||||||
|
boolean isWatchOnly;
|
||||||
|
Wallet.Status status;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(String... params) {
|
||||||
|
if (params.length != 2) return false;
|
||||||
|
String walletPath = params[0];
|
||||||
|
password = params[1];
|
||||||
|
|
||||||
|
Wallet wallet;
|
||||||
|
boolean closeWallet;
|
||||||
|
if (type.equals(GenerateReviewFragment.VIEW_TYPE_WALLET)) {
|
||||||
|
wallet = GenerateReviewFragment.this.walletCallback.getWallet();
|
||||||
|
closeWallet = false;
|
||||||
|
} else {
|
||||||
|
wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||||
|
closeWallet = true;
|
||||||
|
}
|
||||||
|
name = wallet.getName();
|
||||||
|
status = wallet.getStatus();
|
||||||
|
if (status != Wallet.Status.Status_Ok) {
|
||||||
|
if (closeWallet) wallet.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
address = wallet.getAddress();
|
||||||
|
seed = wallet.getSeed();
|
||||||
|
viewKey = wallet.getSecretViewKey();
|
||||||
|
spendKey = isWatchOnly ? getActivity().getString(R.string.watchonly_label) : wallet.getSecretSpendKey();
|
||||||
|
isWatchOnly = wallet.isWatchOnly();
|
||||||
|
if (closeWallet) wallet.close();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
tvWalletName.setText(wallet.getName());
|
|
||||||
tvWalletAddress.setText(wallet.getAddress());
|
@Override
|
||||||
tvWalletMnemonic.setText(wallet.getSeed());
|
protected void onPostExecute(Boolean result) {
|
||||||
tvWalletViewKey.setText(wallet.getSecretViewKey());
|
super.onPostExecute(result);
|
||||||
String spend = wallet.isWatchOnly() ? "" : "not available - use seed for recovery";
|
tvWalletName.setText(name);
|
||||||
if (spend.length() > 0) { //TODO should be == 64, but spendkey is not in the API yet
|
if (result) {
|
||||||
tvWalletSpendKey.setText(spend);
|
if (type.equals(GenerateReviewFragment.VIEW_TYPE_ACCEPT)) {
|
||||||
} else {
|
tvWalletPassword.setText(password);
|
||||||
tvWalletSpendKey.setText(getString(R.string.generate_wallet_watchonly));
|
bAccept.setVisibility(View.VISIBLE);
|
||||||
|
bAccept.setEnabled(true);
|
||||||
|
}
|
||||||
|
tvWalletAddress.setText(address);
|
||||||
|
tvWalletMnemonic.setText(seed);
|
||||||
|
tvWalletViewKey.setText(viewKey);
|
||||||
|
tvWalletSpendKey.setText(spendKey);
|
||||||
|
} else {
|
||||||
|
// TODO show proper error message
|
||||||
|
// TODO end the fragment
|
||||||
|
tvWalletAddress.setText(status.toString());
|
||||||
|
tvWalletMnemonic.setText(status.toString());
|
||||||
|
tvWalletViewKey.setText(status.toString());
|
||||||
|
tvWalletSpendKey.setText(status.toString());
|
||||||
|
}
|
||||||
|
hideProgress();
|
||||||
}
|
}
|
||||||
hideProgress();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateReviewFragment.Listener acceptCallback = null;
|
GenerateReviewFragment.Listener acceptCallback = null;
|
||||||
@@ -140,6 +171,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
|
|
||||||
public interface ListenerWithWallet {
|
public interface ListenerWithWallet {
|
||||||
Wallet getWallet();
|
Wallet getWallet();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -163,4 +195,8 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
public void hideProgress() {
|
public void hideProgress() {
|
||||||
pbProgress.setVisibility(View.INVISIBLE);
|
pbProgress.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean backOk() {
|
||||||
|
return !type.equals(GenerateReviewFragment.VIEW_TYPE_ACCEPT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
498
app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java
Normal file
498
app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java
Normal file
File diff suppressed because it is too large
Load Diff
112
app/src/main/java/com/m2049r/xmrwallet/ScannerFragment.java
Normal file
112
app/src/main/java/com/m2049r/xmrwallet/ScannerFragment.java
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017 dm77, m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class ScannerFragment extends Fragment implements ZXingScannerView.ResultHandler {
|
||||||
|
static final String TAG = "ScannerFragment";
|
||||||
|
|
||||||
|
Listener activityCallback;
|
||||||
|
|
||||||
|
public interface Listener {
|
||||||
|
boolean onAddressScanned(String uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ZXingScannerView mScannerView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
Log.d(TAG, "onCreateView");
|
||||||
|
mScannerView = new ZXingScannerView(getActivity());
|
||||||
|
return mScannerView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
Log.d(TAG, "onResume");
|
||||||
|
mScannerView.setResultHandler(this);
|
||||||
|
mScannerView.startCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
static final String QR_SCHEME = "monero:";
|
||||||
|
static final String QR_PAYMENTID = "tx_payment_id";
|
||||||
|
static final String QR_AMOUNT = "tx_amount";
|
||||||
|
|
||||||
|
@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())) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getActivity(), getString(R.string.send_qr_address_invalid), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getActivity(), getString(R.string.send_qr_invalid), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note from dm77:
|
||||||
|
// * Wait 2 seconds to resume the preview.
|
||||||
|
// * On older devices continuously stopping and resuming camera preview can result in freezing the app.
|
||||||
|
// * I don't know why this is the case but I don't have the time to figure out.
|
||||||
|
Handler handler = new Handler();
|
||||||
|
handler.postDelayed(new
|
||||||
|
|
||||||
|
Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mScannerView.resumeCameraPreview(ScannerFragment.this);
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
Log.d(TAG, "onPause");
|
||||||
|
mScannerView.stopCamera();
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
//Log.d(TAG, "attaching scan");
|
||||||
|
if (context instanceof Listener) {
|
||||||
|
this.activityCallback = (Listener) context;
|
||||||
|
} else {
|
||||||
|
throw new ClassCastException(context.toString()
|
||||||
|
+ " must implement Listener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -16,14 +16,16 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -40,14 +42,16 @@ import com.m2049r.xmrwallet.model.PendingTransaction;
|
|||||||
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.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.BarcodeData;
|
||||||
import com.m2049r.xmrwallet.util.TxData;
|
import com.m2049r.xmrwallet.util.TxData;
|
||||||
|
|
||||||
public class SendFragment extends Fragment {
|
public class SendFragment extends Fragment {
|
||||||
static final String TAG = "GenerateFragment";
|
static final String TAG = "SendFragment";
|
||||||
|
|
||||||
EditText etAddress;
|
EditText etAddress;
|
||||||
EditText etPaymentId;
|
EditText etPaymentId;
|
||||||
EditText etAmount;
|
EditText etAmount;
|
||||||
|
Button bScan;
|
||||||
Button bSweep;
|
Button bSweep;
|
||||||
Spinner sMixin;
|
Spinner sMixin;
|
||||||
Spinner sPriority;
|
Spinner sPriority;
|
||||||
@@ -60,11 +64,13 @@ public class SendFragment extends Fragment {
|
|||||||
TextView tvTxDust;
|
TextView tvTxDust;
|
||||||
EditText etNotes;
|
EditText etNotes;
|
||||||
Button bSend;
|
Button bSend;
|
||||||
|
Button bReallySend;
|
||||||
ProgressBar pbProgress;
|
ProgressBar pbProgress;
|
||||||
|
|
||||||
final static int Mixins[] = {4, 6, 8, 10, 13}; // must match the layout XML
|
final static int Mixins[] = {4, 7, 12, 25}; // must match the layout XML
|
||||||
final static PendingTransaction.Priority Priorities[] =
|
final static PendingTransaction.Priority Priorities[] =
|
||||||
{PendingTransaction.Priority.Priority_Low,
|
{PendingTransaction.Priority.Priority_Default,
|
||||||
|
PendingTransaction.Priority.Priority_Low,
|
||||||
PendingTransaction.Priority.Priority_Medium,
|
PendingTransaction.Priority.Priority_Medium,
|
||||||
PendingTransaction.Priority.Priority_High}; // must match the layout XML
|
PendingTransaction.Priority.Priority_High}; // must match the layout XML
|
||||||
|
|
||||||
@@ -79,6 +85,7 @@ public class SendFragment extends Fragment {
|
|||||||
etAddress = (EditText) view.findViewById(R.id.etAddress);
|
etAddress = (EditText) view.findViewById(R.id.etAddress);
|
||||||
etPaymentId = (EditText) view.findViewById(R.id.etPaymentId);
|
etPaymentId = (EditText) view.findViewById(R.id.etPaymentId);
|
||||||
etAmount = (EditText) view.findViewById(R.id.etAmount);
|
etAmount = (EditText) view.findViewById(R.id.etAmount);
|
||||||
|
bScan = (Button) view.findViewById(R.id.bScan);
|
||||||
bSweep = (Button) view.findViewById(R.id.bSweep);
|
bSweep = (Button) view.findViewById(R.id.bSweep);
|
||||||
bPrepareSend = (Button) view.findViewById(R.id.bPrepareSend);
|
bPrepareSend = (Button) view.findViewById(R.id.bPrepareSend);
|
||||||
bPaymentId = (Button) view.findViewById(R.id.bPaymentId);
|
bPaymentId = (Button) view.findViewById(R.id.bPaymentId);
|
||||||
@@ -90,17 +97,14 @@ public class SendFragment extends Fragment {
|
|||||||
tvTxDust = (TextView) view.findViewById(R.id.tvTxDust);
|
tvTxDust = (TextView) view.findViewById(R.id.tvTxDust);
|
||||||
etNotes = (EditText) view.findViewById(R.id.etNotes);
|
etNotes = (EditText) view.findViewById(R.id.etNotes);
|
||||||
bSend = (Button) view.findViewById(R.id.bSend);
|
bSend = (Button) view.findViewById(R.id.bSend);
|
||||||
|
bReallySend = (Button) view.findViewById(R.id.bReallySend);
|
||||||
|
|
||||||
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
||||||
|
|
||||||
etAddress.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etAddress.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
etPaymentId.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etPaymentId.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
etNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
|
||||||
// etAddress.setText("9tDC52GsMjTNt4dpnRCwAF7ekVBkbkgkXGaMKTcSTpBhGpqkPX56jCNRydLq9oGjbbAQBsZhLfgmTKsntmxRd3TaJFYM2f8");
|
|
||||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
|
||||||
if (!testnet) throw new IllegalStateException("Sending TX only on testnet. sorry.");
|
|
||||||
|
|
||||||
Helper.showKeyboard(getActivity());
|
Helper.showKeyboard(getActivity());
|
||||||
etAddress.requestFocus();
|
etAddress.requestFocus();
|
||||||
etAddress.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
etAddress.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
@@ -196,10 +200,18 @@ public class SendFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bScan.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
activityCallback.onScanAddress();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
bPaymentId.setOnClickListener(new View.OnClickListener() {
|
bPaymentId.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
etPaymentId.setText((activityCallback.generatePaymentId()));
|
etPaymentId.setText((Wallet.generatePaymentId()));
|
||||||
|
etPaymentId.setSelection(etPaymentId.getText().length());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -229,6 +241,26 @@ public class SendFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
bSend.setEnabled(false);
|
bSend.setEnabled(false);
|
||||||
|
boolean testnet = WalletManager.getInstance().isTestNet();
|
||||||
|
if (testnet) {
|
||||||
|
send();
|
||||||
|
} else {
|
||||||
|
etNotes.setEnabled(false);
|
||||||
|
Handler handler = new Handler();
|
||||||
|
handler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
bReallySend.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bReallySend.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
bReallySend.setEnabled(false);
|
||||||
send();
|
send();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -245,11 +277,7 @@ public class SendFragment extends Fragment {
|
|||||||
|
|
||||||
private boolean addressOk() {
|
private boolean addressOk() {
|
||||||
String address = etAddress.getText().toString();
|
String address = etAddress.getText().toString();
|
||||||
if (WalletManager.getInstance().isTestNet()) {
|
return Helper.isAddressOk(address, WalletManager.getInstance().isTestNet());
|
||||||
return ((address.length() == 95) && ("9A".indexOf(address.charAt(0)) >= 0));
|
|
||||||
} else {
|
|
||||||
return ((address.length() == 95) && ("4".indexOf(address.charAt(0)) >= 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean amountOk() {
|
private boolean amountOk() {
|
||||||
@@ -259,7 +287,7 @@ public class SendFragment extends Fragment {
|
|||||||
|
|
||||||
private boolean paymentIdOk() {
|
private boolean paymentIdOk() {
|
||||||
String paymentId = etPaymentId.getText().toString();
|
String paymentId = etPaymentId.getText().toString();
|
||||||
return paymentId.isEmpty() || activityCallback.isPaymentIdValid(paymentId);
|
return paymentId.isEmpty() || Wallet.isPaymentIdValid(paymentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareSend() {
|
private void prepareSend() {
|
||||||
@@ -295,6 +323,7 @@ public class SendFragment extends Fragment {
|
|||||||
etAddress.setEnabled(false);
|
etAddress.setEnabled(false);
|
||||||
etPaymentId.setEnabled(false);
|
etPaymentId.setEnabled(false);
|
||||||
etAmount.setEnabled(false);
|
etAmount.setEnabled(false);
|
||||||
|
bScan.setEnabled(false);
|
||||||
bPaymentId.setEnabled(false);
|
bPaymentId.setEnabled(false);
|
||||||
bSweep.setEnabled(false);
|
bSweep.setEnabled(false);
|
||||||
bPrepareSend.setEnabled(false);
|
bPrepareSend.setEnabled(false);
|
||||||
@@ -306,10 +335,14 @@ public class SendFragment extends Fragment {
|
|||||||
etAddress.setEnabled(true);
|
etAddress.setEnabled(true);
|
||||||
etPaymentId.setEnabled(true);
|
etPaymentId.setEnabled(true);
|
||||||
etAmount.setEnabled(true);
|
etAmount.setEnabled(true);
|
||||||
|
bScan.setEnabled(true);
|
||||||
bPaymentId.setEnabled(true);
|
bPaymentId.setEnabled(true);
|
||||||
bSweep.setEnabled(true);
|
bSweep.setEnabled(true);
|
||||||
bPrepareSend.setEnabled(true);
|
bPrepareSend.setEnabled(true);
|
||||||
llConfirmSend.setVisibility(View.GONE);
|
llConfirmSend.setVisibility(View.GONE);
|
||||||
|
bSend.setEnabled(true);
|
||||||
|
etNotes.setEnabled(true);
|
||||||
|
bReallySend.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send() {
|
private void send() {
|
||||||
@@ -327,14 +360,53 @@ public class SendFragment extends Fragment {
|
|||||||
|
|
||||||
void onSend(String notes);
|
void onSend(String notes);
|
||||||
|
|
||||||
String generatePaymentId();
|
|
||||||
|
|
||||||
boolean isPaymentIdValid(String paymentId);
|
|
||||||
|
|
||||||
String getWalletAddress();
|
String getWalletAddress();
|
||||||
|
|
||||||
void onDisposeRequest();
|
void onDisposeRequest();
|
||||||
|
|
||||||
|
void onScanAddress();
|
||||||
|
|
||||||
|
BarcodeData getScannedData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
Log.d(TAG, "onResume");
|
||||||
|
BarcodeData data = activityCallback.getScannedData();
|
||||||
|
if (data != null) {
|
||||||
|
String scannedAddress = data.address;
|
||||||
|
if (scannedAddress != null) {
|
||||||
|
etAddress.setText(scannedAddress);
|
||||||
|
} else {
|
||||||
|
etAddress.getText().clear();
|
||||||
|
}
|
||||||
|
String scannedPaymenId = data.paymentId;
|
||||||
|
if (scannedPaymenId != null) {
|
||||||
|
etPaymentId.setText(scannedPaymenId);
|
||||||
|
} else {
|
||||||
|
etPaymentId.getText().clear();
|
||||||
|
}
|
||||||
|
if (data.amount >= 0) {
|
||||||
|
String scannedAmount = Helper.getDisplayAmount(data.amount);
|
||||||
|
etAmount.setText(scannedAmount);
|
||||||
|
} else {
|
||||||
|
etAmount.getText().clear();
|
||||||
|
}
|
||||||
|
etAmount.requestFocus();
|
||||||
|
etAmount.setSelection(etAmount.getText().length());
|
||||||
|
} else { // no scan data
|
||||||
|
// jump to first empty field
|
||||||
|
if (etAddress.getText().toString().isEmpty()) {
|
||||||
|
etAddress.requestFocus();
|
||||||
|
} else if (etPaymentId.getText().toString().isEmpty()) {
|
||||||
|
etPaymentId.requestFocus();
|
||||||
|
} else {
|
||||||
|
etAmount.requestFocus();
|
||||||
|
etAmount.setSelection(etAmount.getText().length());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -372,6 +444,7 @@ public class SendFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setMessage(errorText);
|
builder.setMessage(errorText);
|
||||||
|
builder.setCancelable(false);
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,28 +16,23 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
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.ProgressBar;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
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;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
|
||||||
import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -50,7 +45,7 @@ public class TxFragment extends Fragment {
|
|||||||
|
|
||||||
static public final String ARG_INFO = "info";
|
static public final String ARG_INFO = "info";
|
||||||
|
|
||||||
private final SimpleDateFormat TS_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
private final SimpleDateFormat TS_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
|
||||||
|
|
||||||
public TxFragment() {
|
public TxFragment() {
|
||||||
super();
|
super();
|
||||||
@@ -146,10 +141,10 @@ public class TxFragment extends Fragment {
|
|||||||
sb.append(getString(R.string.tx_timestamp)).append(": ");
|
sb.append(getString(R.string.tx_timestamp)).append(": ");
|
||||||
sb.append(TS_FORMATTER.format(new Date(info.timestamp * 1000))).append("\n");
|
sb.append(TS_FORMATTER.format(new Date(info.timestamp * 1000))).append("\n");
|
||||||
sb.append(getString(R.string.tx_blockheight)).append(": ");
|
sb.append(getString(R.string.tx_blockheight)).append(": ");
|
||||||
if (info.isPending) {
|
if (info.isFailed) {
|
||||||
sb.append(getString(R.string.tx_pending)).append("\n");
|
|
||||||
} else 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) {
|
||||||
|
sb.append(getString(R.string.tx_pending)).append("\n");
|
||||||
} else {
|
} else {
|
||||||
sb.append(info.blockheight).append("\n");
|
sb.append(info.blockheight).append("\n");
|
||||||
}
|
}
|
||||||
@@ -196,10 +191,10 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxId.setText(info.hash);
|
tvTxId.setText(info.hash);
|
||||||
tvTxKey.setText(info.txKey.isEmpty() ? "-" : info.txKey);
|
tvTxKey.setText(info.txKey.isEmpty() ? "-" : info.txKey);
|
||||||
tvTxPaymentId.setText(info.paymentId);
|
tvTxPaymentId.setText(info.paymentId);
|
||||||
if (info.isPending) {
|
if (info.isFailed) {
|
||||||
tvTxBlockheight.setText(getString(R.string.tx_pending));
|
|
||||||
} else if (info.isFailed) {
|
|
||||||
tvTxBlockheight.setText(getString(R.string.tx_failed));
|
tvTxBlockheight.setText(getString(R.string.tx_failed));
|
||||||
|
} else if (info.isPending) {
|
||||||
|
tvTxBlockheight.setText(getString(R.string.tx_pending));
|
||||||
} else {
|
} else {
|
||||||
tvTxBlockheight.setText("" + info.blockheight);
|
tvTxBlockheight.setText("" + info.blockheight);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -16,17 +16,18 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.ClipData;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.constraint.ConstraintLayout;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v7.widget.DividerItemDecoration;
|
import android.support.v7.widget.DividerItemDecoration;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@@ -36,9 +37,8 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
|
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Transfer;
|
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -49,14 +49,26 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
private NumberFormat formatter = NumberFormat.getInstance();
|
private NumberFormat formatter = NumberFormat.getInstance();
|
||||||
|
|
||||||
TextView tvBalance;
|
TextView tvBalance;
|
||||||
TextView tvUnlockedBalance;
|
TextView tvUnconfirmedAmount;
|
||||||
TextView tvBlockHeightProgress;
|
TextView tvBlockHeightProgress;
|
||||||
TextView tvConnectionStatus;
|
ConstraintLayout clProgress;
|
||||||
LinearLayout llProgress;
|
|
||||||
TextView tvProgress;
|
TextView tvProgress;
|
||||||
ProgressBar pbProgress;
|
ProgressBar pbProgress;
|
||||||
Button bSend;
|
Button bSend;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setHasOptionsMenu(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
|
if (activityCallback.hasWallet())
|
||||||
|
inflater.inflate(R.menu.wallet_menu, menu);
|
||||||
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
@@ -64,20 +76,18 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
|
|
||||||
tvProgress = (TextView) view.findViewById(R.id.tvProgress);
|
tvProgress = (TextView) view.findViewById(R.id.tvProgress);
|
||||||
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
||||||
llProgress = (LinearLayout) view.findViewById(R.id.llProgress);
|
clProgress = (ConstraintLayout) view.findViewById(R.id.clProgress);
|
||||||
tvBalance = (TextView) view.findViewById(R.id.tvBalance);
|
tvBalance = (TextView) view.findViewById(R.id.tvBalance);
|
||||||
tvUnlockedBalance = (TextView) view.findViewById(R.id.tvUnlockedBalance);
|
tvBalance.setText(getResources().getString(R.string.xmr_balance, Helper.getDisplayAmount(0)));
|
||||||
|
tvUnconfirmedAmount = (TextView) view.findViewById(R.id.tvUnconfirmedAmount);
|
||||||
|
tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, Helper.getDisplayAmount(0)));
|
||||||
tvBlockHeightProgress = (TextView) view.findViewById(R.id.tvBlockHeightProgress);
|
tvBlockHeightProgress = (TextView) view.findViewById(R.id.tvBlockHeightProgress);
|
||||||
tvConnectionStatus = (TextView) view.findViewById(R.id.tvConnectionStatus);
|
|
||||||
|
|
||||||
bSend = (Button) view.findViewById(R.id.bSend);
|
bSend = (Button) view.findViewById(R.id.bSend);
|
||||||
|
|
||||||
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.list);
|
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.list);
|
||||||
RecyclerView.ItemDecoration itemDecoration = new
|
|
||||||
DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
|
|
||||||
recyclerView.addItemDecoration(itemDecoration);
|
|
||||||
|
|
||||||
this.adapter = new TransactionInfoAdapter(this);
|
this.adapter = new TransactionInfoAdapter(getActivity(), this);
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
bSend.setOnClickListener(new View.OnClickListener()
|
bSend.setOnClickListener(new View.OnClickListener()
|
||||||
@@ -118,7 +128,7 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onSynced() {
|
public void onSynced() {
|
||||||
if (!activityCallback.isWatchOnly() && WalletManager.getInstance().isTestNet()) {
|
if (!activityCallback.isWatchOnly()) {
|
||||||
bSend.setVisibility(View.VISIBLE);
|
bSend.setVisibility(View.VISIBLE);
|
||||||
bSend.setEnabled(true);
|
bSend.setEnabled(true);
|
||||||
}
|
}
|
||||||
@@ -145,11 +155,13 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void showProgress() {
|
public void showProgress() {
|
||||||
llProgress.setVisibility(View.VISIBLE);
|
clProgress.setVisibility(View.VISIBLE);
|
||||||
|
tvBlockHeightProgress.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideProgress() {
|
public void hideProgress() {
|
||||||
llProgress.setVisibility(View.GONE);
|
clProgress.setVisibility(View.GONE);
|
||||||
|
tvBlockHeightProgress.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
String setActivityTitle(Wallet wallet) {
|
String setActivityTitle(Wallet wallet) {
|
||||||
@@ -158,10 +170,14 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
if (shortName.length() > 16) {
|
if (shortName.length() > 16) {
|
||||||
shortName = shortName.substring(0, 14) + "...";
|
shortName = shortName.substring(0, 14) + "...";
|
||||||
}
|
}
|
||||||
String title = "[" + wallet.getAddress().substring(0, 6) + "] "
|
// TODO very very rarely this craches because getAddress returns "" or so ...
|
||||||
+ shortName
|
// maybe because this runs in the ui thread and not in a 5MB thread
|
||||||
+ (wallet.isWatchOnly() ? " " + getString(R.string.watchonly_label) : "");
|
String title = "[" + wallet.getAddress().substring(0, 6) + "] " + shortName;
|
||||||
activityCallback.setTitle(title);
|
activityCallback.setTitle(title);
|
||||||
|
|
||||||
|
String watchOnly = (wallet.isWatchOnly() ? " " + getString(R.string.watchonly_label) : "");
|
||||||
|
String net = (wallet.isTestNet() ? getString(R.string.connect_testnet) : getString(R.string.connect_mainnet));
|
||||||
|
activityCallback.setSubtitle(net + " " + watchOnly);
|
||||||
Log.d(TAG, "wallet title is " + title);
|
Log.d(TAG, "wallet title is " + title);
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
@@ -175,8 +191,10 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
walletTitle = setActivityTitle(wallet);
|
walletTitle = setActivityTitle(wallet);
|
||||||
onProgress(100); // of loading
|
onProgress(100); // of loading
|
||||||
}
|
}
|
||||||
tvBalance.setText(Wallet.getDisplayAmount(wallet.getBalance()));
|
long balance = wallet.getBalance();
|
||||||
tvUnlockedBalance.setText(Wallet.getDisplayAmount(wallet.getUnlockedBalance()));
|
long unlockedBalance = wallet.getUnlockedBalance();
|
||||||
|
tvBalance.setText(getResources().getString(R.string.xmr_balance, Helper.getDisplayAmount(unlockedBalance)));
|
||||||
|
tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, Helper.getDisplayAmount(balance - unlockedBalance)));
|
||||||
String sync = "";
|
String sync = "";
|
||||||
if (!activityCallback.hasBoundService())
|
if (!activityCallback.hasBoundService())
|
||||||
throw new IllegalStateException("WalletService not bound.");
|
throw new IllegalStateException("WalletService not bound.");
|
||||||
@@ -197,9 +215,10 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
sync = getString(R.string.status_synced) + ": " + formatter.format(wallet.getBlockChainHeight());
|
sync = getString(R.string.status_synced) + ": " + formatter.format(wallet.getBlockChainHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String net = (wallet.isTestNet() ? getString(R.string.connect_testnet) : getString(R.string.connect_mainnet));
|
|
||||||
tvBlockHeightProgress.setText(sync);
|
tvBlockHeightProgress.setText(sync);
|
||||||
tvConnectionStatus.setText(net + " " + daemonConnected.toString().substring(17));
|
//String net = (wallet.isTestNet() ? getString(R.string.connect_testnet) : getString(R.string.connect_mainnet));
|
||||||
|
//activityCallback.setSubtitle(net + " " + daemonConnected.toString().substring(17));
|
||||||
|
// TODO show connected status somewhere
|
||||||
}
|
}
|
||||||
|
|
||||||
Listener activityCallback;
|
Listener activityCallback;
|
||||||
@@ -216,6 +235,8 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
|
|
||||||
void setTitle(String title);
|
void setTitle(String title);
|
||||||
|
|
||||||
|
void setSubtitle(String subtitle);
|
||||||
|
|
||||||
void onSendRequest();
|
void onSendRequest();
|
||||||
|
|
||||||
void onTxDetailsRequest(TransactionInfo info);
|
void onTxDetailsRequest(TransactionInfo info);
|
||||||
@@ -225,6 +246,10 @@ public class WalletFragment extends Fragment implements TransactionInfoAdapter.O
|
|||||||
boolean isWatchOnly();
|
boolean isWatchOnly();
|
||||||
|
|
||||||
String getTxKey(String txId);
|
String getTxKey(String txId);
|
||||||
|
|
||||||
|
void onWalletReceive();
|
||||||
|
|
||||||
|
boolean hasWallet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user