1
mirror of https://github.com/m2049r/xmrwallet synced 2025-09-02 15:53:04 +02:00

Compare commits

...

8 Commits

Author SHA1 Message Date
m2049r
ccacec9d0b Added explicit info about keeping mnemonic seed safe (#92) 2017-09-30 09:17:47 +02:00
m2049r
9ebacb8528 corrected backups folder 2017-09-29 23:20:38 +02:00
m2049r
49a9f84226 new version 23 2017-09-29 19:50:59 +02:00
m2049r
91b4aaad60 removed unnecessary permission 2017-09-29 19:44:43 +02:00
m2049r
c4ce12ceff Explain permissions 2017-09-29 19:41:22 +02:00
m2049r
96cf9ee95e new version (#91) 2017-09-29 19:21:11 +02:00
m2049r
00852da9f7 Add some Help (#90)
* simple help for create wallet

* toast that selecting seed or spendkey is not allowed
2017-09-29 19:18:07 +02:00
m2049r
15b90e7ebc instructions now cater for zeromq & non-zermq monero 2017-09-28 09:30:15 +02:00
21 changed files with 411 additions and 118 deletions

1
.idea/.gitignore generated vendored
View File

@@ -1,2 +1,3 @@
workspace.xml
markdown-*
misc.xml

46
.idea/misc.xml generated
View File

@@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@@ -14,7 +14,7 @@ You may lose all your Moneroj if you use this App. Be cautious when spending on
- Based off monero v0.11.0.0 with PR #2289 applied
- currently only android32 (runs on 64-bit as well)
- works on the testnet & mainnet
- takes forever to sync due to 32-bit architecture
- sync is slow due to 32-bit architecture
- use your own daemon - it's easy
- screen stays on until first sync is complete
- saves wallet only on first sync and when sending transactions or editing notes

View File

@@ -8,8 +8,8 @@ android {
applicationId "com.m2049r.xmrwallet"
minSdkVersion 21
targetSdkVersion 25
versionCode 21
versionName "0.8.0.8"
versionCode 24
versionName "1.0.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {

View File

@@ -3,7 +3,6 @@
package="com.m2049r.xmrwallet">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

View File

@@ -18,6 +18,7 @@ package com.m2049r.xmrwallet;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.InputType;
@@ -25,6 +26,8 @@ import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
@@ -379,4 +382,15 @@ public class GenerateFragment extends Fragment {
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.create_wallet_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}

View File

@@ -19,14 +19,18 @@ package com.m2049r.xmrwallet;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
@@ -66,6 +70,20 @@ public class GenerateReviewFragment extends Fragment {
boolean testnet = WalletManager.getInstance().isTestNet();
tvWalletMnemonic.setTextIsSelectable(testnet);
tvWalletSpendKey.setTextIsSelectable(testnet);
if (!testnet) {
tvWalletMnemonic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), getString(R.string.message_noselect_seed), Toast.LENGTH_SHORT).show();
}
});
tvWalletSpendKey.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), getString(R.string.message_noselect_key), Toast.LENGTH_SHORT).show();
}
});
}
bAccept.setOnClickListener(new View.OnClickListener() {
@Override
@@ -199,4 +217,15 @@ public class GenerateReviewFragment extends Fragment {
boolean backOk() {
return !type.equals(GenerateReviewFragment.VIEW_TYPE_ACCEPT);
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.wallet_details_menu, menu);
}
}

View File

@@ -45,15 +45,14 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.m2049r.xmrwallet.layout.DropDownEditText;
import com.m2049r.xmrwallet.license.LicensesFragment;
import com.m2049r.xmrwallet.dialog.HelpFragment;
import com.m2049r.xmrwallet.dialog.LicensesFragment;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.service.WalletService;
import com.m2049r.xmrwallet.util.AsyncExchangeRate;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
import com.m2049r.xmrwallet.util.NodeList;
import java.io.File;
import java.io.FileInputStream;
@@ -971,6 +970,12 @@ public class LoginActivity extends AppCompatActivity
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_create_help:
HelpFragment.displayHelp(getSupportFragmentManager(),R.raw.help_create);
return true;
case R.id.action_details_help:
HelpFragment.displayHelp(getSupportFragmentManager(),R.raw.help_details);
return true;
case R.id.action_lincense_info:
LicensesFragment.displayLicensesFragment(getSupportFragmentManager());
return true;

View File

@@ -0,0 +1,160 @@
/**
* Copyright 2013 Adam Speakman, m2049r
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.dialog;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebView;
import android.widget.ProgressBar;
import com.m2049r.xmrwallet.R;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* Based on LicensesFragment by Adam Speakman on 24/09/13.
* http://speakman.net.nz
*/
public class HelpFragment extends DialogFragment {
private static final String FRAGMENT_TAG = "com.m2049r.xmrwallet.dialog.HelpFragment";
private static final String HELP_ID = "HELP_ID";
private AsyncTask<Void, Void, String> loader;
public static HelpFragment newInstance(int helpResourceId) {
HelpFragment fragment = new HelpFragment();
Bundle bundle = new Bundle();
bundle.putInt(HELP_ID, helpResourceId);
fragment.setArguments(bundle);
return fragment;
}
/**
* @param fm A fragment manager instance used to display this LicensesFragment.
*/
public static void displayHelp(FragmentManager fm, int helpResourceId) {
FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(FRAGMENT_TAG);
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = HelpFragment.newInstance(helpResourceId);
newFragment.show(ft, FRAGMENT_TAG);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
int helpId = 0;
Bundle arguments = getArguments();
if (arguments != null) {
helpId = arguments.getInt(HELP_ID);
}
if (helpId > 0)
loadHelp(helpId);
}
@Override
public void onDestroy() {
super.onDestroy();
if (loader != null) {
loader.cancel(true);
}
}
private WebView webView;
private ProgressBar progress;
@SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View content = LayoutInflater.from(getActivity()).inflate(R.layout.help_fragment, null);
webView = (WebView) content.findViewById(R.id.helpFragmentWebView);
progress = (ProgressBar) content.findViewById(R.id.helpFragmentProgress);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(content);
builder.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
private void loadHelp(final int helpResourceId) {
// Load asynchronously in case of a very large file.
loader = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
InputStream rawResource = getActivity().getResources().openRawResource(helpResourceId);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(rawResource));
String line;
StringBuilder sb = new StringBuilder();
try {
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
bufferedReader.close();
} catch (IOException e) {
// TODO You may want to include some logging here.
}
return sb.toString();
}
@Override
protected void onPostExecute(String licensesBody) {
super.onPostExecute(licensesBody);
if (getActivity() == null || isCancelled()) {
return;
}
progress.setVisibility(View.INVISIBLE);
webView.setVisibility(View.VISIBLE);
webView.loadDataWithBaseURL(null, licensesBody, "text/html", "utf-8", null);
loader = null;
}
}.execute();
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.m2049r.xmrwallet.license;
package com.m2049r.xmrwallet.dialog;
import java.io.BufferedReader;
import java.io.IOException;
@@ -51,8 +51,7 @@ public class LicensesFragment extends DialogFragment {
private AsyncTask<Void, Void, String> mLicenseLoader;
private static final String FRAGMENT_TAG = "nz.net.speakman.androidlicensespage.LicensesFragment";
private static final String KEY_SHOW_CLOSE_BUTTON = "keyShowCloseButton";
private static final String FRAGMENT_TAG = "com.m2049r.xmrwalelt.dialog.LicensesFragment";
/**
* Creates a new instance of LicensesFragment with no Close button.
@@ -63,22 +62,6 @@ public class LicensesFragment extends DialogFragment {
return new LicensesFragment();
}
/**
* Creates a new instance of LicensesFragment with an optional Close button.
*
* @param showCloseButton Whether to show a Close button at the bottom of the dialog.
* @return A new licenses fragment.
*/
public static LicensesFragment newInstance(boolean showCloseButton) {
LicensesFragment fragment = new LicensesFragment();
Bundle bundle = new Bundle();
bundle.putBoolean(KEY_SHOW_CLOSE_BUTTON, showCloseButton);
fragment.setArguments(bundle);
return fragment;
}
/**
* Builds and displays a licenses fragment with no Close button. Requires
* "/res/raw/licenses.html" and "/res/layout/licenses_fragment.xml" to be
@@ -99,27 +82,6 @@ public class LicensesFragment extends DialogFragment {
newFragment.show(ft, FRAGMENT_TAG);
}
/**
* Builds and displays a licenses fragment with or without a Close button.
* Requires "/res/raw/licenses.html" and "/res/layout/licenses_fragment.xml"
* to be present.
*
* @param fm A fragment manager instance used to display this LicensesFragment.
* @param showCloseButton Whether to show a Close button at the bottom of the dialog.
*/
public static void displayLicensesFragment(FragmentManager fm, boolean showCloseButton) {
FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(FRAGMENT_TAG);
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = LicensesFragment.newInstance(showCloseButton);
newFragment.show(ft, FRAGMENT_TAG);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -144,26 +106,18 @@ public class LicensesFragment extends DialogFragment {
mWebView = (WebView) content.findViewById(R.id.licensesFragmentWebView);
mIndeterminateProgress = (ProgressBar) content.findViewById(R.id.licensesFragmentIndeterminateProgress);
boolean showCloseButton = true;
Bundle arguments = getArguments();
if (arguments != null) {
showCloseButton = arguments.getBoolean(KEY_SHOW_CLOSE_BUTTON);
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
TextView text = (TextView) content.findViewById(R.id.text);
TextView text = (TextView) content.findViewById(R.id.licensesFragmentText);
text.setText(getString(R.string.about_text, versionName, versionCode));
builder.setView(content);
if (showCloseButton) {
builder.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
}
builder.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
</vector>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/helpFragmentIcon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
android:padding="8sp"/>
<WebView
android:id="@+id/helpFragmentWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/helpFragmentIcon"
android:visibility="invisible" />
<ProgressBar
android:id="@+id/helpFragmentProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true" />
</RelativeLayout>

View File

@@ -6,18 +6,18 @@
android:orientation="vertical">
<ImageView
android:id="@+id/icon"
android:id="@+id/licensesFragmentIcon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
android:padding="8sp"/>
<TextView
android:id="@+id/text"
android:id="@+id/licensesFragmentText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/about_text"
android:layout_below="@+id/icon"
android:layout_below="@+id/licensesFragmentIcon"
android:gravity="center"
android:layout_marginBottom="8sp"/>
@@ -25,7 +25,7 @@
android:id="@+id/licensesFragmentWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/text"
android:layout_below="@+id/licensesFragmentText"
android:visibility="invisible" />
<ProgressBar

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_create_help"
android:icon="@drawable/ic_help_black_24dp"
android:orderInCategory="100"
android:title="@string/menu_help"
app:showAsAction="always" />
</menu>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_details_help"
android:icon="@drawable/ic_help_black_24dp"
android:orderInCategory="100"
android:title="@string/menu_help"
app:showAsAction="always" />
</menu>

View File

@@ -0,0 +1,54 @@
<html>
<head>
<style>body {font-family: sans-serif; font-size: 1em;}</style>
</head>
<body>
<h1>Create Wallet</h1>
A wallet can be created in a number of ways:
<ul>
<li>New Address</li>
<li>Recover from Seed</li>
<li>Recover from Keys</li>
<li>View Only</li>
</ul>
In all cases you need to name your wallet and give it a password. The password is used for
securing your wallet data on the device. Use a strong password - better a passphrase.
<h2>New Address</h2>
You need a new Monero Address - no need to enter additional info.
<h3>Take Note of your Mnemonic Seed!</h3>
<p>
On the following screen you will find your 25-word "Mnemonic Seed".
This is the only data needed to recover your wallet at a later time
and gain full access to your funds.
Keeping this secure and private is very important, as it gives <em>anyone</em>
full access to your funds!
</p>
<p>
If you loose your wallet password, you can still recover your wallet with the mnemonic seed.
</p>
<p>
There is no way to recover it if it is lost! Your funds would be lost.
The mnemonic seed can also never be changed, and if it is stolen or otherwise compromised,
you will have to move your funds to new wallet (with a new mnemonic seed). Therefore, it is best
that you backup your mnemonic seed by writing it down and storing it in <em>multiple</em> safe
and secure places.
</p>
<h2>Recover from Seed</h2>
You already have a Monero Address and want to recover the transactions from the blockchain.<br/>
Enter your Seed in the field "Mnemonic Seed". If you know the block number of the first
transaction used for this address, enter it in the field "Restore Height" - leaving in blank will
scan the <em>entire</em> blockchain for transactions belonging to your address.
This takes a <em>long</em> time.
<h2>Recover from Keys</h2>
Instead of recovering from the mnemonic seed, you can recover using your keys.<br/>
Enter your Monero Address in the field "Public Address" and fill out "View Key", "Spend Key"
and optionally "Restore Height" with the appropriate values.
<h2>View Only</h2>
You just want to monitor incoming transactions to a wallet.<br/>
Enter your Monero Address in the field "Public Address" and fill out the "View Key" and
optionally "Restore Height" with the appropriate values leaving the "Spend Key" blank.
</body>
</html>

View File

@@ -0,0 +1,44 @@
<html>
<head>
<style>body {font-family: sans-serif; font-size: 1em;}</style>
</head>
<body>
<h1>Wallet Details</h1>
Here you see the details of your wallet.
<ul>
<li>Mnemonic Seed</li>
<li>Public Address</li>
<li>View Key</li>
<li>Spend Key</li>
</ul>
<h2>Mnemonic Seed</h2>
<p>
Your 25-word "Mnemonic Seed". This is the only data needed to recover your wallet at a later
time and gain full access to your funds.
Keeping this secure and private is very important, as it gives <em>anyone</em>
full access to your funds!
</p>
<p>
If you loose your wallet password, you can still recover your wallet with the mnemonic seed.
</p>
<p>
There is no way to recover it if it is lost! Your funds would be lost.
The mnemonic seed can also never be changed, and if it is stolen or otherwise compromised,
you will have to move your funds to new wallet (with a new mnemonic seed). Therefore, it is best
that you backup your mnemonic seed by writing it down and storing it in <em>multiple</em> safe
and secure places.
</p>
<h2>Public Address</h2>
This is your account number. You can use it to receive funds. A sender needs to know nothing
more.
<h2>View Key</h2>
This key is required for creating a view-only wallet or for recovering from keys.
<h2>Spend Key</h2>
This is key is required for recovering from keys.
</body>
</html>

View File

@@ -6,6 +6,7 @@
<string name="menu_testnet">Testnet</string>
<string name="menu_about">About &#8230;</string>
<string name="menu_help">Help</string>
<string name="menu_info">Details</string>
<string name="menu_receive">QR Receive</string>
<string name="menu_rename">Rename</string>
@@ -82,6 +83,9 @@
<string name="message_strorage_not_permitted">We really need those External Storage permissions!</string>
<string name="message_camera_not_permitted">No camera = No QR scanning!</string>
<string name="message_noselect_seed">Selecting seed disabled for security reasons!</string>
<string name="message_noselect_key">Selecting spend key disabled for security reasons!</string>
<string name="generate_title">Create Wallet</string>
<string name="generate_name_hint">Wallet Name</string>
<string name="generate_password_hint">Wallet Password</string>

View File

@@ -84,6 +84,7 @@ export PATH=/opt/android/tool32/arm-linux-androideabi/bin:/opt/android/tool32/bi
```
## Build & prepare zeromq
Only needed for zeromq versions (>v0.11.0.0).
```
cd /opt/android
wget git clone https://github.com/zeromq/zeromq3-x.git
@@ -105,7 +106,7 @@ cd monero
```
```
# <patch monero code as needed>
# also, don't abort on warnings:
# also, don't abort on warnings (this is only an issue >v0.11.0.0):
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1f74f59..2c791c0 100644
--- a/CMakeLists.txt
@@ -127,7 +128,12 @@ cd build/release.android32
# only if not set already set
export PATH=/opt/android/tool32/arm-linux-androideabi/bin:/opt/android/tool32/bin:$PATH
# for zeromq versions (>v0.11.0.0).
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 ../..
# for pre-zeromq versions (<=v0.11.0.0).
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 ../..
make
find . -name '*.a' -exec cp '{}' lib \;

View File

@@ -22,7 +22,7 @@
- All significant figures shown in balance
- QR Code scanning - make sure to *ALWAYS* verify the scanned code is what it is advertised to be!
- QR Code for receiving with conversion of XMR to USD/EUR and back through kraken API
- Backup wallets to ```.backups``` folder in main wallet folder (old backups are overwritten)
- Backup wallets to ```backups``` folder in main wallet folder (old backups are overwritten)
- Rename wallets
- Archive (=Backup and delete)
- 3 Default nodes + History of last 5 used nodes

View File

@@ -1,4 +1,11 @@
# Privacy Policy
All data entered in the monerujo app is stored locally on the device and is not collected remotely or otherwise processed except
for the purpose of processing transactions in the monero network in encrypted form.
All data entered in the Monerujo app is stored locally on the device and is not collected remotely or otherwise processed except
for the purpose of processing transactions in the Monero Network in encrypted form.
## App permissions
- INTERNET : Connect to the Monero Network via Monero Daemon Node
- READ_EXTERNAL_STORAGE : Read wallets
- WRITE_EXTERNAL_STORAGE : Write wallets
- WAKE_LOCK : Keep device awake while syncing
- CAMERA : Scan QR Codes