Updated on 2026-08-14
This commit is contained in:
parent
ad17abe440
commit
b867868273
20 changed files with 468 additions and 1118 deletions
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
|
@ -25,7 +25,7 @@
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -15,7 +15,7 @@ android {
|
||||||
applicationId "com.tangem.wallet"
|
applicationId "com.tangem.wallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
versionCode 47
|
versionCode 48
|
||||||
versionName "0.87.1." + generateVersionName()
|
versionName "0.87.1." + generateVersionName()
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
package com.tangem.data.network.task.main;
|
|
||||||
|
|
||||||
import com.tangem.data.network.request.InfuraRequest;
|
|
||||||
import com.tangem.data.network.task.InfuraTask;
|
|
||||||
import com.tangem.domain.wallet.Blockchain;
|
|
||||||
import com.tangem.domain.wallet.TangemCard;
|
|
||||||
import com.tangem.presentation.fragment.Main;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ETHRequestTask extends InfuraTask {
|
|
||||||
private WeakReference<Main> reference;
|
|
||||||
|
|
||||||
public ETHRequestTask(Main context, Blockchain blockchain) {
|
|
||||||
super(blockchain);
|
|
||||||
reference = new WeakReference<>(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FinishWithError(String wallet, String message) {
|
|
||||||
Main main = reference.get();
|
|
||||||
main.mCardListAdapter.UpdateWalletError(wallet, "Cannot obtain data from blockchain");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(List<InfuraRequest> requests) {
|
|
||||||
super.onPostExecute(requests);
|
|
||||||
Main main = reference.get();
|
|
||||||
|
|
||||||
for (InfuraRequest request : requests) {
|
|
||||||
try {
|
|
||||||
if (request.error == null) {
|
|
||||||
|
|
||||||
if (request.isMethod(InfuraRequest.METHOD_ETH_GetBalance)) {
|
|
||||||
try {
|
|
||||||
String mWalletAddress = request.getParams().getString(0);
|
|
||||||
|
|
||||||
String balanceCap = request.getResultString();
|
|
||||||
balanceCap = balanceCap.substring(2);
|
|
||||||
BigInteger l = new BigInteger(balanceCap, 16);
|
|
||||||
BigInteger d = l.divide(new BigInteger("1000000000000000000", 10));
|
|
||||||
Long balance = d.longValue();
|
|
||||||
if (request.getBlockchain() != Blockchain.Token)
|
|
||||||
main.mCardListAdapter.UpdateWalletBalance(mWalletAddress, balance, l.toString(10), getValidationNodeDescription());
|
|
||||||
main.mCardListAdapter.UpdateWalletBalanceOnlyAlter(mWalletAddress, l.toString(10));
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
}
|
|
||||||
} else if (request.isMethod(InfuraRequest.METHOD_ETH_Call)) {
|
|
||||||
try {
|
|
||||||
String mWalletAddress = request.WalletAddress;
|
|
||||||
|
|
||||||
String balanceCap = request.getResultString();
|
|
||||||
balanceCap = balanceCap.substring(2);
|
|
||||||
BigInteger l = new BigInteger(balanceCap, 16);
|
|
||||||
Long balance = l.longValue();
|
|
||||||
if (l.compareTo(BigInteger.ZERO) == 0) {
|
|
||||||
main.mCardListAdapter.UpdateWalletBlockchain(mWalletAddress, Blockchain.Ethereum);
|
|
||||||
main.mCardListAdapter.AddWalletBlockchainNameToken(mWalletAddress);
|
|
||||||
TangemCard card = main.mCardListAdapter.getCardByWallet(request.WalletAddress);
|
|
||||||
// if (card != null) {
|
|
||||||
// main.refreshCard(card);
|
|
||||||
// }
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
main.mCardListAdapter.UpdateWalletBalance(mWalletAddress, balance, l.toString(10), getValidationNodeDescription());
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
}
|
|
||||||
} else if (request.isMethod(InfuraRequest.METHOD_ETH_GetOutTransactionCount)) {
|
|
||||||
try {
|
|
||||||
String mWalletAddress = request.getParams().getString(0);
|
|
||||||
|
|
||||||
String nonce = request.getResultString();
|
|
||||||
nonce = nonce.substring(2);
|
|
||||||
BigInteger count = new BigInteger(nonce, 16);
|
|
||||||
|
|
||||||
main.mCardListAdapter.UpdateWalletCoutConfirmTx(mWalletAddress, count);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FinishWithError(request.WalletAddress, request.error);
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
package com.tangem.data.network.task.main;
|
|
||||||
|
|
||||||
import com.tangem.data.network.request.ExchangeRequest;
|
|
||||||
import com.tangem.data.network.task.ExchangeTask;
|
|
||||||
import com.tangem.presentation.fragment.Main;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class RateInfoTask extends ExchangeTask {
|
|
||||||
private WeakReference<Main> reference;
|
|
||||||
|
|
||||||
public RateInfoTask(Main context) {
|
|
||||||
reference = new WeakReference<>(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPostExecute(List<ExchangeRequest> requests) {
|
|
||||||
super.onPostExecute(requests);
|
|
||||||
Main main = reference.get();
|
|
||||||
|
|
||||||
for (ExchangeRequest request : requests) {
|
|
||||||
if (request.error == null) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
JSONArray arr = request.getAnswerList();
|
|
||||||
for (int i = 0; i < arr.length(); ++i) {
|
|
||||||
JSONObject obj = arr.getJSONObject(i);
|
|
||||||
String currency = obj.getString("id");
|
|
||||||
|
|
||||||
boolean stop = false;
|
|
||||||
boolean stopAlter = false;
|
|
||||||
if (currency.equals(request.currency)) {
|
|
||||||
String usd = obj.getString("price_usd");
|
|
||||||
|
|
||||||
Float rate = Float.valueOf(usd);
|
|
||||||
main.mCardListAdapter.UpdateRate(request.WalletAddress, rate);
|
|
||||||
stop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currency.equals(request.currencyAlter)) {
|
|
||||||
String usd = obj.getString("price_usd");
|
|
||||||
|
|
||||||
Float rate = Float.valueOf(usd);
|
|
||||||
main.mCardListAdapter.UpdateRateAlter(request.WalletAddress, rate);
|
|
||||||
stopAlter = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stop && stopAlter) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//mCardListAdapter.UpdateWalletBalance(mWalletAddress, balance, l.toString(10));
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,196 +0,0 @@
|
||||||
package com.tangem.data.network.task.main;
|
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.tangem.data.network.request.ElectrumRequest;
|
|
||||||
import com.tangem.data.network.task.ElectrumTask;
|
|
||||||
import com.tangem.domain.wallet.Blockchain;
|
|
||||||
import com.tangem.domain.wallet.CoinEngine;
|
|
||||||
import com.tangem.domain.wallet.CoinEngineFactory;
|
|
||||||
import com.tangem.domain.wallet.SharedData;
|
|
||||||
import com.tangem.presentation.fragment.Main;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class RequestWalletInfoTask extends ElectrumTask {
|
|
||||||
private WeakReference<Main> reference;
|
|
||||||
|
|
||||||
public RequestWalletInfoTask(Main context, String host, int port) {
|
|
||||||
super(host, port);
|
|
||||||
reference = new WeakReference<>(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public RequestWalletInfoTask(Main context, String host, int port, SharedData sharedData) {
|
|
||||||
super(host, port, sharedData);
|
|
||||||
reference = new WeakReference<>(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate(Integer... values) {
|
|
||||||
super.onProgressUpdate(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCancelled() {
|
|
||||||
super.onCancelled();
|
|
||||||
Main main = reference.get();
|
|
||||||
// main.requestTasks.remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FinishWithError(String wallet, String message) {
|
|
||||||
Main main = reference.get();
|
|
||||||
main.mCardListAdapter.UpdateWalletError(wallet, "Cannot obtain data from blockchain");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(List<ElectrumRequest> requests) {
|
|
||||||
super.onPostExecute(requests);
|
|
||||||
Main main = reference.get();
|
|
||||||
|
|
||||||
// main.requestTasks.remove(this);
|
|
||||||
// Log.i("RequestWalletInfoTask", "onPostExecute[" + String.valueOf(requests.size()) + "]");
|
|
||||||
|
|
||||||
CoinEngine engine = CoinEngineFactory.Create(Blockchain.Bitcoin);
|
|
||||||
|
|
||||||
for (ElectrumRequest request : requests) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
if (request.error == null) {
|
|
||||||
if (request.isMethod(ElectrumRequest.METHOD_GetBalance)) {
|
|
||||||
try {
|
|
||||||
Long conf = request.getResult().getLong("confirmed");
|
|
||||||
Long unconf = request.getResult().getLong("unconfirmed");
|
|
||||||
if (sharedCounter != null) {
|
|
||||||
int counter = sharedCounter.requestCounter.incrementAndGet();
|
|
||||||
if (counter != 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String mWalletAddress = request.getParams().getString(0);
|
|
||||||
main.mCardListAdapter.UpdateWalletBalance(mWalletAddress, conf, unconf, getValidationNodeDescription());
|
|
||||||
} catch (JSONException e) {
|
|
||||||
if (sharedCounter != null) {
|
|
||||||
int errCounter = sharedCounter.errorRequest.incrementAndGet();
|
|
||||||
if (errCounter == sharedCounter.allRequest) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (request.isMethod(ElectrumRequest.METHOD_ListUnspent)) {
|
|
||||||
try {
|
|
||||||
String mWalletAddress = request.getParams().getString(0);
|
|
||||||
main.mCardListAdapter.UpdateWalletUnspent(mWalletAddress, request.getResultArray());
|
|
||||||
|
|
||||||
JSONArray unspentList = request.getResultArray();
|
|
||||||
|
|
||||||
for (int i = 0; i < unspentList.length(); i++) {
|
|
||||||
JSONObject jsUnspent = unspentList.getJSONObject(i);
|
|
||||||
Integer height = jsUnspent.getInt("height");
|
|
||||||
String hash = jsUnspent.getString("tx_hash");
|
|
||||||
if (height != -1) {
|
|
||||||
RequestWalletInfoTask task = new RequestWalletInfoTask(main, request.Host, request.Port);
|
|
||||||
// main.requestTasks.add(task);
|
|
||||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.GetHeader(mWalletAddress, String.valueOf(height)),
|
|
||||||
ElectrumRequest.GetTransaction(mWalletAddress, hash));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
} else if (request.isMethod(ElectrumRequest.METHOD_GetHistory)) {
|
|
||||||
try {
|
|
||||||
String mWalletAddress = request.getParams().getString(0);
|
|
||||||
main.mCardListAdapter.UpdateWalletHistory(mWalletAddress, request.getResultArray());
|
|
||||||
|
|
||||||
JSONArray historyList = request.getResultArray();
|
|
||||||
|
|
||||||
for (int i = 0; i < historyList.length(); i++) {
|
|
||||||
JSONObject jsUnspent = historyList.getJSONObject(i);
|
|
||||||
Integer height = jsUnspent.getInt("height");
|
|
||||||
String hash = jsUnspent.getString("tx_hash");
|
|
||||||
if (height != -1) {
|
|
||||||
RequestWalletInfoTask task = new RequestWalletInfoTask(main, request.Host, request.Port);
|
|
||||||
// main.requestTasks.add(task);
|
|
||||||
|
|
||||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ElectrumRequest.GetHeader(mWalletAddress, String.valueOf(height)),
|
|
||||||
ElectrumRequest.GetTransaction(mWalletAddress, hash));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
} else if (request.isMethod(ElectrumRequest.METHOD_GetHeader)) {
|
|
||||||
try {
|
|
||||||
String mWalletAddress = request.WalletAddress;
|
|
||||||
|
|
||||||
main.mCardListAdapter.UpdateWalletHeader(mWalletAddress, request.getResult());
|
|
||||||
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
} else if (request.isMethod(ElectrumRequest.METHOD_GetTransaction)) {
|
|
||||||
try {
|
|
||||||
Log.e("MainActivityFragment_TX", request.TxHash);
|
|
||||||
String mWalletAddress = request.WalletAddress;
|
|
||||||
String tx = request.TxHash;
|
|
||||||
String raw = request.getResultString();
|
|
||||||
Log.e("MainActivityFragment_R", raw);
|
|
||||||
main.mCardListAdapter.UpdateTransaction(mWalletAddress, tx, raw);
|
|
||||||
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
main.mCardListAdapter.UpdateWalletError(request.WalletAddress, "Cannot obtain data from blockchain");
|
|
||||||
FinishWithError(request.WalletAddress, e.toString());
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (sharedCounter != null) {
|
|
||||||
int errCounter = sharedCounter.errorRequest.incrementAndGet();
|
|
||||||
if (errCounter >= sharedCounter.allRequest) {
|
|
||||||
FinishWithError(request.WalletAddress, request.error);
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FinishWithError(request.WalletAddress, request.error);
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
if (sharedCounter != null) {
|
|
||||||
int errCounter = sharedCounter.errorRequest.incrementAndGet();
|
|
||||||
if (errCounter >= sharedCounter.allRequest) {
|
|
||||||
e.printStackTrace();
|
|
||||||
main.mCardListAdapter.UpdateWalletError(request.WalletAddress, "Cannot obtain data from blockchain");
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e.printStackTrace();
|
|
||||||
main.mCardListAdapter.UpdateWalletError(request.WalletAddress, "Cannot obtain data from blockchain");
|
|
||||||
engine.SwitchNode(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -78,7 +78,7 @@ public class ConfirmPaymentActivity extends AppCompatActivity implements NfcAdap
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_confirm_payment);
|
setContentView(R.layout.activity_confirm_payment);
|
||||||
|
|
||||||
MainActivity.commonInit(getApplicationContext());
|
MainActivity.Companion.commonInit(getApplicationContext());
|
||||||
mNfcManager = new NfcManager(this, this);
|
mNfcManager = new NfcManager(this, this);
|
||||||
|
|
||||||
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public class CreateNewWalletActivity extends AppCompatActivity implements NfcAda
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_create_new_wallet);
|
setContentView(R.layout.activity_create_new_wallet);
|
||||||
|
|
||||||
MainActivity.commonInit(getApplicationContext());
|
MainActivity.Companion.commonInit(getApplicationContext());
|
||||||
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
||||||
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
|
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ public class EmptyWalletActivity extends AppCompatActivity implements NfcAdapter
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_empty_wallet);
|
setContentView(R.layout.activity_empty_wallet);
|
||||||
|
|
||||||
MainActivity.commonInit(getApplicationContext());
|
MainActivity.Companion.commonInit(getApplicationContext());
|
||||||
mNfcManager = new NfcManager(this, this);
|
mNfcManager = new NfcManager(this, this);
|
||||||
|
|
||||||
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
||||||
|
|
|
||||||
|
|
@ -1,306 +0,0 @@
|
||||||
package com.tangem.presentation.activity;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ActivityInfo;
|
|
||||||
import android.nfc.NfcAdapter;
|
|
||||||
import android.nfc.Tag;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.design.widget.FloatingActionButton;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.support.v7.widget.PopupMenu;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.DecelerateInterpolator;
|
|
||||||
import android.view.animation.Transformation;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.scottyab.rootbeer.RootBeer;
|
|
||||||
import com.skyfishjy.library.RippleBackground;
|
|
||||||
import com.tangem.domain.cardReader.FW;
|
|
||||||
import com.tangem.domain.wallet.DeviceNFCAntennaLocation;
|
|
||||||
import com.tangem.domain.wallet.Issuer;
|
|
||||||
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.util.CommonUtil;
|
|
||||||
import com.tangem.util.PhoneUtility;
|
|
||||||
import com.tangem.wallet.BuildConfig;
|
|
||||||
import com.tangem.wallet.R;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
|
|
||||||
public static final String TAG = MainActivity.class.getSimpleName();
|
|
||||||
|
|
||||||
private static final int REQUEST_CODE_SEND_EMAIL = 2;
|
|
||||||
|
|
||||||
private File zipFile = null;
|
|
||||||
private NfcAdapter.ReaderCallback onNFCReaderCallback;
|
|
||||||
private OnCardsClean onCardsClean;
|
|
||||||
private LinearLayout llTapPrompt;
|
|
||||||
private DeviceNFCAntennaLocation antenna;
|
|
||||||
private LinearLayout nfc;
|
|
||||||
private LinearLayout llHand;
|
|
||||||
|
|
||||||
public interface OnCardsClean {
|
|
||||||
void doClean();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnCardsClean(OnCardsClean onCardsClean) {
|
|
||||||
this.onCardsClean = onCardsClean;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNfcAdapterReaderCallback(NfcAdapter.ReaderCallback callback) {
|
|
||||||
onNFCReaderCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onNewIntent(Intent intent) {
|
|
||||||
super.onNewIntent(intent);
|
|
||||||
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))) {
|
|
||||||
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
|
||||||
if (tag != null && onNFCReaderCallback != null) {
|
|
||||||
onNFCReaderCallback.onTagDiscovered(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_main);
|
|
||||||
|
|
||||||
TextView tvNFCHint = findViewById(R.id.tvNFCHint);
|
|
||||||
llTapPrompt = findViewById(R.id.llTapPrompt);
|
|
||||||
llHand = findViewById(R.id.llHand);
|
|
||||||
ImageView ivHandCardHorizontal = findViewById(R.id.ivHandCardHorizontal);
|
|
||||||
ImageView ivHandCardVertical = findViewById(R.id.ivHandCardVertical);
|
|
||||||
nfc = findViewById(R.id.llNFC);
|
|
||||||
RippleBackground rippleBackground = findViewById(R.id.imNFC);
|
|
||||||
FloatingActionButton fab = findViewById(R.id.fab);
|
|
||||||
|
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
|
|
||||||
|
|
||||||
commonInit(getApplicationContext());
|
|
||||||
|
|
||||||
rippleBackground.startRippleAnimation();
|
|
||||||
|
|
||||||
antenna = new DeviceNFCAntennaLocation();
|
|
||||||
antenna.getAntennaLocation();
|
|
||||||
|
|
||||||
// set card orientation
|
|
||||||
switch (antenna.getOrientation()) {
|
|
||||||
case DeviceNFCAntennaLocation.CARD_ORIENTATION_HORIZONTAL:
|
|
||||||
ivHandCardHorizontal.setVisibility(View.VISIBLE);
|
|
||||||
ivHandCardVertical.setVisibility(View.GONE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DeviceNFCAntennaLocation.CARD_ORIENTATION_VERTICAL:
|
|
||||||
ivHandCardVertical.setVisibility(View.VISIBLE);
|
|
||||||
ivHandCardHorizontal.setVisibility(View.GONE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set card z position
|
|
||||||
switch (antenna.getZ()) {
|
|
||||||
case DeviceNFCAntennaLocation.CARD_ON_BACK:
|
|
||||||
llHand.setElevation(0.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DeviceNFCAntennaLocation.CARD_ON_FRONT:
|
|
||||||
llHand.setElevation(30.0f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set phone name
|
|
||||||
if (!antenna.getFullName().equals(""))
|
|
||||||
tvNFCHint.setText(String.format(getString(R.string.scan_banknote), antenna.getFullName()));
|
|
||||||
else
|
|
||||||
tvNFCHint.setText(String.format(getString(R.string.scan_banknote), getString(R.string.phone)));
|
|
||||||
|
|
||||||
animate();
|
|
||||||
|
|
||||||
// add fragment
|
|
||||||
// Main main = (Main) getSupportFragmentManager().findFragmentById(R.id.fragmentMain);
|
|
||||||
// if (main.getCardListAdapter().getItemCount() > 0)
|
|
||||||
// showCleanButton();
|
|
||||||
// else
|
|
||||||
// hideCleanButton();
|
|
||||||
|
|
||||||
// NFC
|
|
||||||
Intent intent = getIntent();
|
|
||||||
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))) {
|
|
||||||
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
|
||||||
if (tag != null && onNFCReaderCallback != null) {
|
|
||||||
onNFCReaderCallback.onTagDiscovered(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if root device
|
|
||||||
RootBeer rootBeer = new RootBeer(this);
|
|
||||||
if (rootBeer.isRootedWithoutBusyBoxCheck() && !BuildConfig.DEBUG)
|
|
||||||
new RootFoundDialog().show(getFragmentManager(), RootFoundDialog.TAG);
|
|
||||||
|
|
||||||
// set listeners
|
|
||||||
fab.setOnClickListener(this::showMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
animate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
if (requestCode == REQUEST_CODE_SEND_EMAIL) {
|
|
||||||
if (zipFile != null) {
|
|
||||||
zipFile.delete();
|
|
||||||
zipFile = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
|
||||||
return onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
for (int i = 0; i < menu.size(); i++) menu.getItem(i).setVisible(true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
int id = item.getItemId();
|
|
||||||
|
|
||||||
// noinspection SimplifiableIfStatement
|
|
||||||
switch (id) {
|
|
||||||
case R.id.sendLogs:
|
|
||||||
File f = null;
|
|
||||||
try {
|
|
||||||
f = Logger.collectLogs(this);
|
|
||||||
if (f != null) {
|
|
||||||
// Log.e(TAG, String.format("Collect %d log bytes", f.length()));
|
|
||||||
CommonUtil.sendEmail(this, zipFile, TAG, "Logs", PhoneUtility.getDeviceInfo(), new File[]{f});
|
|
||||||
} else {
|
|
||||||
// Log.e(TAG, "Can't create temporaly log file");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
if (f != null && f.exists()) {
|
|
||||||
f.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case R.id.managePIN:
|
|
||||||
showSavePinActivity();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case R.id.managePIN2:
|
|
||||||
showSavePin2Activity();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case R.id.cleanCards:
|
|
||||||
onCardsClean.doClean();
|
|
||||||
hideCleanButton();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case R.id.about:
|
|
||||||
showLogoActivity();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void commonInit(Context context) {
|
|
||||||
if (PINStorage.needInit()) {
|
|
||||||
PINStorage.Init(context);
|
|
||||||
}
|
|
||||||
if (LastSignStorage.needInit()) {
|
|
||||||
LastSignStorage.Init(context);
|
|
||||||
}
|
|
||||||
if (Issuer.needInit()) Issuer.Init(context);
|
|
||||||
if (FW.needInit()) FW.Init(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showCleanButton() {
|
|
||||||
llTapPrompt.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void hideCleanButton() {
|
|
||||||
llTapPrompt.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showLogoActivity() {
|
|
||||||
Intent intent = new Intent(getBaseContext(), LogoActivity.class);
|
|
||||||
intent.putExtra(LogoActivity.Companion.getTAG(), true);
|
|
||||||
intent.putExtra(LogoActivity.EXTRA_AUTO_HIDE, false);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void animate() {
|
|
||||||
final RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) llHand.getLayoutParams();
|
|
||||||
final RelativeLayout.LayoutParams lp2 = (RelativeLayout.LayoutParams) nfc.getLayoutParams();
|
|
||||||
final float dp = getResources().getDisplayMetrics().density;
|
|
||||||
final float lm = dp * (69 + antenna.getX() * 75);
|
|
||||||
lp.topMargin = (int) (dp * (-100 + antenna.getY() * 250));
|
|
||||||
lp2.topMargin = (int) (dp * (-125 + antenna.getY() * 250));
|
|
||||||
nfc.setLayoutParams(lp2);
|
|
||||||
|
|
||||||
Animation a = new Animation() {
|
|
||||||
@Override
|
|
||||||
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
|
||||||
lp.leftMargin = (int) (lm * interpolatedTime);
|
|
||||||
llHand.setLayoutParams(lp);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
a.setDuration(2000);
|
|
||||||
a.setInterpolator(new DecelerateInterpolator());
|
|
||||||
llHand.startAnimation(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showSavePinActivity() {
|
|
||||||
Intent intent = new Intent(getBaseContext(), SavePINActivity.class);
|
|
||||||
intent.putExtra("PIN2", false);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showSavePin2Activity() {
|
|
||||||
Intent intent = new Intent(getBaseContext(), SavePINActivity.class);
|
|
||||||
intent.putExtra("PIN2", true);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showMenu(View v) {
|
|
||||||
PopupMenu popup = new PopupMenu(this, v);
|
|
||||||
MenuInflater inflater = popup.getMenuInflater();
|
|
||||||
inflater.inflate(R.menu.menu_main, popup.getMenu());
|
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
popup.getMenu().findItem(R.id.managePIN).setEnabled(true);
|
|
||||||
popup.getMenu().findItem(R.id.managePIN2).setEnabled(true);
|
|
||||||
popup.getMenu().findItem(R.id.sendLogs).setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.setOnMenuItemClickListener(this);
|
|
||||||
popup.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,426 @@
|
||||||
|
package com.tangem.presentation.activity
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.nfc.NfcAdapter
|
||||||
|
import android.nfc.Tag
|
||||||
|
import android.nfc.tech.IsoDep
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
|
import android.support.v7.widget.PopupMenu
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import android.view.animation.Animation
|
||||||
|
import android.view.animation.DecelerateInterpolator
|
||||||
|
import android.view.animation.Transformation
|
||||||
|
import android.widget.RelativeLayout
|
||||||
|
import android.widget.Toast
|
||||||
|
import com.scottyab.rootbeer.RootBeer
|
||||||
|
import com.tangem.data.nfc.ReadCardInfoTask
|
||||||
|
import com.tangem.domain.cardReader.CardProtocol
|
||||||
|
import com.tangem.domain.cardReader.FW
|
||||||
|
import com.tangem.domain.cardReader.NfcManager
|
||||||
|
import com.tangem.domain.wallet.*
|
||||||
|
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog
|
||||||
|
import com.tangem.presentation.dialog.RootFoundDialog
|
||||||
|
import com.tangem.presentation.dialog.WaitSecurityDelayDialog
|
||||||
|
import com.tangem.util.CommonUtil
|
||||||
|
import com.tangem.util.PhoneUtility
|
||||||
|
import com.tangem.wallet.BuildConfig
|
||||||
|
import com.tangem.wallet.R
|
||||||
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, PopupMenu.OnMenuItemClickListener {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TAG: String = MainActivity::class.java.simpleName
|
||||||
|
|
||||||
|
private const val REQUEST_CODE_SEND_EMAIL = 3
|
||||||
|
private const val REQUEST_CODE_ENTER_PIN_ACTIVITY = 2
|
||||||
|
private const val REQUEST_CODE_SHOW_CARD_ACTIVITY = 1
|
||||||
|
|
||||||
|
const val EXTRA_LAST_DISCOVERED_TAG = "extra_last_tag"
|
||||||
|
|
||||||
|
fun commonInit(context: Context) {
|
||||||
|
if (PINStorage.needInit())
|
||||||
|
PINStorage.Init(context)
|
||||||
|
|
||||||
|
if (LastSignStorage.needInit())
|
||||||
|
LastSignStorage.Init(context)
|
||||||
|
|
||||||
|
if (Issuer.needInit())
|
||||||
|
Issuer.Init(context)
|
||||||
|
|
||||||
|
if (FW.needInit())
|
||||||
|
FW.Init(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var zipFile: File? = null
|
||||||
|
private val onNFCReaderCallback: NfcAdapter.ReaderCallback? = null
|
||||||
|
private val onCardsClean: OnCardsClean? = null
|
||||||
|
private var antenna: DeviceNFCAntennaLocation? = null
|
||||||
|
private var mNfcManager: NfcManager? = null
|
||||||
|
private var readCardInfoTask: ReadCardInfoTask? = null
|
||||||
|
private var unsuccessReadCount = 0
|
||||||
|
private var lastTag: Tag? = null
|
||||||
|
|
||||||
|
override fun onNewIntent(intent: Intent?) {
|
||||||
|
super.onNewIntent(intent)
|
||||||
|
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action || NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action)) {
|
||||||
|
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
|
||||||
|
if (tag != null && onNFCReaderCallback != null)
|
||||||
|
onNFCReaderCallback.onTagDiscovered(tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
mNfcManager = NfcManager(this, this)
|
||||||
|
|
||||||
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
||||||
|
|
||||||
|
commonInit(applicationContext)
|
||||||
|
|
||||||
|
rippleBackgroundNfc.startRippleAnimation()
|
||||||
|
|
||||||
|
antenna = DeviceNFCAntennaLocation()
|
||||||
|
antenna!!.getAntennaLocation()
|
||||||
|
|
||||||
|
// set card orientation
|
||||||
|
when (antenna!!.orientation) {
|
||||||
|
DeviceNFCAntennaLocation.CARD_ORIENTATION_HORIZONTAL -> {
|
||||||
|
ivHandCardHorizontal.visibility = View.VISIBLE
|
||||||
|
ivHandCardVertical.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceNFCAntennaLocation.CARD_ORIENTATION_VERTICAL -> {
|
||||||
|
ivHandCardVertical.visibility = View.VISIBLE
|
||||||
|
ivHandCardHorizontal.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set card z position
|
||||||
|
when (antenna!!.z) {
|
||||||
|
DeviceNFCAntennaLocation.CARD_ON_BACK -> llHand.elevation = 0.0f
|
||||||
|
DeviceNFCAntennaLocation.CARD_ON_FRONT -> llHand.elevation = 30.0f
|
||||||
|
}
|
||||||
|
|
||||||
|
// set phone name
|
||||||
|
if (antenna!!.fullName != "")
|
||||||
|
tvNFCHint.text = String.format(getString(R.string.scan_banknote), antenna!!.fullName)
|
||||||
|
else
|
||||||
|
tvNFCHint.text = String.format(getString(R.string.scan_banknote), getString(R.string.phone))
|
||||||
|
|
||||||
|
animate()
|
||||||
|
|
||||||
|
// NFC
|
||||||
|
val intent = intent
|
||||||
|
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action || NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action)) {
|
||||||
|
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
|
||||||
|
if (tag != null && onNFCReaderCallback != null) {
|
||||||
|
onNFCReaderCallback.onTagDiscovered(tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if root device
|
||||||
|
val rootBeer = RootBeer(this)
|
||||||
|
if (rootBeer.isRootedWithoutBusyBoxCheck && !BuildConfig.DEBUG)
|
||||||
|
RootFoundDialog().show(fragmentManager, RootFoundDialog.TAG)
|
||||||
|
|
||||||
|
// set listeners
|
||||||
|
fab.setOnClickListener { this.showMenu(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
|
||||||
|
if (requestCode == REQUEST_CODE_SEND_EMAIL) {
|
||||||
|
if (zipFile != null) {
|
||||||
|
zipFile!!.delete()
|
||||||
|
zipFile = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestCode == REQUEST_CODE_ENTER_PIN_ACTIVITY) {
|
||||||
|
if (resultCode == Activity.RESULT_OK && lastTag != null) {
|
||||||
|
onTagDiscovered(lastTag!!)
|
||||||
|
} else {
|
||||||
|
ReadCardInfoTask.resetLastReadInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||||
|
return onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
menuInflater.inflate(R.menu.menu_main, menu)
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
for (i in 0 until menu.size()) menu.getItem(i).isVisible = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
val id = item.itemId
|
||||||
|
|
||||||
|
when (id) {
|
||||||
|
R.id.sendLogs -> {
|
||||||
|
var f: File? = null
|
||||||
|
try {
|
||||||
|
f = Logger.collectLogs(this)
|
||||||
|
if (f != null) {
|
||||||
|
// Log.e(TAG, String.format("Collect %d log bytes", f.length()));
|
||||||
|
CommonUtil.sendEmail(this, zipFile, TAG, "Logs", PhoneUtility.getDeviceInfo(), arrayOf(f))
|
||||||
|
} else {
|
||||||
|
// Log.e(TAG, "Can't create temporaly log file");
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
if (f != null && f.exists())
|
||||||
|
f.delete()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.managePIN -> {
|
||||||
|
showSavePinActivity()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.managePIN2 -> {
|
||||||
|
showSavePin2Activity()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.cleanCards -> {
|
||||||
|
onCardsClean!!.doClean()
|
||||||
|
llTapPrompt.visibility = View.VISIBLE
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.about -> {
|
||||||
|
showLogoActivity()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTagDiscovered(tag: Tag) {
|
||||||
|
try {
|
||||||
|
// get IsoDep handle and run cardReader thread
|
||||||
|
val isoDep = IsoDep.get(tag)
|
||||||
|
?: throw CardProtocol.TangemException(getString(R.string.wrong_tag_err))
|
||||||
|
|
||||||
|
// Log.e(TAG, "setTimeout(" + String.valueOf(1000 + 3000 * unsuccessReadCount) + ")");
|
||||||
|
if (unsuccessReadCount < 2) {
|
||||||
|
isoDep.timeout = 2000 + 5000 * unsuccessReadCount
|
||||||
|
} else {
|
||||||
|
isoDep.timeout = 90000
|
||||||
|
}
|
||||||
|
lastTag = tag
|
||||||
|
|
||||||
|
readCardInfoTask = ReadCardInfoTask(this, mNfcManager, isoDep, this)
|
||||||
|
readCardInfoTask!!.start()
|
||||||
|
|
||||||
|
// Log.i(TAG, "onTagDiscovered " + Arrays.toString(tag.getId()));
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
mNfcManager!!.notifyReadResult(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
animate()
|
||||||
|
ReadCardInfoTask.resetLastReadInfo()
|
||||||
|
mNfcManager!!.onResume()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun onPause() {
|
||||||
|
mNfcManager!!.onPause()
|
||||||
|
if (readCardInfoTask != null) {
|
||||||
|
readCardInfoTask!!.cancel(true)
|
||||||
|
}
|
||||||
|
super.onPause()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun onStop() {
|
||||||
|
// dismiss enable NFC dialog
|
||||||
|
mNfcManager!!.onStop()
|
||||||
|
if (readCardInfoTask != null) {
|
||||||
|
readCardInfoTask!!.cancel(true)
|
||||||
|
}
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnReadStart(cardProtocol: CardProtocol) {
|
||||||
|
rlProgressBar.post { rlProgressBar.visibility = View.VISIBLE }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnReadProgress(protocol: CardProtocol, progress: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnReadFinish(cardProtocol: CardProtocol?) {
|
||||||
|
readCardInfoTask = null
|
||||||
|
if (cardProtocol != null) {
|
||||||
|
if (cardProtocol.error == null) {
|
||||||
|
mNfcManager!!.notifyReadResult(true)
|
||||||
|
rlProgressBar.post {
|
||||||
|
rlProgressBar.visibility = View.GONE
|
||||||
|
|
||||||
|
val cardInfo = Bundle()
|
||||||
|
cardInfo.putString("UID", cardProtocol.card.uid)
|
||||||
|
val bCard = Bundle()
|
||||||
|
cardProtocol.card.SaveToBundle(bCard)
|
||||||
|
cardInfo.putBundle("Card", bCard)
|
||||||
|
|
||||||
|
val uid = cardInfo.getString("UID")
|
||||||
|
val card = TangemCard(uid)
|
||||||
|
card.LoadFromBundle(cardInfo.getBundle("Card"))
|
||||||
|
|
||||||
|
val intent: Intent
|
||||||
|
intent = if (card.status == TangemCard.Status.Empty)
|
||||||
|
Intent(this, EmptyWalletActivity::class.java)
|
||||||
|
else if (card.status == TangemCard.Status.Loaded)
|
||||||
|
Intent(this, LoadedWalletActivity::class.java)
|
||||||
|
else if (card.status == TangemCard.Status.NotPersonalized || card.status == TangemCard.Status.Purged)
|
||||||
|
return@post
|
||||||
|
else
|
||||||
|
Intent(this, LoadedWalletActivity::class.java)
|
||||||
|
|
||||||
|
intent.putExtra(EXTRA_LAST_DISCOVERED_TAG, lastTag)
|
||||||
|
intent.putExtras(cardInfo)
|
||||||
|
startActivityForResult(intent, REQUEST_CODE_SHOW_CARD_ACTIVITY)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// remove last UIDs because of error and no card read
|
||||||
|
rlProgressBar.post {
|
||||||
|
Toast.makeText(this, R.string.try_to_scan_again, Toast.LENGTH_SHORT).show()
|
||||||
|
unsuccessReadCount++
|
||||||
|
|
||||||
|
if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN)
|
||||||
|
doEnterPIN()
|
||||||
|
else {
|
||||||
|
if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported)
|
||||||
|
if (!NoExtendedLengthSupportDialog.allReadyShowed)
|
||||||
|
NoExtendedLengthSupportDialog().show(fragmentManager, NoExtendedLengthSupportDialog.TAG)
|
||||||
|
|
||||||
|
lastTag = null
|
||||||
|
ReadCardInfoTask.resetLastReadInfo()
|
||||||
|
mNfcManager!!.notifyReadResult(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rlProgressBar.postDelayed({
|
||||||
|
try {
|
||||||
|
rlProgressBar.visibility = View.GONE
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnReadCancel() {
|
||||||
|
readCardInfoTask = null
|
||||||
|
ReadCardInfoTask.resetLastReadInfo()
|
||||||
|
rlProgressBar.postDelayed({
|
||||||
|
try {
|
||||||
|
rlProgressBar.visibility = View.GONE
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnReadWait(msec: Int) {
|
||||||
|
WaitSecurityDelayDialog.OnReadWait(Objects.requireNonNull(this), msec)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnReadBeforeRequest(timeout: Int) {
|
||||||
|
WaitSecurityDelayDialog.onReadBeforeRequest(Objects.requireNonNull(this), timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun OnReadAfterRequest() {
|
||||||
|
WaitSecurityDelayDialog.onReadAfterRequest(Objects.requireNonNull(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OnCardsClean {
|
||||||
|
fun doClean()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showLogoActivity() {
|
||||||
|
val intent = Intent(baseContext, LogoActivity::class.java)
|
||||||
|
intent.putExtra(LogoActivity.TAG, true)
|
||||||
|
intent.putExtra(LogoActivity.EXTRA_AUTO_HIDE, false)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun animate() {
|
||||||
|
val lp = llHand.layoutParams as RelativeLayout.LayoutParams
|
||||||
|
val lp2 = llNfc.layoutParams as RelativeLayout.LayoutParams
|
||||||
|
val dp = resources.displayMetrics.density
|
||||||
|
val lm = dp * (69 + antenna!!.x * 75)
|
||||||
|
lp.topMargin = (dp * (-100 + antenna!!.y * 250)).toInt()
|
||||||
|
lp2.topMargin = (dp * (-125 + antenna!!.y * 250)).toInt()
|
||||||
|
llNfc.layoutParams = lp2
|
||||||
|
|
||||||
|
val a = object : Animation() {
|
||||||
|
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
|
||||||
|
lp.leftMargin = (lm * interpolatedTime).toInt()
|
||||||
|
llHand.layoutParams = lp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a.duration = 2000
|
||||||
|
a.interpolator = DecelerateInterpolator()
|
||||||
|
llHand.startAnimation(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showSavePinActivity() {
|
||||||
|
val intent = Intent(baseContext, SavePINActivity::class.java)
|
||||||
|
intent.putExtra("PIN2", false)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showSavePin2Activity() {
|
||||||
|
val intent = Intent(baseContext, SavePINActivity::class.java)
|
||||||
|
intent.putExtra("PIN2", true)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showMenu(v: View) {
|
||||||
|
val popup = PopupMenu(this, v)
|
||||||
|
val inflater = popup.menuInflater
|
||||||
|
inflater.inflate(R.menu.menu_main, popup.menu)
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
popup.menu.findItem(R.id.managePIN).isEnabled = true
|
||||||
|
popup.menu.findItem(R.id.managePIN2).isEnabled = true
|
||||||
|
popup.menu.findItem(R.id.sendLogs).isVisible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.setOnMenuItemClickListener(this)
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doEnterPIN() {
|
||||||
|
val intent = Intent(this, RequestPINActivity::class.java)
|
||||||
|
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN.toString())
|
||||||
|
startActivityForResult(intent, REQUEST_CODE_ENTER_PIN_ACTIVITY)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -124,7 +124,7 @@ public class PurgeActivity extends AppCompatActivity implements NfcAdapter.Reade
|
||||||
|
|
||||||
mNfcManager = new NfcManager(this, this);
|
mNfcManager = new NfcManager(this, this);
|
||||||
|
|
||||||
MainActivity.commonInit(getApplicationContext());
|
MainActivity.Companion.commonInit(getApplicationContext());
|
||||||
|
|
||||||
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
||||||
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
|
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ public class RequestPINActivity extends AppCompatActivity implements NfcAdapter.
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_request_pin);
|
setContentView(R.layout.activity_request_pin);
|
||||||
|
|
||||||
MainActivity.commonInit(getApplicationContext());
|
MainActivity.Companion.commonInit(getApplicationContext());
|
||||||
|
|
||||||
mNfcManager = new NfcManager(this, this);
|
mNfcManager = new NfcManager(this, this);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public class SavePINActivity extends AppCompatActivity implements FingerprintHel
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_save_pin);
|
setContentView(R.layout.activity_save_pin);
|
||||||
|
|
||||||
MainActivity.commonInit(getApplicationContext());
|
MainActivity.Companion.commonInit(getApplicationContext());
|
||||||
|
|
||||||
UsePIN2 = getIntent().getBooleanExtra("PIN2", false);
|
UsePIN2 = getIntent().getBooleanExtra("PIN2", false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ public class SendTransactionActivity extends AppCompatActivity {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_send_transaction);
|
setContentView(R.layout.activity_send_transaction);
|
||||||
|
|
||||||
MainActivity.commonInit(getApplicationContext());
|
MainActivity.Companion.commonInit(getApplicationContext());
|
||||||
|
|
||||||
progressBar = findViewById(R.id.progressBar);
|
progressBar = findViewById(R.id.progressBar);
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -40,7 +40,7 @@ public class SwapPINActivity extends AppCompatActivity implements NfcAdapter.Rea
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_swap_pin);
|
setContentView(R.layout.activity_swap_pin);
|
||||||
|
|
||||||
MainActivity.commonInit(getApplicationContext());
|
MainActivity.Companion.commonInit(getApplicationContext());
|
||||||
|
|
||||||
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
mCard = new TangemCard(getIntent().getStringExtra("UID"));
|
||||||
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
|
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
|
||||||
mCard = TangemCard(activity!!.intent.getStringExtra(TangemCard.EXTRA_CARD))
|
mCard = TangemCard(activity!!.intent.getStringExtra(TangemCard.EXTRA_CARD))
|
||||||
mCard!!.LoadFromBundle(activity!!.intent.extras.getBundle(TangemCard.EXTRA_CARD))
|
mCard!!.LoadFromBundle(activity!!.intent.extras.getBundle(TangemCard.EXTRA_CARD))
|
||||||
|
|
||||||
lastTag = activity!!.intent.getParcelableExtra(Main.EXTRA_LAST_DISCOVERED_TAG)
|
lastTag = activity!!.intent.getParcelableExtra(MainActivity.EXTRA_LAST_DISCOVERED_TAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
|
|
||||||
|
|
@ -1,386 +0,0 @@
|
||||||
package com.tangem.presentation.fragment;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.nfc.NfcAdapter;
|
|
||||||
import android.nfc.Tag;
|
|
||||||
import android.nfc.tech.IsoDep;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.v4.app.ActivityCompat;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.support.v7.widget.helper.ItemTouchHelper;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.tangem.data.nfc.ReadCardInfoTask;
|
|
||||||
import com.tangem.domain.cardReader.CardProtocol;
|
|
||||||
import com.tangem.domain.cardReader.NfcManager;
|
|
||||||
import com.tangem.domain.wallet.TangemCard;
|
|
||||||
import com.tangem.presentation.activity.EmptyWalletActivity;
|
|
||||||
import com.tangem.presentation.activity.LoadedWalletActivity;
|
|
||||||
import com.tangem.presentation.activity.MainActivity;
|
|
||||||
import com.tangem.presentation.activity.RequestPINActivity;
|
|
||||||
import com.tangem.presentation.adapter.CardListAdapter;
|
|
||||||
import com.tangem.presentation.dialog.NoExtendedLengthSupportDialog;
|
|
||||||
import com.tangem.presentation.dialog.WaitSecurityDelayDialog;
|
|
||||||
import com.tangem.util.Util;
|
|
||||||
import com.tangem.wallet.R;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A placeholder fragment containing a simple view.
|
|
||||||
*/
|
|
||||||
public class Main extends Fragment implements NfcAdapter.ReaderCallback, CardListAdapter.UiCallbacks, CardProtocol.Notifications, MainActivity.OnCardsClean {
|
|
||||||
public static final String TAG = Main.class.getSimpleName();
|
|
||||||
|
|
||||||
public static final String EXTRA_LAST_DISCOVERED_TAG = "extra_last_tag";
|
|
||||||
|
|
||||||
private static final int REQUEST_CODE_SHOW_CARD_ACTIVITY = 1;
|
|
||||||
private static final int REQUEST_CODE_ENTER_PIN_ACTIVITY = 2;
|
|
||||||
private static final int REQUEST_CODE_REQUEST_CAMERA_PERMISSIONS = 3;
|
|
||||||
|
|
||||||
private NfcManager mNfcManager;
|
|
||||||
private ArrayList<String> slCardUIDs = new ArrayList<>();
|
|
||||||
private RelativeLayout rlProgressBar;
|
|
||||||
public CardListAdapter mCardListAdapter;
|
|
||||||
private ReadCardInfoTask readCardInfoTask;
|
|
||||||
|
|
||||||
private int unsuccessReadCount = 0;
|
|
||||||
private Tag lastTag = null;
|
|
||||||
|
|
||||||
public Main() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public CardListAdapter getCardListAdapter() {
|
|
||||||
return mCardListAdapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
|
||||||
View v = inflater.inflate(R.layout.fr_main, container, false);
|
|
||||||
|
|
||||||
mNfcManager = new NfcManager(getActivity(), this);
|
|
||||||
|
|
||||||
verifyPermissions();
|
|
||||||
|
|
||||||
rlProgressBar = v.findViewById(R.id.rlProgressBar);
|
|
||||||
RecyclerView rvCards = v.findViewById(R.id.lvCards);
|
|
||||||
rvCards.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
rvCards.setLayoutManager(new LinearLayoutManager(getContext()));
|
|
||||||
mCardListAdapter = new CardListAdapter(inflater, savedInstanceState, this);
|
|
||||||
rvCards.setAdapter(mCardListAdapter);
|
|
||||||
|
|
||||||
if (savedInstanceState != null && savedInstanceState.containsKey("slCardUIDs")) {
|
|
||||||
slCardUIDs = savedInstanceState.getStringArrayList("slCardUIDs");
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
|
|
||||||
@Override
|
|
||||||
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
|
|
||||||
// remove swiped item from list and notify the RecyclerView
|
|
||||||
int cardIndex = viewHolder.getAdapterPosition();
|
|
||||||
if (cardIndex < 0 || cardIndex >= mCardListAdapter.getItemCount()) return;
|
|
||||||
slCardUIDs.remove(mCardListAdapter.getCard(cardIndex).getUID());
|
|
||||||
|
|
||||||
mCardListAdapter.removeCard(cardIndex);
|
|
||||||
if (mCardListAdapter.getItemCount() == 0 && getActivity().getClass() == MainActivity.class) {
|
|
||||||
((MainActivity) getActivity()).hideCleanButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
itemTouchHelper.attachToRecyclerView(rvCards);
|
|
||||||
|
|
||||||
if (getActivity() instanceof MainActivity) {
|
|
||||||
((MainActivity) getActivity()).setOnCardsClean(this);
|
|
||||||
((MainActivity) getActivity()).setNfcAdapterReaderCallback(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
ReadCardInfoTask.resetLastReadInfo();
|
|
||||||
mNfcManager.onResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
mNfcManager.onPause();
|
|
||||||
if (readCardInfoTask != null) {
|
|
||||||
readCardInfoTask.cancel(true);
|
|
||||||
}
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
// dismiss enable NFC dialog
|
|
||||||
mNfcManager.onStop();
|
|
||||||
if (readCardInfoTask != null) {
|
|
||||||
readCardInfoTask.cancel(true);
|
|
||||||
}
|
|
||||||
// for (RequestWalletInfoTask rt : requestTasks) {
|
|
||||||
// rt.cancel(true);
|
|
||||||
// }
|
|
||||||
super.onStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
Log.d(TAG, "ActivityResult: requestCode = " + requestCode + ", resultCode = " + resultCode);
|
|
||||||
|
|
||||||
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_SHOW_CARD_ACTIVITY) {
|
|
||||||
if (data != null && Objects.requireNonNull(data.getExtras()).containsKey("UID")) {
|
|
||||||
final TangemCard card = new TangemCard(data.getStringExtra("UID"));
|
|
||||||
card.LoadFromBundle(data.getBundleExtra("Card"));
|
|
||||||
|
|
||||||
switch (data.getStringExtra("modification")) {
|
|
||||||
case "delete":
|
|
||||||
mCardListAdapter.removeCard(card);
|
|
||||||
for (int i = 0; i < slCardUIDs.size(); i++) {
|
|
||||||
if (slCardUIDs.get(i).equals(card.getUID())) {
|
|
||||||
slCardUIDs.remove(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mCardListAdapter.getItemCount() == 0 && getActivity().getClass() == MainActivity.class) {
|
|
||||||
((MainActivity) getActivity()).hideCleanButton();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "update":
|
|
||||||
mCardListAdapter.updateCard(card);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "updateAndViewCard":
|
|
||||||
mCardListAdapter.updateCard(card);
|
|
||||||
onViewCard(data.getExtras());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (requestCode == REQUEST_CODE_ENTER_PIN_ACTIVITY) {
|
|
||||||
if (resultCode == Activity.RESULT_OK && lastTag != null) {
|
|
||||||
onTagDiscovered(lastTag);
|
|
||||||
} else {
|
|
||||||
ReadCardInfoTask.resetLastReadInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTagDiscovered(Tag tag) {
|
|
||||||
try {
|
|
||||||
// get IsoDep handle and run cardReader thread
|
|
||||||
final IsoDep isoDep = IsoDep.get(tag);
|
|
||||||
if (isoDep == null) {
|
|
||||||
throw new CardProtocol.TangemException(getString(R.string.wrong_tag_err));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte UID[] = tag.getId();
|
|
||||||
String sUID = Util.byteArrayToHexString(UID);
|
|
||||||
if (slCardUIDs.indexOf(sUID) != -1) {
|
|
||||||
Log.d(TAG, "Repeat UID: " + sUID);
|
|
||||||
mNfcManager.ignoreTag(isoDep.getTag());
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
Log.v(TAG, "UID: " + sUID);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.e(TAG, "setTimeout(" + String.valueOf(1000 + 3000 * unsuccessReadCount) + ")");
|
|
||||||
if (unsuccessReadCount < 2) {
|
|
||||||
isoDep.setTimeout(2000 + 5000 * unsuccessReadCount);
|
|
||||||
} else {
|
|
||||||
isoDep.setTimeout(90000);
|
|
||||||
}
|
|
||||||
lastTag = tag;
|
|
||||||
|
|
||||||
readCardInfoTask = new ReadCardInfoTask(getActivity(), mNfcManager, isoDep, this);
|
|
||||||
readCardInfoTask.start();
|
|
||||||
|
|
||||||
// Log.i(TAG, "onTagDiscovered " + Arrays.toString(tag.getId()));
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
mNfcManager.notifyReadResult(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCard(Bundle cardInfo) {
|
|
||||||
String UID = cardInfo.getString("UID");
|
|
||||||
TangemCard card = new TangemCard(UID);
|
|
||||||
card.LoadFromBundle(cardInfo.getBundle("Card"));
|
|
||||||
|
|
||||||
Intent intent;
|
|
||||||
if (card.getStatus() == TangemCard.Status.Empty) {
|
|
||||||
intent = new Intent(getActivity(), EmptyWalletActivity.class);
|
|
||||||
|
|
||||||
} else if (card.getStatus() == TangemCard.Status.Loaded) {
|
|
||||||
intent = new Intent(getActivity(), LoadedWalletActivity.class);
|
|
||||||
|
|
||||||
} else if (card.getStatus() == TangemCard.Status.NotPersonalized || card.getStatus() == TangemCard.Status.Purged) {
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
intent = new Intent(getActivity(), LoadedWalletActivity.class);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
intent.putExtras(cardInfo);
|
|
||||||
startActivityForResult(intent, REQUEST_CODE_SHOW_CARD_ACTIVITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void OnReadStart(CardProtocol cardProtocol) {
|
|
||||||
rlProgressBar.post(() -> rlProgressBar.setVisibility(View.VISIBLE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void OnReadProgress(CardProtocol protocol, final int progress) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void OnReadFinish(final CardProtocol cardProtocol) {
|
|
||||||
readCardInfoTask = null;
|
|
||||||
if (cardProtocol != null) {
|
|
||||||
if (cardProtocol.getError() == null) {
|
|
||||||
mNfcManager.notifyReadResult(true);
|
|
||||||
rlProgressBar.post(() -> {
|
|
||||||
rlProgressBar.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
Bundle cardInfo = new Bundle();
|
|
||||||
cardInfo.putString("UID", cardProtocol.getCard().getUID());
|
|
||||||
Bundle bCard = new Bundle();
|
|
||||||
cardProtocol.getCard().SaveToBundle(bCard);
|
|
||||||
cardInfo.putBundle("Card", bCard);
|
|
||||||
|
|
||||||
|
|
||||||
String UID = cardInfo.getString("UID");
|
|
||||||
TangemCard card = new TangemCard(UID);
|
|
||||||
card.LoadFromBundle(cardInfo.getBundle("Card"));
|
|
||||||
|
|
||||||
Intent intent;
|
|
||||||
if (card.getStatus() == TangemCard.Status.Empty) {
|
|
||||||
intent = new Intent(getActivity(), EmptyWalletActivity.class);
|
|
||||||
|
|
||||||
} else if (card.getStatus() == TangemCard.Status.Loaded) {
|
|
||||||
intent = new Intent(getActivity(), LoadedWalletActivity.class);
|
|
||||||
|
|
||||||
} else if (card.getStatus() == TangemCard.Status.NotPersonalized || card.getStatus() == TangemCard.Status.Purged) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
intent = new Intent(getActivity(), LoadedWalletActivity.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
intent.putExtra(EXTRA_LAST_DISCOVERED_TAG, lastTag);
|
|
||||||
intent.putExtras(cardInfo);
|
|
||||||
startActivityForResult(intent, REQUEST_CODE_SHOW_CARD_ACTIVITY);
|
|
||||||
|
|
||||||
mCardListAdapter.clearCards();
|
|
||||||
slCardUIDs.clear();
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// remove last UIDs because of error and no card read
|
|
||||||
rlProgressBar.post(() -> {
|
|
||||||
if (getContext() != null) {
|
|
||||||
Toast.makeText(getContext(), R.string.try_to_scan_again, Toast.LENGTH_SHORT).show();
|
|
||||||
unsuccessReadCount++;
|
|
||||||
|
|
||||||
slCardUIDs.remove(cardProtocol.getCard().getUID());
|
|
||||||
if (cardProtocol.getError() instanceof CardProtocol.TangemException_InvalidPIN) {
|
|
||||||
doEnterPIN();
|
|
||||||
} else {
|
|
||||||
if (cardProtocol.getError() instanceof CardProtocol.TangemException_ExtendedLengthNotSupported) {
|
|
||||||
if (!NoExtendedLengthSupportDialog.allReadyShowed) {
|
|
||||||
new NoExtendedLengthSupportDialog().show(Objects.requireNonNull(getActivity()).getFragmentManager(), NoExtendedLengthSupportDialog.TAG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastTag = null;
|
|
||||||
ReadCardInfoTask.resetLastReadInfo();
|
|
||||||
mNfcManager.notifyReadResult(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rlProgressBar.postDelayed(() -> {
|
|
||||||
try {
|
|
||||||
rlProgressBar.setVisibility(View.GONE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnReadCancel() {
|
|
||||||
readCardInfoTask = null;
|
|
||||||
ReadCardInfoTask.resetLastReadInfo();
|
|
||||||
rlProgressBar.postDelayed(() -> {
|
|
||||||
try {
|
|
||||||
rlProgressBar.setVisibility(View.GONE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnReadWait(final int msec) {
|
|
||||||
WaitSecurityDelayDialog.OnReadWait(Objects.requireNonNull(getActivity()), msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void OnReadBeforeRequest(int timeout) {
|
|
||||||
WaitSecurityDelayDialog.onReadBeforeRequest(Objects.requireNonNull(getActivity()), timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void OnReadAfterRequest() {
|
|
||||||
WaitSecurityDelayDialog.onReadAfterRequest(Objects.requireNonNull(getActivity()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doClean() {
|
|
||||||
mCardListAdapter.clearCards();
|
|
||||||
slCardUIDs.clear();
|
|
||||||
ReadCardInfoTask.resetLastReadInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doEnterPIN() {
|
|
||||||
Intent intent = new Intent(getContext(), RequestPINActivity.class);
|
|
||||||
intent.putExtra("mode", RequestPINActivity.Mode.RequestPIN.toString());
|
|
||||||
startActivityForResult(intent, REQUEST_CODE_ENTER_PIN_ACTIVITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyPermissions() {
|
|
||||||
NfcManager.verifyPermissions(getActivity());
|
|
||||||
if (ActivityCompat.checkSelfPermission(Objects.requireNonNull(getActivity()), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
|
|
||||||
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_REQUEST_CAMERA_PERMISSIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="com.tangem.presentation.activity.MainActivity">
|
tools:context="com.tangem.presentation.activity.MainActivity"
|
||||||
|
tools:ignore="contentDescription">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/llTapPrompt"
|
android:id="@+id/llTapPrompt"
|
||||||
|
|
@ -37,7 +38,7 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/llNFC"
|
android:id="@+id/llNfc"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="100dp"
|
android:layout_marginStart="100dp"
|
||||||
|
|
@ -46,7 +47,7 @@
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.skyfishjy.library.RippleBackground
|
<com.skyfishjy.library.RippleBackground
|
||||||
android:id="@+id/imNFC"
|
android:id="@+id/rippleBackgroundNfc"
|
||||||
android:layout_width="150dp"
|
android:layout_width="150dp"
|
||||||
android:layout_height="150dp"
|
android:layout_height="150dp"
|
||||||
app:rb_color="@color/fab"
|
app:rb_color="@color/fab"
|
||||||
|
|
@ -56,7 +57,6 @@
|
||||||
app:rb_scale="4"
|
app:rb_scale="4"
|
||||||
app:rb_strokeWidth="8dp"
|
app:rb_strokeWidth="8dp"
|
||||||
app:rb_type="strokeRipple">
|
app:rb_type="strokeRipple">
|
||||||
|
|
||||||
</com.skyfishjy.library.RippleBackground>
|
</com.skyfishjy.library.RippleBackground>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
@ -84,6 +84,32 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rlProgressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:elevation="10dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:alpha="0.8"
|
||||||
|
android:text="@string/reading"
|
||||||
|
android:textColor="@color/colorPrimary"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="@dimen/size_progress_bar_big"
|
||||||
|
android:layout_height="@dimen/size_progress_bar_big"
|
||||||
|
android:alpha="0.8"
|
||||||
|
android:elevation="1dp"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
@ -104,12 +130,6 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/include2"
|
|
||||||
layout="@layout/content_main"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"/>
|
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/frameFAB"
|
android:id="@+id/frameFAB"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context="com.tangem.presentation.fragment.Main"
|
|
||||||
tools:showIn="@layout/content_main">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/rlProgressBar"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:alpha="0.8"
|
|
||||||
android:text="@string/reading"
|
|
||||||
android:textColor="@color/colorPrimary"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:layout_width="@dimen/size_progress_bar_big"
|
|
||||||
android:layout_height="@dimen/size_progress_bar_big"
|
|
||||||
android:alpha="0.8"
|
|
||||||
android:elevation="1dp" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
|
||||||
android:id="@+id/lvCards"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:foregroundGravity="center_vertical"
|
|
||||||
android:paddingTop="14dp"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue