wownero
/
wownerujo
Archived
4
0
Fork 0

Receive QR code

upstream
m2049r 7 years ago
parent e0439a1359
commit 93025c5e1b

@ -69,12 +69,9 @@ public class GenerateFragment extends Fragment {
bGenerate = (Button) view.findViewById(R.id.bGenerate);
etWalletMnemonic.setRawInputType(InputType.TYPE_CLASS_TEXT);
etWalletAddress.setRawInputType(InputType.TYPE_CLASS_TEXT);
etWalletViewKey.setRawInputType(InputType.TYPE_CLASS_TEXT);
etWalletSpendKey.setRawInputType(InputType.TYPE_CLASS_TEXT);
boolean testnet = WalletManager.getInstance().isTestNet();
//etWalletMnemonic.setTextIsSelectable(testnet);
etWalletAddress.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
etWalletViewKey.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
etWalletSpendKey.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
Helper.showKeyboard(getActivity());
etWalletName.addTextChangedListener(new TextWatcher() {
@ -298,8 +295,8 @@ public class GenerateFragment extends Fragment {
private void generateWallet() {
String name = etWalletName.getText().toString();
if (name.length() == 0) return;
String walletPath = Helper.getWalletPath(getActivity(), name);
if (WalletManager.getInstance().walletExists(walletPath)) {
File walletFile = Helper.getWalletFile(getActivity(), name);
if (WalletManager.getInstance().walletExists(walletFile)) {
Toast.makeText(getActivity(), getString(R.string.generate_wallet_exists), Toast.LENGTH_LONG).show();
etWalletName.requestFocus();
return;

@ -79,10 +79,10 @@ public class GenerateReviewFragment extends Fragment {
Bundle b = getArguments();
String type = b.getString("type");
if (!type.equals(VIEW_WALLET)) {
String name = b.getString("name");
String path = b.getString("path");
String password = b.getString("password");
tvWalletName.setText(new File(name).getName());
show(name, password, type);
tvWalletName.setText(new File(path).getName());
show(path, password, type);
} else {
show(walletCallback.getWallet(), null, type);
}

@ -85,8 +85,8 @@ public class LoginActivity extends AppCompatActivity
}
Log.d(TAG, "selected wallet is ." + walletName + ".");
// now it's getting real, check if wallet exists
String walletPath = Helper.getWalletPath(this, walletName);
if (WalletManager.getInstance().walletExists(walletPath)) {
File walletFile = Helper.getWalletFile(this, walletName);
if (WalletManager.getInstance().walletExists(walletFile)) {
promptPassword(walletName, new PasswordAction() {
@Override
public void action(String walletName, String password) {
@ -101,12 +101,12 @@ public class LoginActivity extends AppCompatActivity
@Override
public void onWalletDetails(final String walletName) {
Log.d(TAG, "details for wallet ." + walletName + ".");
final String walletPath = Helper.getWalletPath(this, walletName);
if (WalletManager.getInstance().walletExists(walletPath)) {
final File walletFile = Helper.getWalletFile(this, walletName);
if (WalletManager.getInstance().walletExists(walletFile)) {
promptPassword(walletName, new PasswordAction() {
@Override
public void action(String walletName, String password) {
startDetails(walletPath, password, GenerateReviewFragment.VIEW_DETAILS);
startDetails(walletFile, password, GenerateReviewFragment.VIEW_DETAILS);
}
});
} else { // this cannot really happen as we prefilter choices
@ -114,6 +114,18 @@ public class LoginActivity extends AppCompatActivity
}
}
@Override
public void onWalletReceive(final String walletName) {
Log.d(TAG, "receive for wallet ." + walletName + ".");
final File walletFile = Helper.getWalletFile(this, walletName);
if (WalletManager.getInstance().walletExists(walletFile)) {
String address = WalletManager.getInstance().getWalletInfo(walletFile).address;
startReceive(address);
} else { // this cannot really happen as we prefilter choices
Toast.makeText(this, getString(R.string.bad_wallet), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onAddWallet() {
startGenerateFragment();
@ -251,15 +263,22 @@ public class LoginActivity extends AppCompatActivity
startActivity(intent);
}
void startDetails(final String walletPath, final String password, String type) {
void startDetails(final File walletFile, final String password, String type) {
Log.d(TAG, "startDetails()");
Bundle b = new Bundle();
b.putString("name", walletPath);
b.putString("path", walletFile.getAbsolutePath());
b.putString("password", password);
b.putString("type", type);
startReviewFragment(b);
}
void startReceive(String address) {
Log.d(TAG, "startReceive()");
Bundle b = new Bundle();
b.putString("address", address);
startReceiveFragment(b);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult()");
@ -297,6 +316,11 @@ public class LoginActivity extends AppCompatActivity
Log.d(TAG, "GenerateReviewFragment placed");
}
void startReceiveFragment(Bundle extras) {
replaceFragment(new ReceiveFragment(), null, extras);
Log.d(TAG, "ReceiveFragment placed");
}
void replaceFragment(Fragment newFragment, String stackName, Bundle extras) {
if (extras != null) {
newFragment.setArguments(extras);
@ -345,29 +369,29 @@ public class LoginActivity extends AppCompatActivity
return;
}
String newWalletPath = new File(newWalletFolder, name).getAbsolutePath();
boolean success = walletCreator.createWallet(newWalletPath, password);
File newWalletFile = new File(newWalletFolder, name);
boolean success = walletCreator.createWallet(newWalletFile, password);
if (success) {
startDetails(newWalletPath, password, GenerateReviewFragment.VIEW_ACCEPT);
startDetails(newWalletFile, password, GenerateReviewFragment.VIEW_ACCEPT);
} else {
Toast.makeText(LoginActivity.this,
getString(R.string.generate_wallet_create_failed), Toast.LENGTH_LONG).show();
Log.e(TAG, "Could not create new wallet in " + newWalletPath);
Log.e(TAG, "Could not create new wallet in " + newWalletFile.getAbsolutePath());
}
}
interface WalletCreator {
boolean createWallet(String path, String password);
boolean createWallet(File aFile, String password);
}
@Override
public void onGenerate(String name, String password) {
createWallet(name, password,
new WalletCreator() {
public boolean createWallet(String path, String password) {
public boolean createWallet(File aFile, String password) {
Wallet newWallet = WalletManager.getInstance()
.createWallet(path, password, MNEMONIC_LANGUAGE);
.createWallet(aFile, password, MNEMONIC_LANGUAGE);
boolean success = (newWallet.getStatus() == Wallet.Status.Status_Ok);
if (!success) Log.e(TAG, newWallet.getErrorString());
newWallet.close();
@ -380,8 +404,8 @@ public class LoginActivity extends AppCompatActivity
public void onGenerate(String name, String password, final String seed, final long restoreHeight) {
createWallet(name, password,
new WalletCreator() {
public boolean createWallet(String path, String password) {
Wallet newWallet = WalletManager.getInstance().recoveryWallet(path, seed, restoreHeight);
public boolean createWallet(File aFile, String password) {
Wallet newWallet = WalletManager.getInstance().recoveryWallet(aFile, seed, restoreHeight);
boolean success = (newWallet.getStatus() == Wallet.Status.Status_Ok);
if (!success) Log.e(TAG, newWallet.getErrorString());
newWallet.setPassword(password);
@ -397,9 +421,9 @@ public class LoginActivity extends AppCompatActivity
final String address, final String viewKey, final String spendKey, final long restoreHeight) {
createWallet(name, password,
new WalletCreator() {
public boolean createWallet(String path, String password) {
public boolean createWallet(File aFile, String password) {
Wallet newWallet = WalletManager.getInstance()
.createWalletFromKeys(path, MNEMONIC_LANGUAGE, restoreHeight,
.createWalletFromKeys(aFile, MNEMONIC_LANGUAGE, restoreHeight,
address, viewKey, spendKey);
boolean success = (newWallet.getStatus() == Wallet.Status.Status_Ok);
if (!success) Log.e(TAG, newWallet.getErrorString());

@ -86,6 +86,8 @@ public class LoginFragment extends Fragment {
void onWalletDetails(final String wallet);
void onWalletReceive(final String wallet);
void onAddWallet();
void setTitle(String title);
@ -408,17 +410,18 @@ public class LoginFragment extends Fragment {
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
String listItem = (String) listView.getItemAtPosition(info.position);
switch (item.getItemId()) {
case R.id.action_info:
String listItem = (String) listView.getItemAtPosition(info.position);
return showInfo(listItem);
case R.id.action_receive:
return showReceive(listItem);
default:
return super.onContextItemSelected(item);
}
}
private boolean showInfo(String listItem) {
if (listItem.length() <= (WALLETNAME_PREAMBLE_LENGTH)) {
Toast.makeText(getActivity(), getString(R.string.panic), Toast.LENGTH_LONG).show();
return true;
@ -436,4 +439,21 @@ public class LoginFragment extends Fragment {
activityCallback.onWalletDetails(wallet);
return true;
}
private boolean showReceive(String listItem) {
if (listItem.length() <= (WALLETNAME_PREAMBLE_LENGTH)) {
Toast.makeText(getActivity(), getString(R.string.panic), Toast.LENGTH_LONG).show();
return true;
}
String wallet = listItem.substring(WALLETNAME_PREAMBLE_LENGTH);
String x = isMainNet() ? "4" : "9A";
if (x.indexOf(listItem.charAt(1)) < 0) {
Toast.makeText(getActivity(), getString(R.string.prompt_wrong_net), Toast.LENGTH_LONG).show();
return true;
}
activityCallback.onWalletReceive(wallet);
return true;
}
}

@ -0,0 +1,265 @@
/*
* Copyright (c) 2017 m2049r
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.m2049r.xmrwallet;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.util.Helper;
import java.util.HashMap;
import java.util.Map;
public class ReceiveFragment extends Fragment {
static final String TAG = "ReceiveFragment";
TextView tvAddress;
EditText etPaymentId;
EditText etAmount;
Button bPaymentId;
Button bGenerate;
ImageView qrCode;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.receive_fragment, container, false);
tvAddress = (TextView) view.findViewById(R.id.tvAddress);
etPaymentId = (EditText) view.findViewById(R.id.etPaymentId);
etAmount = (EditText) view.findViewById(R.id.etAmount);
bPaymentId = (Button) view.findViewById(R.id.bPaymentId);
qrCode = (ImageView) view.findViewById(R.id.qrCode);
bGenerate = (Button) view.findViewById(R.id.bGenerate);
etPaymentId.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
Helper.showKeyboard(getActivity());
etPaymentId.requestFocus();
etPaymentId.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_NEXT)) {
if (paymentIdOk()) {
etAmount.requestFocus();
} // otherwise ignore
return true;
}
return false;
}
});
etPaymentId.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable editable) {
qrCode.setImageBitmap(null);
if (paymentIdOk() && amountOk()) {
bGenerate.setEnabled(true);
} else {
bGenerate.setEnabled(false);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
etAmount.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_NEXT)) {
if (paymentIdOk() && amountOk()) {
Helper.hideKeyboard(getActivity());
generateQr();
}
return true;
}
return false;
}
});
etAmount.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable editable) {
qrCode.setImageBitmap(null);
if (paymentIdOk() && amountOk()) {
bGenerate.setEnabled(true);
} else {
bGenerate.setEnabled(false);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
bPaymentId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
etPaymentId.setText((Wallet.generatePaymentId()));
etPaymentId.setSelection(etPaymentId.getText().length());
if (paymentIdOk() && amountOk()) {
generateQr();
}
}
});
bGenerate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (paymentIdOk() && amountOk()) {
Helper.hideKeyboard(getActivity());
generateQr();
}
}
});
Bundle b = getArguments();
String address = b.getString("address", "");
tvAddress.setText(address);
return view;
}
private boolean amountOk() {
String amountEntry = etAmount.getText().toString();
if (amountEntry.isEmpty()) return true;
long amount = Wallet.getAmountFromString(amountEntry);
return (amount > 0);
}
private boolean paymentIdOk() {
String paymentId = etPaymentId.getText().toString();
return paymentId.isEmpty() || Wallet.isPaymentIdValid(paymentId);
}
private void generateQr() {
String address = tvAddress.getText().toString();
String paymentId = etPaymentId.getText().toString();
String enteredAmount = etAmount.getText().toString();
// that's a lot of converting ...
String amount = (enteredAmount.isEmpty()?enteredAmount:Helper.getDisplayAmount(Wallet.getAmountFromString(enteredAmount)));
StringBuffer sb = new StringBuffer();
sb.append(ScannerFragment.QR_SCHEME).append(address);
boolean first = true;
if (!paymentId.isEmpty()) {
if (first) {
sb.append("?");
first = false;
}
sb.append(ScannerFragment.QR_PAYMENTID).append('=').append(paymentId);
}
if (!amount.isEmpty()) {
if (first) {
sb.append("?");
} else {
sb.append("&");
}
sb.append(ScannerFragment.QR_AMOUNT).append('=').append(amount);
}
String text = sb.toString();
Bitmap qr = generate(text, 500, 500);
if (qr != null) {
qrCode.setImageBitmap(qr);
}
}
public Bitmap generate(String text, int width, int height) {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
try {
BitMatrix bitMatrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
int[] pixels = new int[width * height];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (bitMatrix.get(j, i)) {
pixels[i * width + j] = 0x00000000;
} else {
pixels[i * height + j] = 0xffffffff;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.RGB_565);
bitmap = addLogo(bitmap);
return bitmap;
} catch (WriterException e) {
e.printStackTrace();
}
return null;
}
private Bitmap addLogo(Bitmap qrBitmap) {
Bitmap logo = getMoneroLogo();
int qrWidth = qrBitmap.getWidth();
int qrHeight = qrBitmap.getHeight();
int logoWidth = logo.getWidth();
int logoHeight = logo.getHeight();
Bitmap logoBitmap = Bitmap.createBitmap(qrWidth, qrHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(logoBitmap);
canvas.drawBitmap(qrBitmap, 0, 0, null);
canvas.save(Canvas.ALL_SAVE_FLAG);
// figure out how to scale the logo
float scaleSize = 1.0f;
while ((logoWidth / scaleSize) > (qrWidth / 5) || (logoHeight / scaleSize) > (qrHeight / 5)) {
scaleSize *= 2;
}
float sx = 1.0f / scaleSize;
canvas.scale(sx, sx, qrWidth / 2, qrHeight / 2);
canvas.drawBitmap(logo, (qrWidth - logoWidth) / 2, (qrHeight - logoHeight) / 2, null);
canvas.restore();
return logoBitmap;
}
private Bitmap logo = null;
private Bitmap getMoneroLogo() {
if (logo == null) {
logo = Helper.getBitmap(getContext(), R.drawable.ic_monero_qr);
}
return logo;
}
}

@ -100,8 +100,8 @@ public class SendFragment extends Fragment {
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
etAddress.setRawInputType(InputType.TYPE_CLASS_TEXT);
etPaymentId.setRawInputType(InputType.TYPE_CLASS_TEXT);
etAddress.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
etPaymentId.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
etNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
Helper.showKeyboard(getActivity());
@ -209,7 +209,8 @@ public class SendFragment extends Fragment {
bPaymentId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
etPaymentId.setText((activityCallback.generatePaymentId()));
etPaymentId.setText((Wallet.generatePaymentId()));
etPaymentId.setSelection(etPaymentId.getText().length());
}
});
@ -285,7 +286,7 @@ public class SendFragment extends Fragment {
private boolean paymentIdOk() {
String paymentId = etPaymentId.getText().toString();
return paymentId.isEmpty() || activityCallback.isPaymentIdValid(paymentId);
return paymentId.isEmpty() || Wallet.isPaymentIdValid(paymentId);
}
private void prepareSend() {
@ -358,10 +359,6 @@ public class SendFragment extends Fragment {
void onSend(String notes);
String generatePaymentId();
boolean isPaymentIdValid(String paymentId);
String getWalletAddress();
void onDisposeRequest();

@ -561,16 +561,6 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
}
}
@Override
public String generatePaymentId() {
return getWallet().generatePaymentId();
}
@Override
public boolean isPaymentIdValid(String paymentId) {
return Wallet.isPaymentIdValid(paymentId);
}
@Override
public String getWalletAddress() {
return getWallet().getAddress();

@ -71,8 +71,8 @@ public class WalletManager {
managedWallets.remove(walletId);
}
public Wallet createWallet(String path, String password, String language) {
long walletHandle = createWalletJ(path, password, language, isTestNet());
public Wallet createWallet(File aFile, String password, String language) {
long walletHandle = createWalletJ(aFile.getAbsolutePath(), password, language, isTestNet());
Wallet wallet = new Wallet(walletHandle);
manageWallet(wallet.getName(), wallet);
return wallet;
@ -89,14 +89,14 @@ public class WalletManager {
private native long openWalletJ(String path, String password, boolean isTestNet);
public Wallet recoveryWallet(String path, String mnemonic) {
Wallet wallet = recoveryWallet(path, mnemonic, 0);
public Wallet recoveryWallet(File aFile, String mnemonic) {
Wallet wallet = recoveryWallet(aFile, mnemonic, 0);
manageWallet(wallet.getName(), wallet);
return wallet;
}
public Wallet recoveryWallet(String path, String mnemonic, long restoreHeight) {
long walletHandle = recoveryWalletJ(path, mnemonic, isTestNet(), restoreHeight);
public Wallet recoveryWallet(File aFile, String mnemonic, long restoreHeight) {
long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), mnemonic, isTestNet(), restoreHeight);
Wallet wallet = new Wallet(walletHandle);
manageWallet(wallet.getName(), wallet);
return wallet;
@ -104,9 +104,9 @@ public class WalletManager {
private native long recoveryWalletJ(String path, String mnemonic, boolean isTestNet, long restoreHeight);
public Wallet createWalletFromKeys(String path, String language, long restoreHeight,
public Wallet createWalletFromKeys(File aFile, String language, long restoreHeight,
String addressString, String viewKeyString, String spendKeyString) {
long walletHandle = createWalletFromKeysJ(path, language, isTestNet(), restoreHeight,
long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), language, isTestNet(), restoreHeight,
addressString, viewKeyString, spendKeyString);
Wallet wallet = new Wallet(walletHandle);
manageWallet(wallet.getName(), wallet);
@ -134,6 +134,10 @@ public class WalletManager {
return closed;
}
public boolean walletExists(File aFile) {
return walletExists(aFile.getAbsolutePath());
}
public native boolean walletExists(String path);
public native boolean verifyWalletPassword(String keys_file_name, String password, boolean watch_only);
@ -146,6 +150,31 @@ public class WalletManager {
public String address;
}
public WalletInfo getWalletInfo(File wallet) {
WalletInfo info = new WalletInfo();
info.path = wallet.getParentFile();
info.name = wallet.getName();
File addressFile = new File(info.path, info.name + ".address.txt");
//Log.d(TAG, addressFile.getAbsolutePath());
info.address = "??????";
BufferedReader addressReader = null;
try {
addressReader = new BufferedReader(new FileReader(addressFile));
info.address = addressReader.readLine();
} catch (IOException ex) {
Log.d(TAG, ex.getLocalizedMessage());
} finally {
if (addressReader != null) {
try {
addressReader.close();
} catch (IOException ex) {
// that's just too bad
}
}
}
return info;
}
public List<WalletInfo> findWallets(File path) {
List<WalletInfo> wallets = new ArrayList<>();
Log.d(TAG, "Scanning: " + path.getAbsolutePath());
@ -155,29 +184,9 @@ public class WalletManager {
}
});
for (int i = 0; i < found.length; i++) {
WalletInfo info = new WalletInfo();
info.path = path;
String filename = found[i].getName();
info.name = filename.substring(0, filename.length() - 5); // 5 is length of ".keys"+1
File addressFile = new File(path, info.name + ".address.txt");
//Log.d(TAG, addressFile.getAbsolutePath());
info.address = "??????";
BufferedReader addressReader = null;
try {
addressReader = new BufferedReader(new FileReader(addressFile));
info.address = addressReader.readLine();
} catch (IOException ex) {
Log.d(TAG, ex.getLocalizedMessage());
} finally {
if (addressReader != null) {
try {
addressReader.close();
} catch (IOException ex) {
// that's just too bad
}
}
}
wallets.add(info);
File f = new File(found[i].getParent(), filename.substring(0, filename.length() - 5)); // 5 is length of ".keys"+1
wallets.add(getWalletInfo(f));
}
return wallets;
}

@ -527,7 +527,7 @@ public class WalletService extends Service {
}
private Wallet openWallet(String walletName, String walletPassword) {
String path = Helper.getWalletPath(getApplicationContext(), walletName);
String path = Helper.getWalletFile(getApplicationContext(), walletName).getAbsolutePath();
showProgress(20);
Wallet wallet = null;
WalletManager walletMgr = WalletManager.getInstance();
@ -557,7 +557,7 @@ public class WalletService extends Service {
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification.Builder(this)
.setContentTitle(getString(R.string.service_description))
.setSmallIcon(R.drawable.ic_notification_sync_32_32)
.setSmallIcon(R.drawable.ic_monero_32dp)
.setContentIntent(pendingIntent)
.build();
startForeground(NOTIFICATION_ID, notification);

@ -21,7 +21,14 @@ import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.VectorDrawable;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
@ -91,12 +98,16 @@ public class Helper {
}
}
static public String getWalletPath(Context context, String aWalletName) {
// static public String getWalletPath(Context context, String aWalletName) {
// return getWalletFile(context, aWalletName).getAbsolutePath();
// }
static public File getWalletFile(Context context, String aWalletName) {
File walletDir = getStorageRoot(context);
//d(TAG, "walletdir=" + walletDir.getAbsolutePath());
File f = new File(walletDir, aWalletName);
Log.d(TAG, "wallet = " + f.getAbsolutePath() + " size=" + f.length());
return f.getAbsolutePath();
return f;
}
/* Checks if external storage is available for read and write */
@ -136,6 +147,7 @@ public class Helper {
return ((address.length() == 95) && ("4".indexOf(address.charAt(0)) >= 0));
}
}
static public String getDisplayAmount(long amount) {
String s = Wallet.getDisplayAmount(amount);
int lastZero = 0;
@ -152,4 +164,25 @@ public class Helper {
int cutoff = Math.max(lastZero, decimal + 2);
return s.substring(0, cutoff);
}
public static Bitmap getBitmap(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (drawable instanceof BitmapDrawable) {
return BitmapFactory.decodeResource(context.getResources(), drawableId);
} else if (drawable instanceof VectorDrawable) {
return getBitmap((VectorDrawable) drawable);
} else {
throw new IllegalArgumentException("unsupported drawable type");
}
}
private static Bitmap getBitmap(VectorDrawable vectorDrawable) {
Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vectorDrawable.draw(canvas);
return bitmap;
}
}

@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportHeight="75.0"
android:viewportWidth="75.0">
<path
android:fillColor="#ffffff"
android:pathData=" M 37.3, 37.3
m -36.9, 0
a 36.9,36.9 0 1,0 73.8,0
a 36.9,36.9 0 1,0 -73.8,0" />
<path
android:fillColor="#ff6600"
android:pathData="m 37.3,0.35329395 c -20.377,0 -36.903,16.524 -36.903,36.902 0,4.074 0.66,7.992 1.88,11.657 l 11.036,0 0,-31.049 23.987,23.987 23.987,-23.987 0,31.049 11.037,0 c 1.22,-3.665 1.88,-7.583 1.88,-11.657 0,-20.378 -16.526,-36.902 -36.904,-36.902" />
<path
android:fillColor="#4c4c4c"
android:pathData="m 21.3164,36.895994 0,19.537 -15.55,0 c 6.478,10.628 18.178,17.726 31.533,17.726 13.355,0 25.056,-7.098 31.533,-17.726 l -15.549,0 0,-19.537 -15.984,15.984 z" />
</vector>

@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="50dp"
android:height="50dp"
android:viewportHeight="75.0"
android:viewportWidth="75.0">
<path
android:fillColor="#ffffff"
android:pathData=" M 37.3, 37.3
m -36.9, 0
a 36.9,36.9 0 1,0 73.8,0
a 36.9,36.9 0 1,0 -73.8,0" />
<path
android:fillColor="#ff6600"
android:pathData="m 37.3,0.35329395 c -20.377,0 -36.903,16.524 -36.903,36.902 0,4.074 0.66,7.992 1.88,11.657 l 11.036,0 0,-31.049 23.987,23.987 23.987,-23.987 0,31.049 11.037,0 c 1.22,-3.665 1.88,-7.583 1.88,-11.657 0,-20.378 -16.526,-36.902 -36.904,-36.902" />
<path
android:fillColor="#4c4c4c"
android:pathData="m 21.3164,36.895994 0,19.537 -15.55,0 c 6.478,10.628 18.178,17.726 31.533,17.726 13.355,0 25.056,-7.098 31.533,-17.726 l -15.549,0 0,-19.537 -15.984,15.984 z" />
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tvAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4sp"
android:layout_marginTop="4sp"
android:hint="@string/send_address_hint"
android:textAlignment="center"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4sp"
android:layout_marginTop="4sp"
android:orientation="horizontal"
android:weightSum="10">
<TextView
android:layout_width="0sp"
android:layout_height="wrap_content"
android:layout_marginRight="8sp"
android:layout_weight="3"
android:text="@string/receive_paymentid_hint"
android:textAlignment="textEnd"
android:textColor="@color/colorAccent"
android:textSize="16sp" />
<EditText
android:id="@+id/etPaymentId"
android:layout_width="0sp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:hint="@string/send_paymentid_hint"
android:imeOptions="actionNext"
android:inputType="textMultiLine"
android:textAlignment="textStart"
android:textSize="16sp" />
<Button
android:id="@+id/bPaymentId"
android:layout_width="0sp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="2"
android:background="@color/colorPrimary"
android:enabled="true"
android:minHeight="36sp"
android:text="@string/receive_paymentid_button"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="4sp"
android:layout_marginTop="4sp"
android:weightSum="10">
<TextView
android:layout_width="0sp"
android:layout_height="wrap_content"
android:layout_marginRight="8sp"
android:layout_weight="3"
android:text="@string/send_amount_label"
android:textAlignment="textEnd"
android:textColor="@color/colorAccent"
android:textSize="24sp" />
<EditText
android:id="@+id/etAmount"
android:layout_width="0sp"
android:layout_height="wrap_content"
android:hint="@string/send_amount_hint"
android:imeOptions="actionNext"
android:inputType="numberDecimal"
android:layout_weight="7"
android:textAlignment="textStart"
android:textSize="24sp" />
</LinearLayout>
<Button
android:id="@+id/bGenerate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4sp"
android:layout_marginTop="4sp"
android:minHeight="36sp"
android:background="@color/colorPrimary"
android:text="@string/receive_generate_hint" />
<ImageView
android:id="@+id/qrCode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="16sp"
android:adjustViewBounds="true"
android:src="@drawable/ic_monero_32dp" />
</LinearLayout>

@ -5,4 +5,8 @@
android:id="@+id/action_info"
android:title="@string/menu_info" />
<item
android:id="@+id/action_receive"
android:title="@string/menu_receive" />
</menu>

@ -4,6 +4,7 @@
<string name="wallet_activity_name">Wallet</string>
<string name="menu_info">Details</string>
<string name="menu_receive">Receive</string>
<string name="prompt_daemon">[&lt;user&gt;:&lt;pass&gt;@]&lt;daemon&gt;[:&lt;port&gt;]</string>
<string name="prompt_mainnet">Net Selection</string>
@ -151,6 +152,10 @@
<string name="tx_pending">PENDING</string>
<string name="tx_failed">FAILED</string>
<string name="receive_generate_hint">Generate QR Code</string>
<string name="receive_paymentid_button">Generate</string>
<string name="receive_paymentid_hint">PaymentID</string>
<string name="big_amount">999999.999999999999</string>
<string-array name="mixin">