Updated on 2026-08-14

This commit is contained in:
Tangem 2018-07-20 14:48:28 +03:00
parent 7130b72624
commit c08dd3b72d
7 changed files with 233 additions and 269 deletions

View file

@ -0,0 +1,55 @@
package com.tangem;
import android.text.InputFilter;
import android.text.Spanned;
public class DecimalDigitsInputFilter implements InputFilter {
private final int decimalDigits;
/**
* Constructor.
*
* @param decimalDigits maximum decimal digits
*/
public DecimalDigitsInputFilter(int decimalDigits) {
this.decimalDigits = decimalDigits;
}
@Override
public CharSequence filter(CharSequence source,
int start,
int end,
Spanned dest,
int dstart,
int dend) {
int dotPos = -1;
int len = dest.length();
for (int i = 0; i < len; i++) {
char c = dest.charAt(i);
if (c == '.' || c == ',') {
dotPos = i;
break;
}
}
if (dotPos >= 0) {
// protects against many dots
if (source.equals(".") || source.equals(","))
{
return "";
}
// if the text is entered before the dot
if (dend <= dotPos) {
return null;
}
if (len - dotPos > decimalDigits) {
return "";
}
}
return null;
}
}

View file

@ -166,5 +166,5 @@ public class NfcManager {
);
}
}
}
}

View file

@ -31,7 +31,6 @@ import com.tangem.domain.wallet.LastSignStorage;
import com.tangem.domain.wallet.Logger;
import com.tangem.domain.wallet.PINStorage;
import com.tangem.presentation.dialog.RootFoundDialog;
import com.tangem.presentation.fragment.Main;
import com.tangem.util.CommonUtil;
import com.tangem.util.PhoneUtility;
import com.tangem.wallet.BuildConfig;
@ -138,11 +137,11 @@ public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuI
animate();
// add fragment
Main main = (Main) getSupportFragmentManager().findFragmentById(R.id.fragmentMain);
if (main.getCardListAdapter().getItemCount() > 0)
showCleanButton();
else
hideCleanButton();
// Main main = (Main) getSupportFragmentManager().findFragmentById(R.id.fragmentMain);
// if (main.getCardListAdapter().getItemCount() > 0)
// showCleanButton();
// else
// hideCleanButton();
// NFC
Intent intent = getIntent();

View file

@ -1,229 +0,0 @@
package com.tangem.presentation.activity;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Html;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.tangem.domain.cardReader.NfcManager;
import com.tangem.domain.wallet.Blockchain;
import com.tangem.domain.wallet.CoinEngine;
import com.tangem.domain.wallet.CoinEngineFactory;
import com.tangem.domain.wallet.TangemCard;
import com.tangem.util.FormatUtil;
import com.tangem.wallet.R;
import java.io.IOException;
public class PreparePaymentActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback {
public static final String TAG = PreparePaymentActivity.class.getSimpleName();
private static final int REQUEST_CODE_SCAN_QR = 1;
private static final int REQUEST_CODE_SEND_PAYMENT = 2;
private EditText etWallet;
private EditText etAmount;
// private TextView tvAmountEquivalent;
boolean use_mCurrency;
private TangemCard mCard;
private NfcManager mNfcManager;
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prepare_payment);
MainActivity.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);
mCard = new TangemCard(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
Button btnVerify = findViewById(R.id.btnVerify);
etWallet = findViewById(R.id.etWallet);
etAmount = findViewById(R.id.etAmount);
ImageView ivCamera = findViewById(R.id.ivCamera);
TextView tvCurrency = findViewById(R.id.tvCurrency);
TextView tvCardId = findViewById(R.id.tvCardID);
TextView tvBalance = findViewById(R.id.tvBalance);
// TextView tvBalanceEquivalent = findViewById(R.id.tvBalanceEquivalent);
// tvAmountEquivalent = findViewById(R.id.tvAmountEquivalent);
tvCardId.setText(mCard.getCIDDescription());
CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
if (mCard.getBlockchain() == Blockchain.Token) {
Spanned html = Html.fromHtml(engine.GetBalanceWithAlter(mCard));
tvBalance.setText(html);
} else {
tvBalance.setText(engine.GetBalanceWithAlter(mCard));
}
// tvBalanceEquivalent.setText(engine.GetBalanceEquivalent(mCard));
if (etAmount != null && mCard.getRemainingSignatures() < 2) {
etAmount.setEnabled(false);
}
// if (!mCard.getAmountEquivalentDescriptionAvailable()) {
// tvBalanceEquivalent.setError("Service unavailable");
// } else {
// tvBalanceEquivalent.setError(null);
// }
etAmount.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// try {
// CoinEngine engine = CoinEngineFactory.Create(mCard.getBlockchain());
// tvAmountEquivalent.setText(engine.GetAmountEqualentDescriptor(mCard, etAmount.getText().toString()));
// if (!mCard.getAmountEquivalentDescriptionAvailable()) {
// tvAmountEquivalent.setError("Service unavailable");
// } else {
// tvAmountEquivalent.setError(null);
// }
// } catch (Exception e) {
// e.printStackTrace();
// tvAmountEquivalent.setText("");
// }
}
@Override
public void afterTextChanged(Editable s) {
}
});
if (mCard.getBlockchain() == Blockchain.Ethereum || mCard.getBlockchain() == Blockchain.EthereumTestNet) {
tvCurrency.setText(engine.GetBalanceCurrency(mCard));
use_mCurrency = false;
etAmount.setText(engine.GetBalanceValue(mCard));
} else if (mCard.getBlockchain() == Blockchain.Bitcoin || mCard.getBlockchain() == Blockchain.BitcoinTestNet) {
Double balance = engine.GetBalanceLong(mCard) / (mCard.getBlockchain().getMultiplier() / 1000.0);
tvCurrency.setText("m" + mCard.getBlockchain().getCurrency());
use_mCurrency = true;
String output = FormatUtil.DoubleToString(balance);
etAmount.setText(output);
} else if (mCard.getBlockchain() == Blockchain.BitcoinCash || mCard.getBlockchain() == Blockchain.BitcoinCashTestNet) {
Double balance = engine.GetBalanceLong(mCard) / (mCard.getBlockchain().getMultiplier() / 1000.0);
tvCurrency.setText("m" + mCard.getBlockchain().getCurrency());
use_mCurrency = true;
String output = FormatUtil.DoubleToString(balance);
etAmount.setText(output);
} else {
tvCurrency.setText(engine.GetBalanceCurrency(mCard));
use_mCurrency = false;
etAmount.setText(engine.GetBalanceValue(mCard));
}
btnVerify.setOnClickListener(v -> {
String strAmount;
strAmount = etAmount.getText().toString().replace(",", ".");
CoinEngine engine1 = CoinEngineFactory.Create(mCard.getBlockchain());
Log.i(TAG, mCard.getBlockchain().getOfficialName());
try {
if (!engine.CheckAmount(mCard, etAmount.getText().toString())) {
etAmount.setError(getString(R.string.not_enough_funds_on_your_card));
}
} catch (Exception e) {
etAmount.setError(getString(R.string.unknown_amount_format));
return;
}
boolean checkAddress = false;
if (engine1 != null) {
checkAddress = engine1.ValdateAddress(etWallet.getText().toString(), mCard);
}
if (!checkAddress) {
etWallet.setError(getString(R.string.incorrect_destination_wallet_address));
return;
}
if (etWallet.getText().toString().equals(mCard.getWallet())) {
etWallet.setError(getString(R.string.destination_wallet_address_equal_source_address));
return;
}
Intent intent = new Intent(getBaseContext(), ConfirmPaymentActivity.class);
intent.putExtra("UID", mCard.getUID());
intent.putExtra("Card", mCard.getAsBundle());
intent.putExtra("Wallet", etWallet.getText().toString());
intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT, strAmount);
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT);
});
ivCamera.setOnClickListener(v -> {
Intent intent = new Intent(getBaseContext(), QRScanActivity.class);
startActivityForResult(intent, REQUEST_CODE_SCAN_QR);
});
}
@Override
public void onResume() {
super.onResume();
mNfcManager.onResume();
}
@Override
public void onPause() {
super.onPause();
mNfcManager.onPause();
}
@Override
public void onStop() {
super.onStop();
mNfcManager.onStop();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SCAN_QR && resultCode == Activity.RESULT_OK && data != null && data.getExtras().containsKey("QRCode")) {
String code = data.getStringExtra("QRCode");
if (code.contains("bitcoin:")) {
String tmp[] = code.split("bitcoin:");
code = tmp[1];
}
etWallet.setText(code);
} else if (requestCode == REQUEST_CODE_SEND_PAYMENT) {
setResult(resultCode, data);
finish();
}
}
@Override
public void onTagDiscovered(Tag tag) {
try {
Log.w(getClass().getName(), "Ignore discovered tag!");
mNfcManager.ignoreTag(tag);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,162 @@
package com.tangem.presentation.activity
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.text.Html
import android.text.InputFilter
import com.tangem.DecimalDigitsInputFilter
import com.tangem.domain.cardReader.NfcManager
import com.tangem.domain.wallet.Blockchain
import com.tangem.domain.wallet.CoinEngineFactory
import com.tangem.domain.wallet.TangemCard
import com.tangem.util.FormatUtil
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.activity_prepare_payment.*
import java.io.IOException
class PreparePaymentActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
companion object {
val TAG: String = PreparePaymentActivity::class.java.simpleName
private const val REQUEST_CODE_SCAN_QR = 1
private const val REQUEST_CODE_SEND_PAYMENT = 2
}
private var useCurrency: Boolean = false
private var mCard: TangemCard? = null
private var mNfcManager: NfcManager? = null
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prepare_payment)
MainActivity.commonInit(applicationContext)
mNfcManager = NfcManager(this, this)
mCard = TangemCard(intent.getStringExtra("UID"))
mCard!!.LoadFromBundle(intent.extras!!.getBundle("Card"))
tvCardID.text = mCard!!.cidDescription
val engine = CoinEngineFactory.Create(mCard!!.blockchain)
if (mCard!!.blockchain == Blockchain.Token) {
val html = Html.fromHtml(engine!!.GetBalanceWithAlter(mCard))
tvBalance.text = html
} else
tvBalance.text = engine!!.GetBalanceWithAlter(mCard)
if (mCard!!.remainingSignatures < 2)
etAmount!!.isEnabled = false
if (mCard!!.blockchain == Blockchain.Ethereum || mCard!!.blockchain == Blockchain.EthereumTestNet) {
tvCurrency.text = engine.GetBalanceCurrency(mCard)
useCurrency = false
etAmount!!.setText(engine.GetBalanceValue(mCard))
} else if (mCard!!.blockchain == Blockchain.Bitcoin || mCard!!.blockchain == Blockchain.BitcoinTestNet) {
val balance = engine.GetBalanceLong(mCard)!! / (mCard!!.blockchain.multiplier / 1000.0)
tvCurrency.text = "m" + mCard!!.blockchain.currency
useCurrency = true
val output = FormatUtil.DoubleToString(balance)
etAmount!!.setText(output)
} else if (mCard!!.blockchain == Blockchain.BitcoinCash || mCard!!.blockchain == Blockchain.BitcoinCashTestNet) {
val balance = engine.GetBalanceLong(mCard)!! / (mCard!!.blockchain.multiplier / 1000.0)
tvCurrency.text = "m" + mCard!!.blockchain.currency
useCurrency = true
val output = FormatUtil.DoubleToString(balance)
etAmount!!.setText(output)
} else {
tvCurrency.text = engine.GetBalanceCurrency(mCard)
useCurrency = false
etAmount!!.setText(engine.GetBalanceValue(mCard))
}
// set listeners
btnVerify.setOnClickListener {
val strAmount: String = etAmount!!.text.toString().replace(",", ".")
val engine1 = CoinEngineFactory.Create(mCard!!.blockchain)
try {
if (!engine.CheckAmount(mCard, etAmount!!.text.toString()))
etAmount!!.error = getString(R.string.not_enough_funds_on_your_card)
} catch (e: Exception) {
etAmount!!.error = getString(R.string.unknown_amount_format)
}
var checkAddress = false
if (engine1 != null)
checkAddress = engine1.ValdateAddress(etWallet!!.text.toString(), mCard)
if (!checkAddress)
etWallet!!.error = getString(R.string.incorrect_destination_wallet_address)
if (etWallet!!.text.toString() == mCard!!.wallet)
etWallet!!.error = getString(R.string.destination_wallet_address_equal_source_address)
val intent = Intent(baseContext, ConfirmPaymentActivity::class.java)
intent.putExtra("UID", mCard!!.uid)
intent.putExtra("Card", mCard!!.asBundle)
intent.putExtra("Wallet", etWallet!!.text.toString())
intent.putExtra(SignPaymentActivity.EXTRA_AMOUNT, strAmount)
startActivityForResult(intent, REQUEST_CODE_SEND_PAYMENT)
}
ivCamera.setOnClickListener {
val intent = Intent(baseContext, QRScanActivity::class.java)
startActivityForResult(intent, REQUEST_CODE_SCAN_QR)
}
if (mCard!!.blockchain == Blockchain.Bitcoin)
etAmount.filters = arrayOf<InputFilter>(DecimalDigitsInputFilter(5))
}
public override fun onResume() {
super.onResume()
mNfcManager!!.onResume()
}
public override fun onPause() {
super.onPause()
mNfcManager!!.onPause()
}
public override fun onStop() {
super.onStop()
mNfcManager!!.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_SCAN_QR && resultCode == Activity.RESULT_OK && data != null && data.extras!!.containsKey("QRCode")) {
var code = data.getStringExtra("QRCode")
if (code.contains("bitcoin:")) {
val tmp = code.split("bitcoin:".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
code = tmp[1]
}
etWallet!!.setText(code)
} else if (requestCode == REQUEST_CODE_SEND_PAYMENT) {
setResult(resultCode, data)
finish()
}
}
override fun onTagDiscovered(tag: Tag) {
try {
// Log.w(javaClass.name, "Ignore discovered tag!")
mNfcManager!!.ignoreTag(tag)
} catch (e: IOException) {
e.printStackTrace()
}
}
}

View file

@ -62,7 +62,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
private const val URL_CARD_VALIDATE = Server.API.Method.CARD_VALIDATE
}
private var mNfcManager: NfcManager? = null
private var nfcManager: NfcManager? = null
var mCard: TangemCard? = null
private var lastTag: Tag? = null
@ -109,7 +109,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mNfcManager = NfcManager(activity, this)
nfcManager = NfcManager(activity, this)
mCard = TangemCard(activity!!.intent.getStringExtra(TangemCard.EXTRA_CARD))
mCard!!.LoadFromBundle(activity!!.intent.extras.getBundle(TangemCard.EXTRA_CARD))
@ -223,17 +223,17 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
override fun onResume() {
super.onResume()
mNfcManager!!.onResume()
nfcManager!!.onResume()
}
override fun onPause() {
super.onPause()
mNfcManager!!.onPause()
nfcManager!!.onPause()
}
override fun onStop() {
super.onStop()
mNfcManager!!.onStop()
nfcManager!!.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -721,7 +721,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
val sUID = Util.byteArrayToHexString(uid)
if (mCard!!.uid != sUID) {
// Log.d(TAG, "Invalid UID: $sUID")
mNfcManager!!.ignoreTag(isoDep.tag)
nfcManager!!.ignoreTag(isoDep.tag)
return
} else {
// Log.v(TAG, "UID: $sUID")
@ -733,7 +733,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
isoDep.timeout = 65000
}
verifyCardTask = VerifyCardTask(context, mCard, mNfcManager, isoDep, this)
verifyCardTask = VerifyCardTask(context, mCard, nfcManager, isoDep, this)
verifyCardTask!!.start()
} catch (e: Exception) {