mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-03 08:23:04 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e270b277a5 | ||
![]() |
2842a4042f | ||
![]() |
1614c0ab84 | ||
![]() |
dceca0e198 | ||
![]() |
94947de9ef | ||
![]() |
10ea6d8e0c | ||
![]() |
0d03b75785 | ||
![]() |
a3db07c6a7 | ||
![]() |
6678222202 |
@@ -25,11 +25,13 @@ You may lose all your Moneroj if you use this App. Be cautious when spending on
|
||||
- more sensible error dialogs
|
||||
|
||||
### Issues / Pitfalls
|
||||
- The backups folder is now called "backups" and not ".backups" - which in most file explorers was a hidden folder
|
||||
- Wallets are now created directly in the "monerujo" folder, and not in the ".new" folder as before
|
||||
- You may want to check the old folders with a file browsing app and delete the ".new" and ".backups" folders AFTER moving neccessary wallet files to the new locations. Or simply make new backups from within Monerujo.
|
||||
- Also note, that on some devices the backups will only be visible on a PC over USB after a reboot of the device (it's an Android bug/feature)
|
||||
- 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.
|
||||
- In rare occasions the monero core code returns a wallet address with corrupted characters -
|
||||
in these cases Monerujo crashes on purpose to make sure nothing bad happens
|
||||
|
||||
### HOW TO BUILD
|
||||
No need to build. Binaries are included:
|
||||
|
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 25
|
||||
versionCode 16
|
||||
versionName "0.8.0.3"
|
||||
versionCode 21
|
||||
versionName "0.8.0.8"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
|
@@ -39,6 +39,8 @@ static jclass class_WalletListener;
|
||||
static jclass class_TransactionInfo;
|
||||
static jclass class_Transfer;
|
||||
|
||||
std::mutex _listenerMutex;
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
|
||||
cachedJVM = jvm;
|
||||
LOGI("JNI_OnLoad");
|
||||
@@ -101,6 +103,7 @@ struct MyWalletListener : Bitmonero::WalletListener {
|
||||
};
|
||||
|
||||
void deleteGlobalJavaRef(JNIEnv *env) {
|
||||
std::lock_guard<std::mutex> lock(_listenerMutex);
|
||||
env->DeleteGlobalRef(jlistener);
|
||||
jlistener = nullptr;
|
||||
}
|
||||
@@ -109,6 +112,7 @@ struct MyWalletListener : Bitmonero::WalletListener {
|
||||
* @brief updated - generic callback, called when any event (sent/received/block reveived/etc) happened with the wallet;
|
||||
*/
|
||||
void updated() {
|
||||
std::lock_guard<std::mutex> lock(_listenerMutex);
|
||||
if (jlistener == nullptr) return;
|
||||
LOGD("updated");
|
||||
JNIEnv *jenv;
|
||||
@@ -128,6 +132,7 @@ struct MyWalletListener : Bitmonero::WalletListener {
|
||||
* @param amount - amount
|
||||
*/
|
||||
void moneySpent(const std::string &txId, uint64_t amount) {
|
||||
std::lock_guard<std::mutex> lock(_listenerMutex);
|
||||
if (jlistener == nullptr) return;
|
||||
LOGD("moneySpent %"
|
||||
PRIu64, amount);
|
||||
@@ -139,6 +144,7 @@ struct MyWalletListener : Bitmonero::WalletListener {
|
||||
* @param amount - amount
|
||||
*/
|
||||
void moneyReceived(const std::string &txId, uint64_t amount) {
|
||||
std::lock_guard<std::mutex> lock(_listenerMutex);
|
||||
if (jlistener == nullptr) return;
|
||||
LOGD("moneyReceived %"
|
||||
PRIu64, amount);
|
||||
@@ -150,6 +156,7 @@ struct MyWalletListener : Bitmonero::WalletListener {
|
||||
* @param amount - amount
|
||||
*/
|
||||
void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) {
|
||||
std::lock_guard<std::mutex> lock(_listenerMutex);
|
||||
if (jlistener == nullptr) return;
|
||||
LOGD("unconfirmedMoneyReceived %"
|
||||
PRIu64, amount);
|
||||
@@ -160,6 +167,7 @@ struct MyWalletListener : Bitmonero::WalletListener {
|
||||
* @param height - block height
|
||||
*/
|
||||
void newBlock(uint64_t height) {
|
||||
std::lock_guard<std::mutex> lock(_listenerMutex);
|
||||
if (jlistener == nullptr) return;
|
||||
//LOGD("newBlock");
|
||||
JNIEnv *jenv;
|
||||
@@ -178,6 +186,7 @@ struct MyWalletListener : Bitmonero::WalletListener {
|
||||
* @brief refreshed - called when wallet refreshed by background thread or explicitly refreshed by calling "refresh" synchronously
|
||||
*/
|
||||
void refreshed() {
|
||||
std::lock_guard<std::mutex> lock(_listenerMutex);
|
||||
if (jlistener == nullptr) return;
|
||||
LOGD("refreshed");
|
||||
JNIEnv *jenv;
|
||||
@@ -465,14 +474,15 @@ JNIEXPORT jboolean JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_WalletManager_closeJ(JNIEnv *env, jobject instance,
|
||||
jobject walletInstance) {
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, walletInstance);
|
||||
bool closeSuccess = Bitmonero::WalletManagerFactory::getWalletManager()->closeWallet(wallet, false);
|
||||
bool closeSuccess = Bitmonero::WalletManagerFactory::getWalletManager()->closeWallet(wallet,
|
||||
false);
|
||||
if (closeSuccess) {
|
||||
MyWalletListener *walletListener = getHandle<MyWalletListener>(env, walletInstance,
|
||||
"listenerHandle");
|
||||
if (walletListener != nullptr) {
|
||||
walletListener->deleteGlobalJavaRef(env);
|
||||
delete walletListener;
|
||||
}
|
||||
delete walletListener;
|
||||
}
|
||||
LOGD("wallet closed");
|
||||
return closeSuccess;
|
||||
@@ -601,7 +611,8 @@ Java_com_m2049r_xmrwallet_model_Wallet_initJ(JNIEnv *env, jobject instance,
|
||||
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);
|
||||
bool status = wallet->init(_daemon_address, upper_transaction_size_limit, _daemon_username, _daemon_password);
|
||||
bool status = wallet->init(_daemon_address, upper_transaction_size_limit, _daemon_username,
|
||||
_daemon_password);
|
||||
env->ReleaseStringUTFChars(daemon_address, _daemon_address);
|
||||
env->ReleaseStringUTFChars(daemon_username, _daemon_username);
|
||||
env->ReleaseStringUTFChars(daemon_password, _daemon_password);
|
||||
@@ -919,7 +930,7 @@ jobject newTransferInstance(JNIEnv *env, uint64_t amount, const std::string &add
|
||||
|
||||
jobject newTransferList(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
||||
const std::vector<Bitmonero::TransactionInfo::Transfer> &transfers = info->transfers();
|
||||
if (transfers.size()==0) { // don't create empty Lists
|
||||
if (transfers.size() == 0) { // don't create empty Lists
|
||||
return nullptr;
|
||||
}
|
||||
// make new ArrayList
|
||||
|
@@ -24,6 +24,7 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.StrictMode;
|
||||
@@ -308,12 +309,14 @@ public class LoginActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
private boolean backupWallet(String walletName) {
|
||||
File backupFolder = new File(getStorageRoot(), ".backups");
|
||||
File backupFolder = new File(getStorageRoot(), "backups");
|
||||
if (!backupFolder.exists()) {
|
||||
if (!backupFolder.mkdir()) {
|
||||
Log.e(TAG, "Cannot create backup dir " + backupFolder.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
// make folder visible over USB/MTP
|
||||
MediaScannerConnection.scanFile(this, new String[]{backupFolder.toString()}, null, null);
|
||||
}
|
||||
File walletFile = Helper.getWalletFile(LoginActivity.this, walletName);
|
||||
File backupFile = new File(backupFolder, walletName);
|
||||
@@ -726,26 +729,17 @@ public class LoginActivity extends AppCompatActivity
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
File newWalletFolder = new File(getStorageRoot(), ".new");
|
||||
if (!newWalletFolder.exists()) {
|
||||
if (!newWalletFolder.mkdir()) {
|
||||
Log.e(TAG, "Cannot create new wallet dir " + newWalletFolder.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File newWalletFolder = getStorageRoot();
|
||||
if (!newWalletFolder.isDirectory()) {
|
||||
Log.e(TAG, "New wallet dir " + newWalletFolder.getAbsolutePath() + "is not a directory");
|
||||
Log.e(TAG, "Wallet dir " + newWalletFolder.getAbsolutePath() + "is not a directory");
|
||||
return false;
|
||||
}
|
||||
File cacheFile = new File(newWalletFolder, walletName);
|
||||
cacheFile.delete();
|
||||
File keysFile = new File(newWalletFolder, walletName + ".keys");
|
||||
keysFile.delete();
|
||||
File addressFile = new File(newWalletFolder, walletName + ".address.txt");
|
||||
addressFile.delete();
|
||||
|
||||
if (cacheFile.exists() || keysFile.exists() || addressFile.exists()) {
|
||||
Log.e(TAG, "Cannot remove all old wallet files: " + cacheFile.getAbsolutePath());
|
||||
Log.e(TAG, "Some wallet files already exist for " + cacheFile.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -854,15 +848,11 @@ public class LoginActivity extends AppCompatActivity
|
||||
|
||||
@Override
|
||||
public void onAccept(final String name, final String password) {
|
||||
File newWalletFile = new File(new File(getStorageRoot(), ".new"), name);
|
||||
File walletFolder = getStorageRoot();
|
||||
File walletFile = new File(walletFolder, name);
|
||||
boolean rc = copyWallet(newWalletFile, walletFile, false);
|
||||
if (rc) {
|
||||
walletFile.delete(); // when recovering wallets, the cache seems corrupt
|
||||
// TODO: figure out why this is so? Only for a private testnet?
|
||||
rc = testWallet(walletFile.getAbsolutePath(), password) == Wallet.Status.Status_Ok;
|
||||
}
|
||||
walletFile.delete(); // when recovering wallets, the cache seems corrupt
|
||||
// TODO: figure out why this is so? Only for a private testnet?
|
||||
boolean rc = testWallet(walletFile.getAbsolutePath(), password) == Wallet.Status.Status_Ok;
|
||||
|
||||
if (rc) {
|
||||
popFragmentStack(GENERATE_STACK);
|
||||
@@ -871,7 +861,7 @@ public class LoginActivity extends AppCompatActivity
|
||||
} else {
|
||||
Log.e(TAG, "Wallet store failed to " + walletFile.getAbsolutePath());
|
||||
Toast.makeText(LoginActivity.this,
|
||||
getString(R.string.generate_wallet_create_failed_2), Toast.LENGTH_LONG).show();
|
||||
getString(R.string.generate_wallet_create_failed), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -186,7 +186,7 @@ public class LoginFragment extends Fragment {
|
||||
etDaemonAddress.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
if (hasFocus && !getActivity().isFinishing() && etDaemonAddress.isLaidOut()) {
|
||||
etDaemonAddress.showDropDown();
|
||||
Helper.showKeyboard(getActivity());
|
||||
}
|
||||
@@ -376,7 +376,7 @@ public class LoginFragment extends Fragment {
|
||||
}
|
||||
|
||||
String getDaemon() {
|
||||
return etDaemonAddress.getText().toString();
|
||||
return etDaemonAddress.getText().toString().trim();
|
||||
}
|
||||
|
||||
void setDaemon(NodeList nodeList) {
|
||||
|
@@ -144,7 +144,7 @@ public class LicensesFragment extends DialogFragment {
|
||||
mWebView = (WebView) content.findViewById(R.id.licensesFragmentWebView);
|
||||
mIndeterminateProgress = (ProgressBar) content.findViewById(R.id.licensesFragmentIndeterminateProgress);
|
||||
|
||||
boolean showCloseButton = false;
|
||||
boolean showCloseButton = true;
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments != null) {
|
||||
showCloseButton = arguments.getBoolean(KEY_SHOW_CLOSE_BUTTON);
|
||||
|
@@ -1,107 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletName"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="0dp"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/generate_name_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:textAlignment="center" />
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletName"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/generate_name_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletPassword"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/generate_password_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:textAlignment="center" />
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletPassword"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/generate_password_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:textAlignment="center" />
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletMnemonic"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/generate_mnemonic_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="textMultiLine"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletAddress"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/generate_address_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="textMultiLine"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llRestoreKeys"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletViewKey"
|
||||
android:id="@+id/etWalletMnemonic"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/generate_viewkey_hint"
|
||||
android:hint="@string/generate_mnemonic_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="textMultiLine"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletSpendKey"
|
||||
android:id="@+id/etWalletAddress"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/generate_spendkey_hint"
|
||||
android:hint="@string/generate_address_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="textMultiLine"
|
||||
android:textAlignment="center"/>
|
||||
android:textAlignment="center" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llRestoreKeys"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletViewKey"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/generate_viewkey_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="textMultiLine"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletSpendKey"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/generate_spendkey_hint"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="textMultiLine"
|
||||
android:textAlignment="center" />
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletRestoreHeight"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/generate_restoreheight_hint"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="number"
|
||||
android:textAlignment="center"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bGenerate"
|
||||
style="@style/MoneroButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:enabled="false"
|
||||
android:text="@string/generate_buttonGenerate" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etWalletRestoreHeight"
|
||||
style="@style/MoneroEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/generate_restoreheight_hint"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="number"
|
||||
android:textAlignment="center"
|
||||
android:visibility="gone" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bGenerate"
|
||||
style="@style/MoneroButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:enabled="false"
|
||||
android:text="@string/generate_buttonGenerate" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -100,8 +100,6 @@
|
||||
<string name="generate_wallet_creating">Creating wallet</string>
|
||||
<string name="generate_wallet_created">Wallet created</string>
|
||||
<string name="generate_wallet_create_failed">Wallet create failed</string>
|
||||
<string name="generate_wallet_create_failed_1">Wallet create failed (1/2)</string>
|
||||
<string name="generate_wallet_create_failed_2">Wallet create failed (2/2)</string>
|
||||
<string name="generate_address_placeholder">9tDC52GsMjTNt4dpnRCwAF7ekVBkbkgkXGaMKTcSTpBhGpqkPX56jCNRydLq9oGjbbAQBsZhLfgmTKsntmxRd3TaJFYM2f8</string>
|
||||
<string name="generate_viewkey_placeholder">e2b99f4cc3d644774c4b118db05f8aa9967583a01ca4d47058c3860af10bd306</string>
|
||||
<string name="generate_spendkey_placeholder">300a54208ab0a638a8407a12e3de946da76f5a9ded303338452332ec7755210d</string>
|
||||
|
@@ -8,7 +8,7 @@ replacing "32" with "64".
|
||||
## Prepare Ubuntu environment
|
||||
|
||||
```
|
||||
sudo apt-get install build-essential cmake tofrodos
|
||||
sudo apt-get install build-essential cmake tofrodos libtool-bin
|
||||
sudo mkdir /opt/android
|
||||
sudo chown $LOGNAME /opt/android
|
||||
```
|
||||
@@ -70,9 +70,9 @@ ln -s ../../../../openssl/android-21/lib/libcrypto.so
|
||||
## Build Boost
|
||||
```
|
||||
cd /opt/android
|
||||
wget https://sourceforge.net/projects/boost/files/boost/1.64.0/boost_1_64_0.tar.gz/download -O boost_1_64_0.tar.gz
|
||||
tar xfz boost_1_64_0.tar.gz
|
||||
(cd boost_1_64_0; ./bootstrap.sh)
|
||||
wget https://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.gz/download -O boost_1_58_0.tar.gz
|
||||
tar xfz boost_1_58_0.tar.gz
|
||||
(cd boost_1_58_0; ./bootstrap.sh)
|
||||
```
|
||||
The NDK r15c above gives errors about fsetpos and fgetpos not found(!?!), so we "just" comment them out in the include file:
|
||||
`nano /opt/android/tool32/include/c++/4.9.x/cstdio` (`//using ::fgetpos`, `//using ::fsetpos`)
|
||||
@@ -83,21 +83,51 @@ export PATH=/opt/android/tool32/arm-linux-androideabi/bin:/opt/android/tool32/bi
|
||||
./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --build-dir=android32 --stagedir=android32 toolset=clang threading=multi threadapi=pthread target-os=android stage
|
||||
```
|
||||
|
||||
## Build & prepare zeromq
|
||||
```
|
||||
cd /opt/android
|
||||
wget git clone https://github.com/zeromq/zeromq3-x.git
|
||||
export PATH=/opt/android/tool32/arm-linux-androideabi/bin:/opt/android/tool32/bin:$PATH
|
||||
export OUTPUT_DIR=/opt/android/zeromq
|
||||
./configure --enable-static --disable-shared --host=arm-linux-androideabi --prefix=$OUTPUT_DIR LDFLAGS="-L$OUTPUT_DIR/lib" CPPFLAGS="-isystem /opt/android/tool32/include/c++/4.9.x -fPIC -I$OUTPUT_DIR/include -Wno-error -D__ANDROID_API__=21" LIBS="-lgcc"
|
||||
make
|
||||
make install
|
||||
|
||||
git clone https://github.com/zeromq/cppzmq.git
|
||||
cp cppzmq/*.hpp zeromq/include/
|
||||
```
|
||||
|
||||
## And finally: Build Monero
|
||||
```
|
||||
cd /opt/android
|
||||
git clone https://github.com/monero-project/monero
|
||||
cd monero
|
||||
|
||||
```
|
||||
```
|
||||
# <patch monero code as needed>
|
||||
|
||||
# also, don't abort on warnings:
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 1f74f59..2c791c0 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -400,7 +400,7 @@ else()
|
||||
set(ARCH_FLAG "-march=${ARCH}")
|
||||
endif()
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
- if(NOT MINGW)
|
||||
+ if(NOT MINGW AND NOT ANDROID)
|
||||
set(WARNINGS_AS_ERRORS_FLAG "-Werror")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
```
|
||||
```
|
||||
mkdir -p build/release.android32
|
||||
cd build/release.android32
|
||||
|
||||
# only if not set already set
|
||||
export PATH=/opt/android/tool32/arm-linux-androideabi/bin:/opt/android/tool32/bin:$PATH
|
||||
|
||||
CC=clang CXX=clang++ cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D BUILD_TAG="android" -D BOOST_ROOT=/opt/android/boost_1_64_0 -D BOOST_LIBRARYDIR=/opt/android/boost_1_64_0/android32/lib -D OPENSSL_ROOT_DIR=/opt/android/openssl/android-21 -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=true ../..
|
||||
CC=clang CXX=clang++ cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D BUILD_TAG="android" -D BOOST_ROOT=/opt/android/boost_1_58_0 -D BOOST_LIBRARYDIR=/opt/android/boost_1_58_0/android32/lib -D OPENSSL_ROOT_DIR=/opt/android/openssl/android-21 -D CMAKE_POSITION_INDEPENDENT_CODE:BOOL=true -D ZMQ_INCLUDE_PATH=/opt/android/zeromq/include -D ZMQ_LIB=/opt/android/zeromq/lib/libzmq.a ../..
|
||||
make
|
||||
|
||||
find . -name '*.a' -exec cp '{}' lib \;
|
||||
|
@@ -27,6 +27,11 @@
|
||||
- Archive (=Backup and delete)
|
||||
- 3 Default nodes + History of last 5 used nodes
|
||||
|
||||
## After installing from Google Play the wallet list is empty!
|
||||
Sorry about that. The folder for the wallets was renamed from "Monerujo" to "monerujo".
|
||||
On most devices this does not matter (they don't care about upper/lower case). Yours does.
|
||||
If you use a file explorer (e.g. es file explorer) you can find the Monerujo folder and rename it to "monerujo".
|
||||
|
||||
## I cannot select and copy the mnemonic seed
|
||||
Copying anything to the clipboard on Android exposes it to any other App running. So this
|
||||
is a security measure to keep your seed safe(r).
|
||||
|
Reference in New Issue
Block a user