Updated on 2026-08-14

This commit is contained in:
Tangem 2018-07-26 13:31:37 +03:00
parent ad17abe440
commit b867868273
20 changed files with 468 additions and 1118 deletions

2
.idea/misc.xml generated
View file

@ -25,7 +25,7 @@
</value>
</option>
</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" />
</component>
</project>

View file

@ -15,7 +15,7 @@ android {
applicationId "com.tangem.wallet"
minSdkVersion 21
targetSdkVersion 27
versionCode 47
versionCode 48
versionName "0.87.1." + generateVersionName()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

View file

@ -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());
}
}
}
}

View file

@ -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();
}
}
}
}
}

View file

@ -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);
}
}
}
}
}

View file

@ -78,7 +78,7 @@ public class ConfirmPaymentActivity extends AppCompatActivity implements NfcAdap
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_confirm_payment);
MainActivity.commonInit(getApplicationContext());
MainActivity.Companion.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);
mCard = new TangemCard(getIntent().getStringExtra("UID"));

View file

@ -40,7 +40,7 @@ public class CreateNewWalletActivity extends AppCompatActivity implements NfcAda
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_new_wallet);
MainActivity.commonInit(getApplicationContext());
MainActivity.Companion.commonInit(getApplicationContext());
mCard = new TangemCard(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));

View file

@ -47,7 +47,7 @@ public class EmptyWalletActivity extends AppCompatActivity implements NfcAdapter
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_empty_wallet);
MainActivity.commonInit(getApplicationContext());
MainActivity.Companion.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);
mCard = new TangemCard(getIntent().getStringExtra("UID"));

View file

@ -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();
}
}

View file

@ -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)
}
}

View file

@ -124,7 +124,7 @@ public class PurgeActivity extends AppCompatActivity implements NfcAdapter.Reade
mNfcManager = new NfcManager(this, this);
MainActivity.commonInit(getApplicationContext());
MainActivity.Companion.commonInit(getApplicationContext());
mCard = new TangemCard(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));

View file

@ -54,7 +54,7 @@ public class RequestPINActivity extends AppCompatActivity implements NfcAdapter.
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request_pin);
MainActivity.commonInit(getApplicationContext());
MainActivity.Companion.commonInit(getApplicationContext());
mNfcManager = new NfcManager(this, this);

View file

@ -63,7 +63,7 @@ public class SavePINActivity extends AppCompatActivity implements FingerprintHel
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save_pin);
MainActivity.commonInit(getApplicationContext());
MainActivity.Companion.commonInit(getApplicationContext());
UsePIN2 = getIntent().getBooleanExtra("PIN2", false);

View file

@ -28,7 +28,7 @@ public class SendTransactionActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_transaction);
MainActivity.commonInit(getApplicationContext());
MainActivity.Companion.commonInit(getApplicationContext());
progressBar = findViewById(R.id.progressBar);

File diff suppressed because one or more lines are too long

View file

@ -40,7 +40,7 @@ public class SwapPINActivity extends AppCompatActivity implements NfcAdapter.Rea
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swap_pin);
MainActivity.commonInit(getApplicationContext());
MainActivity.Companion.commonInit(getApplicationContext());
mCard = new TangemCard(getIntent().getStringExtra("UID"));
mCard.LoadFromBundle(getIntent().getExtras().getBundle("Card"));

View file

@ -114,7 +114,7 @@ class LoadedWallet : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notific
mCard = TangemCard(activity!!.intent.getStringExtra(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? {

View file

@ -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);
}
}

View file

@ -5,7 +5,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="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
android:id="@+id/llTapPrompt"
@ -37,7 +38,7 @@
</LinearLayout>
<LinearLayout
android:id="@+id/llNFC"
android:id="@+id/llNfc"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="100dp"
@ -46,7 +47,7 @@
android:orientation="vertical">
<com.skyfishjy.library.RippleBackground
android:id="@+id/imNFC"
android:id="@+id/rippleBackgroundNfc"
android:layout_width="150dp"
android:layout_height="150dp"
app:rb_color="@color/fab"
@ -56,7 +57,6 @@
app:rb_scale="4"
app:rb_strokeWidth="8dp"
app:rb_type="strokeRipple">
</com.skyfishjy.library.RippleBackground>
</LinearLayout>
@ -84,6 +84,32 @@
</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>
<TextView
@ -104,12 +130,6 @@
</LinearLayout>
<include
android:id="@+id/include2"
layout="@layout/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/frameFAB"
android:layout_width="wrap_content"

View file

@ -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>