Updated on 2026-08-14
This commit is contained in:
commit
028a57b6cf
34 changed files with 786 additions and 538 deletions
31
.idea/navEditor.xml
generated
Normal file
31
.idea/navEditor.xml
generated
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="navEditor-manualLayoutAlgorithm2">
|
||||
<option name="myPositions">
|
||||
<map>
|
||||
<entry key="main_graph.xml">
|
||||
<value>
|
||||
<LayoutPositions>
|
||||
<option name="myPositions">
|
||||
<map>
|
||||
<entry key="main">
|
||||
<value>
|
||||
<LayoutPositions>
|
||||
<option name="myPosition">
|
||||
<Point>
|
||||
<option name="x" value="-203" />
|
||||
<option name="y" value="-292" />
|
||||
</Point>
|
||||
</option>
|
||||
</LayoutPositions>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</LayoutPositions>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -30,7 +30,6 @@ android {
|
|||
debuggable true
|
||||
minifyEnabled false
|
||||
applicationIdSuffix ".debug"
|
||||
versionNameSuffix '-DEBUG'
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
|
|
@ -67,12 +66,15 @@ dependencies {
|
|||
// implementation 'com.github.TangemCash:card-common:0.1.2'
|
||||
// implementation 'com.github.TangemCash:card-android:0.1.3'
|
||||
// implementation 'com.github.TangemCash:server-android:0.1.4'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'
|
||||
implementation "androidx.preference:preference:1.1.0-alpha04"
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'android.arch.navigation:navigation-fragment:1.0.0'
|
||||
implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation "androidx.preference:preference:1.1.0-alpha04"
|
||||
implementation 'androidx.biometric:biometric:1.0.0-alpha04'
|
||||
implementation 'co.nstant.in:cbor:0.8'
|
||||
implementation 'com.google.android.material:material:1.1.0-alpha05'
|
||||
implementation 'com.google.dagger:dagger:2.21'
|
||||
kapt 'com.google.dagger:dagger-compiler:2.21'
|
||||
|
|
@ -90,6 +92,7 @@ dependencies {
|
|||
implementation 'com.skyfishjy.ripplebackground:library:1.0.1'
|
||||
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
|
||||
implementation "com.orhanobut:hawk:2.0.1"
|
||||
implementation 'co.nstant.in:cbor:0.8'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!--<string name="app_name">DEBUG</string>-->
|
||||
<string name="app_name">DEBUG</string>
|
||||
|
||||
</resources>
|
||||
|
|
@ -29,12 +29,13 @@
|
|||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
tools:ignore="GoogleAppIndexingWarning">
|
||||
<!--<provider-->
|
||||
<!--android:name="com.tangem.data.LogFileProvider"-->
|
||||
<!--android:authorities="@string/log_file_provider_authorities"-->
|
||||
<!--android:enabled="true"-->
|
||||
<!--android:exported="false"-->
|
||||
<!--android:grantUriPermissions="true" />-->
|
||||
|
||||
<provider
|
||||
android:name="com.tangem.data.LogFileProvider"
|
||||
android:authorities="@string/log_file_provider_authorities"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true" />
|
||||
|
||||
<activity
|
||||
android:name="com.tangem.ui.activity.LogoActivity"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ object Constant {
|
|||
|
||||
const val INTENT_TYPE_TEXT_PLAIN = "text/plain"
|
||||
|
||||
// LoadedWallet, VerifyCard
|
||||
// LoadedWalletFragment, VerifyCard
|
||||
const val REQUEST_CODE_SEND_TRANSACTION = 1
|
||||
const val REQUEST_CODE_PURGE = 2
|
||||
const val REQUEST_CODE_REQUEST_PIN2_FOR_PURGE = 3
|
||||
|
|
|
|||
|
|
@ -45,6 +45,13 @@ class ToastHelper {
|
|||
snackbar.show()
|
||||
}
|
||||
|
||||
fun showSnackbarWarning(context: Context, vg: ViewGroup, message: String) {
|
||||
val snackbar = Snackbar.make(vg, message, Snackbar.LENGTH_LONG)
|
||||
val snackView = snackbar.view
|
||||
snackView.setBackgroundColor(context.resources.getColor(R.color.msg_err))
|
||||
snackbar.show()
|
||||
}
|
||||
|
||||
private var singleToast: Toast? = null
|
||||
private var showTime: Date = Date()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.di
|
||||
|
||||
import com.tangem.ui.ConfirmTransactionActivity
|
||||
import com.tangem.ui.PrepareTransactionActivity
|
||||
import com.tangem.ui.activity.EmptyWalletActivity
|
||||
import com.tangem.ui.activity.LoadedWalletActivity
|
||||
|
|
@ -15,6 +16,8 @@ interface ToastHelperComponent {
|
|||
|
||||
fun inject(activity: LoadedWalletActivity)
|
||||
|
||||
fun inject(activity: ConfirmTransactionActivity)
|
||||
|
||||
fun inject(activity: PrepareTransactionActivity)
|
||||
|
||||
fun inject(activity: EmptyWalletActivity)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import com.tangem.Constant
|
|||
import com.tangem.di.Navigator
|
||||
import com.tangem.di.ToastHelper
|
||||
import com.tangem.wallet.TangemContext
|
||||
import com.tangem.ui.fragment.LoadedWallet
|
||||
import com.tangem.ui.fragment.LoadedWalletFragment
|
||||
import com.tangem.wallet.R
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ class LoadedWalletActivity : AppCompatActivity() {
|
|||
if (intent.extras!!.containsKey(NfcAdapter.EXTRA_TAG)) {
|
||||
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
|
||||
if (tag != null) {
|
||||
val fragment = supportFragmentManager.findFragmentById(R.id.loaded_wallet_fragment) as LoadedWallet
|
||||
val fragment = supportFragmentManager.findFragmentById(R.id.loaded_wallet_fragment) as LoadedWalletFragment
|
||||
fragment.onTagDiscovered(tag)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,151 +3,79 @@
|
|||
package com.tangem.ui.activity
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.nfc.NfcAdapter
|
||||
import android.nfc.Tag
|
||||
import android.nfc.tech.IsoDep
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.Navigation
|
||||
import com.scottyab.rootbeer.RootBeer
|
||||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.card_android.android.nfc.NfcDeviceAntennaLocation
|
||||
import com.tangem.card_android.android.nfc.NfcLifecycleObserver
|
||||
import com.tangem.card_android.android.reader.NfcManager
|
||||
import com.tangem.card_android.android.reader.NfcReader
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.card_android.data.loadFromBundle
|
||||
import com.tangem.card_android.data.saveToBundle
|
||||
import com.tangem.card_common.data.TangemCard
|
||||
import com.tangem.card_common.reader.CardProtocol
|
||||
import com.tangem.card_common.tasks.CustomReadCardTask
|
||||
import com.tangem.card_common.tasks.ReadCardInfoTask
|
||||
import com.tangem.data.Logger
|
||||
import com.tangem.data.network.ServerApiCommon
|
||||
import com.tangem.di.Navigator
|
||||
import com.tangem.di.ToastHelper
|
||||
import com.tangem.wallet.CoinEngineFactory
|
||||
import com.tangem.wallet.TangemContext
|
||||
import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.ui.dialog.RootFoundDialog
|
||||
import com.tangem.ui.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.util.CommonUtil
|
||||
import com.tangem.util.LOG
|
||||
import com.tangem.util.UtilHelper
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.android.synthetic.main.layout_touch_card.*
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, PopupMenu.OnMenuItemClickListener {
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
val TAG: String = MainActivity::class.java.simpleName
|
||||
fun callingIntent(context: Context) = Intent(context, MainActivity::class.java)
|
||||
}
|
||||
|
||||
lateinit var navController: NavController
|
||||
@Inject
|
||||
internal lateinit var navigator: Navigator
|
||||
@Inject
|
||||
internal lateinit var toastHelper: ToastHelper
|
||||
|
||||
private lateinit var nfcManager: NfcManager
|
||||
// private var onNfcReaderCallback: NfcAdapter.ReaderCallback? = null
|
||||
|
||||
private var zipFile: File? = null
|
||||
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
|
||||
private var unsuccessReadCount = 0
|
||||
private var lastTag: Tag? = null
|
||||
private var task: CustomReadCardTask? = null
|
||||
private var onNfcReaderCallback: NfcAdapter.ReaderCallback? = 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 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)
|
||||
|
||||
navController = Navigation.findNavController(this, R.id.nav_host_fragment)
|
||||
|
||||
App.navigatorComponent.inject(this)
|
||||
App.toastHelperComponent.inject(this)
|
||||
|
||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||
|
||||
nfcManager = NfcManager(this, this)
|
||||
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
|
||||
|
||||
verifyPermissions()
|
||||
|
||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
||||
|
||||
setNfcAdapterReaderCallback(this)
|
||||
|
||||
rippleBackgroundNfc.startRippleAnimation()
|
||||
|
||||
// init NFC Antenna
|
||||
nfcDeviceAntenna = NfcDeviceAntennaLocation(this, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
|
||||
nfcDeviceAntenna.init()
|
||||
|
||||
// set phone name
|
||||
if (nfcDeviceAntenna.fullName != "")
|
||||
tvNFCHint.text = String.format(getString(R.string.scan_banknote), nfcDeviceAntenna.fullName)
|
||||
else
|
||||
tvNFCHint.text = String.format(getString(R.string.scan_banknote), getString(R.string.phone))
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
// // 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(supportFragmentManager, RootFoundDialog.TAG)
|
||||
|
||||
// set listeners
|
||||
fab.setOnClickListener { showMenu(it) }
|
||||
|
||||
val apiHelper = ServerApiCommon()
|
||||
apiHelper.setLastVersionListener { response ->
|
||||
try {
|
||||
if (response.isNullOrEmpty())
|
||||
return@setLastVersionListener
|
||||
val responseVersionName = response.trim(' ', '\n', '\r', '\t')
|
||||
val responseBuildVersion = responseVersionName.split('.').last()
|
||||
val appBuildVersion = BuildConfig.VERSION_NAME.split('.').last()
|
||||
if (responseBuildVersion.toInt() > appBuildVersion.toInt())
|
||||
if (BuildConfig.FLAVOR.equals(Constant.FLAVOR_TANGEM_ACCESS))
|
||||
toastHelper.showSnackbarUpdateVersion(this, cl, responseVersionName)
|
||||
} catch (E: Exception) {
|
||||
E.printStackTrace()
|
||||
}
|
||||
}
|
||||
apiHelper.requestLastVersion()
|
||||
}
|
||||
|
||||
private fun verifyPermissions() {
|
||||
|
|
@ -157,231 +85,4 @@ class MainActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, CardProtoco
|
|||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when (requestCode) {
|
||||
Constant.REQUEST_CODE_SEND_EMAIL -> {
|
||||
if (zipFile != null) {
|
||||
zipFile!!.delete()
|
||||
zipFile = null
|
||||
}
|
||||
}
|
||||
Constant.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", UtilHelper.getDeviceInfo(), arrayOf(f))
|
||||
} else {
|
||||
LOG.e(TAG, "Can't create temporarily log file")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
if (f != null && f.exists())
|
||||
f.delete()
|
||||
}
|
||||
return true
|
||||
}
|
||||
R.id.managePIN -> {
|
||||
navigator.showPinSave(this, false)
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.managePIN2 -> {
|
||||
navigator.showPinSave(this, true)
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.settings -> {
|
||||
navigator.showSettings(this)
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.about -> {
|
||||
navigator.showLogo(this, false)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onTagDiscovered(tag: Tag) {
|
||||
try {
|
||||
// get IsoDep handle and run cardReader thread
|
||||
val isoDep = IsoDep.get(tag)
|
||||
if (unsuccessReadCount < 2)
|
||||
isoDep.timeout = 2000 + 5000 * unsuccessReadCount
|
||||
else
|
||||
isoDep.timeout = 90000
|
||||
|
||||
lastTag = tag
|
||||
|
||||
task = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
|
||||
task?.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
nfcManager.notifyReadResult(false)
|
||||
}
|
||||
}
|
||||
|
||||
public override fun onResume() {
|
||||
super.onResume()
|
||||
nfcDeviceAntenna.animate()
|
||||
ReadCardInfoTask.resetLastReadInfo()
|
||||
}
|
||||
|
||||
public override fun onPause() {
|
||||
task?.cancel(true)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
public override fun onStop() {
|
||||
task?.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?) {
|
||||
task = null
|
||||
if (cardProtocol != null) {
|
||||
if (cardProtocol.error == null) {
|
||||
nfcManager.notifyReadResult(true)
|
||||
rlProgressBar.post {
|
||||
rlProgressBar.visibility = View.GONE
|
||||
|
||||
// TODO - ??? remove save and load???
|
||||
val cardInfo = Bundle()
|
||||
val bCard = Bundle()
|
||||
|
||||
cardInfo.putString(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
|
||||
cardInfo.putBundle(EXTRA_TANGEM_CARD, bCard)
|
||||
cardProtocol.card.saveToBundle(bCard)
|
||||
|
||||
val uid = cardInfo.getString(EXTRA_TANGEM_CARD_UID)
|
||||
val card = TangemCard(uid)
|
||||
cardInfo.getBundle(EXTRA_TANGEM_CARD)?.let { card.loadFromBundle(it) }
|
||||
|
||||
val ctx = TangemContext(card)
|
||||
when {
|
||||
card.status == TangemCard.Status.Loaded -> lastTag?.let {
|
||||
val engineCoin = CoinEngineFactory.create(ctx)
|
||||
if (engineCoin != null) {
|
||||
engineCoin.defineWallet()
|
||||
navigator.showLoadedWallet(this, it, ctx)
|
||||
}
|
||||
}
|
||||
card.status == TangemCard.Status.Empty -> navigator.showEmptyWallet(this, ctx)
|
||||
card.status == TangemCard.Status.Purged -> Toast.makeText(this, R.string.erased_wallet, Toast.LENGTH_SHORT).show()
|
||||
card.status == TangemCard.Status.NotPersonalized -> Toast.makeText(this, R.string.not_personalized, Toast.LENGTH_SHORT).show()
|
||||
else -> lastTag?.let { navigator.showLoadedWallet(this, it, ctx) }
|
||||
}
|
||||
}
|
||||
|
||||
} 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)
|
||||
navigator.showPinRequest(this, PinRequestActivity.Mode.RequestPIN.toString())
|
||||
else {
|
||||
if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported)
|
||||
if (!NoExtendedLengthSupportDialog.allReadyShowed)
|
||||
NoExtendedLengthSupportDialog().show(supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
|
||||
|
||||
lastTag = null
|
||||
ReadCardInfoTask.resetLastReadInfo()
|
||||
nfcManager.notifyReadResult(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rlProgressBar.postDelayed({
|
||||
try {
|
||||
rlProgressBar.visibility = View.GONE
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
override fun onReadCancel() {
|
||||
task = 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))
|
||||
}
|
||||
|
||||
private fun setNfcAdapterReaderCallback(callback: NfcAdapter.ReaderCallback) {
|
||||
onNfcReaderCallback = callback
|
||||
}
|
||||
|
||||
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.menu.findItem(R.id.settings).isVisible = true
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener(this)
|
||||
popup.show()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -246,7 +246,7 @@ class PinRequestActivity : AppCompatActivity(), NfcAdapter.ReaderCallback, Finge
|
|||
|
||||
@SuppressLint("NewApi")
|
||||
private fun testFingerPrintSettings(): Boolean {
|
||||
LOG.i(TAG, "Testing Fingerprint Settings")
|
||||
LOG.i(TAG, "Testing Fingerprint SettingsFragment")
|
||||
|
||||
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
||||
fingerprintManager = getSystemService(Context.FINGERPRINT_SERVICE) as FingerprintManager
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import android.nfc.tech.IsoDep
|
|||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.util.Log
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
|
@ -20,6 +21,8 @@ import android.view.ViewGroup
|
|||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.data.Blockchain
|
||||
|
|
@ -63,11 +66,12 @@ import java.io.InputStream
|
|||
import java.util.*
|
||||
import kotlin.concurrent.timerTask
|
||||
|
||||
class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
class LoadedWalletFragment : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
companion object {
|
||||
val TAG: String = LoadedWallet::class.java.simpleName
|
||||
val TAG: String = LoadedWalletFragment::class.java.simpleName
|
||||
}
|
||||
|
||||
private lateinit var viewModel: LoadedWalletViewModel
|
||||
private lateinit var ctx: TangemContext
|
||||
private lateinit var nfcManager: NfcManager
|
||||
private lateinit var mpSecondScanSound: MediaPlayer
|
||||
|
|
@ -274,19 +278,23 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
|
|||
}
|
||||
serverApiTangem.setArtworkListener(artworkListener)
|
||||
|
||||
// request rate info listener
|
||||
serverApiCommon.setRateInfoListener {
|
||||
if (activity == null || !UtilHelper.isOnline(activity!!)) return@setRateInfoListener
|
||||
val rate = it.priceUsd.toFloat()
|
||||
ctx.coinData!!.rate = rate
|
||||
ctx.coinData!!.rateAlter = rate
|
||||
}
|
||||
|
||||
refresh()
|
||||
|
||||
startVerify(lastTag)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
viewModel = ViewModelProviders.of(this).get(LoadedWalletViewModel::class.java)
|
||||
|
||||
// set rate info to CoinData
|
||||
viewModel.getRateInfo().observe(this, Observer<Float> { rate ->
|
||||
ctx.coinData.rate = rate
|
||||
ctx.coinData.rateAlter = rate
|
||||
})
|
||||
viewModel.requestRateInfo(ctx)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (timerHideErrorAndMessage != null) {
|
||||
|
|
@ -647,7 +655,8 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
|
|||
|
||||
requestBalanceAndUnspentTransactions()
|
||||
|
||||
requestRateInfo()
|
||||
if (::viewModel.isInitialized)
|
||||
viewModel.requestRateInfo(ctx)
|
||||
|
||||
if (requestCounter == 0) {
|
||||
// if no connection and no requests posted
|
||||
|
|
@ -709,37 +718,6 @@ class LoadedWallet : androidx.fragment.app.Fragment(), NfcAdapter.ReaderCallback
|
|||
}
|
||||
}
|
||||
|
||||
private fun requestRateInfo() {
|
||||
if (UtilHelper.isOnline(context as Activity)) {
|
||||
LOG.i(TAG, "requestRateInfo")
|
||||
|
||||
// TODO - move requestRateInfo to CoinEngine
|
||||
val cryptoId: String = when (ctx.blockchain) {
|
||||
Blockchain.Bitcoin -> "bitcoin"
|
||||
Blockchain.BitcoinTestNet -> "bitcoin"
|
||||
Blockchain.Ethereum -> "ethereum"
|
||||
Blockchain.EthereumTestNet -> "ethereum"
|
||||
Blockchain.Token -> "ethereum"
|
||||
Blockchain.NftToken -> "ethereum"
|
||||
Blockchain.BitcoinCash -> "bitcoin-cash"
|
||||
Blockchain.Litecoin -> "litecoin"
|
||||
Blockchain.Rootstock -> "bitcoin"
|
||||
Blockchain.RootstockToken -> "bitcoin"
|
||||
Blockchain.Cardano -> "cardano"
|
||||
Blockchain.Ripple -> "ripple"
|
||||
Blockchain.Binance -> "binance-coin"
|
||||
Blockchain.BinanceTestNet -> "binance-coin"
|
||||
else -> {
|
||||
throw Exception("Can''t get rate for blockchain " + ctx.blockchainName)
|
||||
}
|
||||
}
|
||||
serverApiCommon.requestRateInfo(cryptoId)
|
||||
} else {
|
||||
ctx.error = getString(R.string.no_connection)
|
||||
updateViews()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startVerify(tag: Tag?) {
|
||||
try {
|
||||
val isoDep = IsoDep.get(tag)
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package com.tangem.ui.fragment
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.data.network.ServerApiCommon
|
||||
import com.tangem.wallet.TangemContext
|
||||
|
||||
class LoadedWalletViewModel : ViewModel() {
|
||||
private var serverApiCommon: ServerApiCommon = ServerApiCommon()
|
||||
private lateinit var ctx: TangemContext
|
||||
private val rate: MutableLiveData<Float> by lazy {
|
||||
MutableLiveData<Float>().also {
|
||||
loadRateInfo()
|
||||
}
|
||||
}
|
||||
|
||||
fun getRateInfo(): LiveData<Float> {
|
||||
return rate
|
||||
}
|
||||
|
||||
fun requestRateInfo(ctx: TangemContext) {
|
||||
this.ctx = ctx
|
||||
// TODO - move loadRateInfo to CoinEngine
|
||||
val cryptoId: String = when (ctx.blockchain) {
|
||||
Blockchain.Bitcoin -> "bitcoin"
|
||||
Blockchain.BitcoinTestNet -> "bitcoin"
|
||||
Blockchain.Ethereum -> "ethereum"
|
||||
Blockchain.EthereumTestNet -> "ethereum"
|
||||
Blockchain.Token -> "ethereum"
|
||||
Blockchain.NftToken -> "ethereum"
|
||||
Blockchain.BitcoinCash -> "bitcoin-cash"
|
||||
Blockchain.Litecoin -> "litecoin"
|
||||
Blockchain.Rootstock -> "bitcoin"
|
||||
Blockchain.RootstockToken -> "bitcoin"
|
||||
Blockchain.Cardano -> "cardano"
|
||||
Blockchain.Ripple -> "ripple"
|
||||
else -> {
|
||||
throw Exception("Can''t get rate for blockchain " + ctx.blockchainName)
|
||||
}
|
||||
}
|
||||
serverApiCommon.requestRateInfo(cryptoId)
|
||||
}
|
||||
|
||||
private fun loadRateInfo() {
|
||||
serverApiCommon.setRateInfoListener {
|
||||
val rate = it.priceUsd.toFloat()
|
||||
this.rate.value = rate
|
||||
}
|
||||
}
|
||||
}
|
||||
340
app/src/main/java/com/tangem/ui/fragment/MainFragment.kt
Normal file
340
app/src/main/java/com/tangem/ui/fragment/MainFragment.kt
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
package com.tangem.ui.fragment
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.nfc.NfcAdapter
|
||||
import android.nfc.Tag
|
||||
import android.nfc.tech.IsoDep
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.widget.PopupMenu
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.card_android.android.nfc.NfcDeviceAntennaLocation
|
||||
import com.tangem.card_android.android.nfc.NfcLifecycleObserver
|
||||
import com.tangem.card_android.android.reader.NfcManager
|
||||
import com.tangem.card_android.android.reader.NfcReader
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.card_android.data.loadFromBundle
|
||||
import com.tangem.card_android.data.saveToBundle
|
||||
import com.tangem.card_common.data.TangemCard
|
||||
import com.tangem.card_common.reader.CardProtocol
|
||||
import com.tangem.card_common.tasks.CustomReadCardTask
|
||||
import com.tangem.card_common.tasks.ReadCardInfoTask
|
||||
import com.tangem.data.Logger
|
||||
import com.tangem.data.network.ServerApiCommon
|
||||
import com.tangem.ui.activity.MainActivity
|
||||
import com.tangem.ui.activity.PinRequestActivity
|
||||
import com.tangem.ui.dialog.NoExtendedLengthSupportDialog
|
||||
import com.tangem.ui.dialog.WaitSecurityDelayDialog
|
||||
import com.tangem.util.CommonUtil
|
||||
import com.tangem.util.LOG
|
||||
import com.tangem.util.UtilHelper
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import com.tangem.wallet.CoinEngineFactory
|
||||
import com.tangem.wallet.R
|
||||
import com.tangem.wallet.TangemContext
|
||||
import kotlinx.android.synthetic.main.layout_touch_card.*
|
||||
import kotlinx.android.synthetic.main.main_fragment.*
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
class MainFragment : Fragment(), NfcAdapter.ReaderCallback, CardProtocol.Notifications, androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener, PopupMenu.OnMenuItemClickListener {
|
||||
|
||||
companion object {
|
||||
fun newInstance() = MainFragment()
|
||||
val TAG: String = MainFragment::class.java.simpleName
|
||||
}
|
||||
|
||||
private lateinit var viewModel: MainViewModel
|
||||
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
|
||||
private var unsuccessReadCount = 0
|
||||
private lateinit var nfcManager: NfcManager
|
||||
private var task: CustomReadCardTask? = null
|
||||
private var lastTag: Tag? = null
|
||||
private var zipFile: File? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
nfcManager = NfcManager(activity!!, this)
|
||||
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
setHasOptionsMenu(true)
|
||||
return inflater.inflate(R.layout.main_fragment, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
rippleBackgroundNfc.startRippleAnimation()
|
||||
|
||||
// init NFC Antenna
|
||||
nfcDeviceAntenna = NfcDeviceAntennaLocation(context!!, ivHandCardHorizontal, ivHandCardVertical, llHand, llNfc)
|
||||
nfcDeviceAntenna.init()
|
||||
|
||||
// set phone name
|
||||
if (nfcDeviceAntenna.fullName != "")
|
||||
tvNFCHint.text = String.format(getString(R.string.scan_banknote), nfcDeviceAntenna.fullName)
|
||||
else
|
||||
tvNFCHint.text = String.format(getString(R.string.scan_banknote), getString(R.string.phone))
|
||||
|
||||
// set listeners
|
||||
fab.setOnClickListener { showMenu(it) }
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
|
||||
|
||||
// show snackbar about new version app
|
||||
viewModel.getVersionName().observe(this, Observer { text ->
|
||||
(activity as MainActivity).toastHelper.showSnackbarUpdateVersion(context!!, cl, text)
|
||||
})
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
nfcDeviceAntenna.animate()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
task?.cancel(true)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
task?.cancel(true)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun onTagDiscovered(tag: Tag) {
|
||||
try {
|
||||
// get IsoDep handle and run cardReader thread
|
||||
val isoDep = IsoDep.get(tag)
|
||||
if (unsuccessReadCount < 2)
|
||||
isoDep.timeout = 2000 + 5000 * unsuccessReadCount
|
||||
else
|
||||
isoDep.timeout = 90000
|
||||
|
||||
lastTag = tag
|
||||
|
||||
task = ReadCardInfoTask(NfcReader(nfcManager, isoDep), App.localStorage, App.pinStorage, this)
|
||||
task?.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
nfcManager.notifyReadResult(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onReadStart(cardProtocol: CardProtocol) {
|
||||
rlProgressBar?.post { rlProgressBar?.visibility = View.VISIBLE }
|
||||
}
|
||||
|
||||
override fun onReadProgress(protocol: CardProtocol, progress: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onReadFinish(cardProtocol: CardProtocol?) {
|
||||
task = null
|
||||
if (cardProtocol != null) {
|
||||
if (cardProtocol.error == null) {
|
||||
nfcManager.notifyReadResult(true)
|
||||
rlProgressBar?.post {
|
||||
rlProgressBar?.visibility = View.GONE
|
||||
|
||||
// TODO - ??? remove save and load???
|
||||
val cardInfo = Bundle()
|
||||
val bCard = Bundle()
|
||||
|
||||
cardInfo.putString(EXTRA_TANGEM_CARD_UID, cardProtocol.card.uid)
|
||||
cardInfo.putBundle(EXTRA_TANGEM_CARD, bCard)
|
||||
cardProtocol.card.saveToBundle(bCard)
|
||||
|
||||
val uid = cardInfo.getString(EXTRA_TANGEM_CARD_UID)
|
||||
val card = TangemCard(uid)
|
||||
cardInfo.getBundle(EXTRA_TANGEM_CARD)?.let { card.loadFromBundle(it) }
|
||||
|
||||
val ctx = TangemContext(card)
|
||||
when {
|
||||
card.status == TangemCard.Status.Loaded -> lastTag?.let {
|
||||
val engineCoin = CoinEngineFactory.create(ctx)
|
||||
if (engineCoin != null) {
|
||||
engineCoin.defineWallet()
|
||||
|
||||
// val bundle = Bundle()
|
||||
// bundle.putParcelable(Constant.EXTRA_LAST_DISCOVERED_TAG, lastTag)
|
||||
// ctx.saveToBundle(bundle)
|
||||
// (activity as MainActivity).navController.navigate(R.id.loadedWallet, bundle)
|
||||
|
||||
(activity as MainActivity).navigator.showLoadedWallet(activity!!, it, ctx)
|
||||
}
|
||||
}
|
||||
card.status == TangemCard.Status.Empty -> (activity as MainActivity).navigator.showEmptyWallet(activity!!, ctx)
|
||||
card.status == TangemCard.Status.Purged -> Toast.makeText(context, R.string.erased_wallet, Toast.LENGTH_SHORT).show()
|
||||
card.status == TangemCard.Status.NotPersonalized -> Toast.makeText(context, R.string.not_personalized, Toast.LENGTH_SHORT).show()
|
||||
else -> {
|
||||
|
||||
// val bundle = Bundle()
|
||||
// bundle.putParcelable(Constant.EXTRA_LAST_DISCOVERED_TAG, lastTag)
|
||||
// ctx.saveToBundle(bundle)
|
||||
// navController.navigate(R.id.loadedWallet, bundle)
|
||||
|
||||
// lastTag?.let { navigator.showLoadedWallet(this, it, ctx) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// remove last UIDs because of error and no card read
|
||||
rlProgressBar.post {
|
||||
Toast.makeText(context, R.string.try_to_scan_again, Toast.LENGTH_SHORT).show()
|
||||
unsuccessReadCount++
|
||||
|
||||
if (cardProtocol.error is CardProtocol.TangemException_InvalidPIN)
|
||||
(activity as MainActivity).navigator.showPinRequest(activity!!, PinRequestActivity.Mode.RequestPIN.toString())
|
||||
else {
|
||||
if (cardProtocol.error is CardProtocol.TangemException_ExtendedLengthNotSupported)
|
||||
if (!NoExtendedLengthSupportDialog.allReadyShowed)
|
||||
NoExtendedLengthSupportDialog().show(activity!!.supportFragmentManager, NoExtendedLengthSupportDialog.TAG)
|
||||
|
||||
lastTag = null
|
||||
ReadCardInfoTask.resetLastReadInfo()
|
||||
nfcManager.notifyReadResult(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rlProgressBar.postDelayed({
|
||||
try {
|
||||
rlProgressBar.visibility = View.GONE
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
override fun onReadCancel() {
|
||||
task = null
|
||||
ReadCardInfoTask.resetLastReadInfo()
|
||||
rlProgressBar.postDelayed({
|
||||
try {
|
||||
rlProgressBar.visibility = View.GONE
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when (requestCode) {
|
||||
Constant.REQUEST_CODE_SEND_EMAIL -> {
|
||||
if (zipFile != null) {
|
||||
zipFile!!.delete()
|
||||
zipFile = null
|
||||
}
|
||||
}
|
||||
Constant.REQUEST_CODE_ENTER_PIN_ACTIVITY -> {
|
||||
if (resultCode == Activity.RESULT_OK && lastTag != null)
|
||||
onTagDiscovered(lastTag!!)
|
||||
else
|
||||
ReadCardInfoTask.resetLastReadInfo()
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_main, menu)
|
||||
if (BuildConfig.DEBUG) {
|
||||
for (i in 0 until menu.size()) menu.getItem(i).isVisible = true
|
||||
}
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.sendLogs -> {
|
||||
var f: File? = null
|
||||
try {
|
||||
f = Logger.collectLogs(activity)
|
||||
if (f != null) {
|
||||
LOG.e(TAG, String.format("Collect %d log bytes", f.length()))
|
||||
CommonUtil.sendEmail(activity, zipFile, TAG, "Logs", UtilHelper.getDeviceInfo(), arrayOf(f))
|
||||
} else {
|
||||
LOG.e(TAG, "Can't create temporarily log file")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
if (f != null && f.exists())
|
||||
f.delete()
|
||||
}
|
||||
return true
|
||||
}
|
||||
R.id.managePIN -> {
|
||||
(activity as MainActivity).navigator.showPinSave(activity!!, false)
|
||||
// (activity as MainActivity).navController.navigate(R.id.pinSaveActivity)
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.managePIN2 -> {
|
||||
(activity as MainActivity).navigator.showPinSave(activity!!, true)
|
||||
// (activity as MainActivity).navController.navigate(R.id.pinSaveActivity)
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.settings -> {
|
||||
(activity as MainActivity).navigator.showSettings(activity!!)
|
||||
// (activity as MainActivity).navController.navigate(R.id.settingsActivity)
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.about -> {
|
||||
(activity as MainActivity).navigator.showLogo(activity!!, false)
|
||||
// (activity as MainActivity).navController.navigate(R.id.logoActivity)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onReadWait(msec: Int) {
|
||||
WaitSecurityDelayDialog.onReadWait(Objects.requireNonNull(activity) as AppCompatActivity?, msec)
|
||||
}
|
||||
|
||||
override fun onReadBeforeRequest(timeout: Int) {
|
||||
WaitSecurityDelayDialog.onReadBeforeRequest(Objects.requireNonNull(activity) as AppCompatActivity?, timeout)
|
||||
}
|
||||
|
||||
override fun onReadAfterRequest() {
|
||||
WaitSecurityDelayDialog.onReadAfterRequest(Objects.requireNonNull(activity))
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(item: MenuItem?): Boolean {
|
||||
return onOptionsItemSelected(item!!)
|
||||
}
|
||||
|
||||
private fun showMenu(v: View) {
|
||||
val popup = PopupMenu(context, 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()
|
||||
}
|
||||
|
||||
}
|
||||
38
app/src/main/java/com/tangem/ui/fragment/MainViewModel.kt
Normal file
38
app/src/main/java/com/tangem/ui/fragment/MainViewModel.kt
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.ui.fragment
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.tangem.Constant
|
||||
import com.tangem.data.network.ServerApiCommon
|
||||
import com.tangem.wallet.BuildConfig
|
||||
|
||||
class MainViewModel : ViewModel() {
|
||||
private var serverApiCommon: ServerApiCommon = ServerApiCommon()
|
||||
|
||||
private var versionName = MutableLiveData<String>()
|
||||
|
||||
fun getVersionName(): LiveData<String> {
|
||||
versionName = MutableLiveData()
|
||||
requestVersionName()
|
||||
return versionName
|
||||
}
|
||||
|
||||
private fun requestVersionName() {
|
||||
serverApiCommon.setLastVersionListener { response ->
|
||||
try {
|
||||
if (response.isNullOrEmpty())
|
||||
return@setLastVersionListener
|
||||
val responseVersionName = response.trim(' ', '\n', '\r', '\t')
|
||||
val responseBuildVersion = responseVersionName.split('.').last()
|
||||
val appBuildVersion = BuildConfig.VERSION_NAME.split('.').last()
|
||||
if (responseBuildVersion.toInt() > appBuildVersion.toInt())
|
||||
if (BuildConfig.FLAVOR.equals(Constant.FLAVOR_TANGEM_ACCESS))
|
||||
versionName.value = responseVersionName
|
||||
} catch (E: Exception) {
|
||||
E.printStackTrace()
|
||||
}
|
||||
}
|
||||
serverApiCommon.requestLastVersion()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
package com.tangem.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.tangem.wallet.R
|
||||
|
||||
class Settings : PreferenceFragmentCompat() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.pref_main)
|
||||
}
|
||||
|
||||
}
|
||||
25
app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt
Normal file
25
app/src/main/java/com/tangem/ui/fragment/SettingsFragment.kt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import com.tangem.wallet.R
|
||||
|
||||
class SettingsFragment : PreferenceFragmentCompat() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.pref_main)
|
||||
|
||||
val categoryCommon = findPreference<PreferenceCategory>(getString(R.string.pref_category_common))
|
||||
val selectNodes = findPreference<Preference>(getString(R.string.pref_select_nodes))
|
||||
val encryptionModes = findPreference<ListPreference>(getString(R.string.pref_encryption_modes))
|
||||
|
||||
if (!BuildConfig.DEBUG) {
|
||||
categoryCommon?.removePreference(selectNodes)
|
||||
categoryCommon?.removePreference(encryptionModes)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ public class TangemContext {
|
|||
}
|
||||
|
||||
public TangemContext(TangemCard card) {
|
||||
|
||||
this.card = card;
|
||||
}
|
||||
|
||||
|
|
@ -135,6 +136,21 @@ public class TangemContext {
|
|||
return tangemContext;
|
||||
}
|
||||
|
||||
public void saveToBundle(Bundle intent) {
|
||||
|
||||
if (card != null) {
|
||||
intent.putString(TangemCardExtensionsKt.EXTRA_TANGEM_CARD_UID, card.getUID());
|
||||
intent.putBundle(TangemCardExtensionsKt.EXTRA_TANGEM_CARD, TangemCardExtensionsKt.getAsBundle(card));
|
||||
}
|
||||
|
||||
if (coinData != null) {
|
||||
intent.putBundle(Constant.EXTRA_BLOCKCHAIN_DATA, coinData.asBundle());
|
||||
}
|
||||
|
||||
intent.putString("Error", error);
|
||||
intent.putString("Message", message);
|
||||
}
|
||||
|
||||
public void saveToIntent(Intent intent) {
|
||||
|
||||
if (card != null) {
|
||||
|
|
@ -148,7 +164,6 @@ public class TangemContext {
|
|||
|
||||
intent.putExtra("Error", error);
|
||||
intent.putExtra("Message", message);
|
||||
|
||||
}
|
||||
|
||||
public String getString(int stringId) {
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.tangem.ui.activity.LoadedWalletActivity">
|
||||
|
||||
<fragment
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/loaded_wallet_fragment"
|
||||
android:name="com.tangem.ui.fragment.LoadedWallet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:layout="@layout/fr_loaded_wallet"/>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.tangem.ui.activity.LoadedWalletActivity">
|
||||
|
||||
<fragment
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/loaded_wallet_fragment"
|
||||
android:name="com.tangem.ui.fragment.LoadedWalletFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:layout="@layout/fr_loaded_wallet"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -1,58 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/cl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.tangem.ui.activity.MainActivity"
|
||||
tools:ignore="contentDescription">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llTapPrompt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/actionbar_text"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
app:srcCompat="@drawable/tangem_logo_full_new" />
|
||||
|
||||
<include layout="@layout/layout_touch_card" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvNFCHint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:fontFamily="@font/maax"
|
||||
android:gravity="center"
|
||||
android:lineSpacingExtra="8dp"
|
||||
android:minHeight="200dp"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingBottom="20dp"
|
||||
android:text="@string/tap_tangem_card"
|
||||
android:textAlignment="center"
|
||||
android:textAllCaps="false"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textColor="@color/primary_dark"
|
||||
android:textSize="@dimen/text_size_medium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_margin="10dp"
|
||||
android:src="@drawable/ic_show_menu"
|
||||
app:backgroundTint="@color/colorPrimary"
|
||||
app:fabSize="normal" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.tangem.ui.activity.MainActivity">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/main_graph" />
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
<fragment
|
||||
android:id="@+id/thanks_fragment"
|
||||
android:name="com.tangem.ui.fragment.Settings"
|
||||
android:name="com.tangem.ui.fragment.SettingsFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/abl"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
android:background="@color/white"
|
||||
android:orientation="vertical"
|
||||
android:padding="0dp"
|
||||
tools:context="com.tangem.ui.fragment.LoadedWallet"
|
||||
tools:context="com.tangem.ui.fragment.LoadedWalletFragment"
|
||||
tools:ignore="contentDescription"
|
||||
tools:showIn="@layout/activity_loaded_wallet">
|
||||
|
||||
|
|
|
|||
58
app/src/main/res/layout/main_fragment.xml
Normal file
58
app/src/main/res/layout/main_fragment.xml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/cl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.tangem.ui.activity.MainActivity"
|
||||
tools:ignore="contentDescription">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llTapPrompt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/actionbar_text"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
app:srcCompat="@drawable/tangem_logo_full_new" />
|
||||
|
||||
<include layout="@layout/layout_touch_card" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvNFCHint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:fontFamily="@font/maax"
|
||||
android:gravity="center"
|
||||
android:lineSpacingExtra="8dp"
|
||||
android:minHeight="200dp"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:paddingBottom="20dp"
|
||||
android:text="@string/tap_tangem_card"
|
||||
android:textAlignment="center"
|
||||
android:textAllCaps="false"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textColor="@color/primary_dark"
|
||||
android:textSize="@dimen/text_size_medium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_margin="10dp"
|
||||
android:src="@drawable/ic_show_menu"
|
||||
app:backgroundTint="@color/colorPrimary"
|
||||
app:fabSize="normal" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -1,25 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/managePIN"
|
||||
android:enabled="false"
|
||||
android:title="@string/manage_user_pin_1" />
|
||||
<item
|
||||
android:id="@+id/managePIN2"
|
||||
android:enabled="false"
|
||||
android:title="@string/manage_user_pin_2" />
|
||||
<item
|
||||
android:id="@+id/sendLogs"
|
||||
android:title="@string/send_logs"
|
||||
android:visible="false" />
|
||||
|
||||
<item
|
||||
android:id="@+id/settings"
|
||||
android:visible="false"
|
||||
android:title="@string/settings" />
|
||||
|
||||
<item
|
||||
android:id="@+id/about"
|
||||
android:title="@string/about" />
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/managePIN"
|
||||
android:enabled="false"
|
||||
android:title="@string/manage_user_pin_1" />
|
||||
<item
|
||||
android:id="@+id/managePIN2"
|
||||
android:enabled="false"
|
||||
android:title="@string/manage_user_pin_2" />
|
||||
<item
|
||||
android:id="@+id/sendLogs"
|
||||
android:title="@string/send_logs"
|
||||
android:visible="false" />
|
||||
|
||||
<item
|
||||
android:id="@+id/settings"
|
||||
android:title="@string/settings" />
|
||||
|
||||
<item
|
||||
android:id="@+id/about"
|
||||
android:title="@string/about" />
|
||||
</menu>
|
||||
16
app/src/main/res/navigation/main_graph.xml
Normal file
16
app/src/main/res/navigation/main_graph.xml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main_graph"
|
||||
app:startDestination="@id/main">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/main"
|
||||
android:name="com.tangem.ui.fragment.MainFragment"
|
||||
android:label="fragment_main"
|
||||
tools:layout="@layout/main_fragment">
|
||||
|
||||
</fragment>
|
||||
|
||||
</navigation>
|
||||
|
|
@ -58,6 +58,8 @@
|
|||
<string name="cardano">Cardano</string>
|
||||
|
||||
<!-- SettingsActivity -->
|
||||
<string name="сommon">Common</string>
|
||||
<string name="manual_editing_fee">Manual editing Fee</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="encryption_modes">Encryption modes</string>
|
||||
<string-array name="encryption_modes_entries">
|
||||
|
|
@ -115,7 +117,7 @@
|
|||
<string name="new_app_version">There is a new application version: %1$s</string>
|
||||
<string name="update">Update</string>
|
||||
|
||||
<!-- LoadedWalletActivity, LoadedWallet -->
|
||||
<!-- LoadedWalletActivity, LoadedWalletFragment -->
|
||||
<string name="wallet_empty">The wallet is empty</string>
|
||||
<string name="no_compatible_wallet">No compatible wallets installed</string>
|
||||
<string name="please_wait_while_previous">Please wait while previous transaction is confirmed in blockchain</string>
|
||||
|
|
@ -217,6 +219,7 @@
|
|||
<string name="pin_2_is_required_to_sign_the_transaction">PIN2 is required to sign the payment</string>
|
||||
<string name="not_enough_funds">Not enough funds</string>
|
||||
<string name="service_unavailable">Service unavailable</string>
|
||||
<string name="risk_delaying">You have a risk of delaying transaction</string>
|
||||
|
||||
<!-- EmptyWalletActivity -->
|
||||
<string name="wallet_has_not_been_yet_created">Wallet hasn\'t been yet created</string>
|
||||
|
|
|
|||
|
|
@ -23,4 +23,9 @@
|
|||
<string name="log_file_provider_authorities">com.tangem.data.LogFileProvider</string>
|
||||
<string name="ex_cant_create_coinEngine">Can\'t create CoinEngine!</string>
|
||||
|
||||
<string name="pref_category_common">category_common</string>
|
||||
<string name="pref_manual_editing_fee">manual_editing_fee</string>
|
||||
<string name="pref_select_nodes">select_nodes</string>
|
||||
<string name="pref_encryption_modes">encryption_modes</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,25 @@
|
|||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory android:title="Common">
|
||||
<PreferenceCategory
|
||||
android:key="@string/pref_category_common"
|
||||
android:title="@string/сommon">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/pref_manual_editing_fee"
|
||||
android:title="@string/manual_editing_fee" />
|
||||
|
||||
<Preference
|
||||
android:defaultValue="true"
|
||||
android:key="select_nodes"
|
||||
android:key="@string/pref_select_nodes"
|
||||
android:title="@string/select_nodes" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/encryption_modes_entries"
|
||||
android:entryValues="@array/encryption_mode_values"
|
||||
android:key="encryption_modes"
|
||||
android:key="@string/pref_encryption_modes"
|
||||
android:title="@string/encryption_modes" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
</PreferenceScreen>
|
||||
|
|
@ -2,40 +2,49 @@ package com.tangem.ui
|
|||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.nfc.NfcAdapter
|
||||
import android.nfc.Tag
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.preference.PreferenceManager
|
||||
import android.text.Editable
|
||||
import android.text.Html
|
||||
import android.text.TextWatcher
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.wallet.CoinEngine
|
||||
import com.tangem.wallet.CoinEngineFactory
|
||||
import com.tangem.wallet.TangemContext
|
||||
import com.tangem.ui.event.TransactionFinishWithError
|
||||
import com.tangem.card_android.android.nfc.NfcLifecycleObserver
|
||||
import com.tangem.card_android.android.reader.NfcManager
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.card_android.data.loadFromBundle
|
||||
import com.tangem.card_common.data.TangemCard
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.di.ToastHelper
|
||||
import com.tangem.ui.activity.PinRequestActivity
|
||||
import com.tangem.ui.activity.SignTransactionActivity
|
||||
import com.tangem.ui.event.TransactionFinishWithError
|
||||
import com.tangem.util.UtilHelper
|
||||
import com.tangem.wallet.CoinEngine
|
||||
import com.tangem.wallet.CoinEngineFactory
|
||||
import com.tangem.wallet.R
|
||||
import com.tangem.wallet.TangemContext
|
||||
import kotlinx.android.synthetic.tangemAccess.activity_confirm_transaction.*
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD
|
||||
import com.tangem.card_android.data.EXTRA_TANGEM_CARD_UID
|
||||
import com.tangem.ui.activity.PinRequestActivity
|
||||
import com.tangem.ui.activity.SignTransactionActivity
|
||||
import kotlinx.android.synthetic.tangemAccess.activity_confirm_transaction.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallback {
|
||||
|
||||
@Inject
|
||||
internal lateinit var toastHelper: ToastHelper
|
||||
|
||||
private lateinit var sp: SharedPreferences
|
||||
private lateinit var nfcManager: NfcManager
|
||||
private lateinit var ctx: TangemContext
|
||||
private lateinit var amount: CoinEngine.Amount
|
||||
|
|
@ -49,6 +58,10 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
|
|||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_confirm_transaction)
|
||||
|
||||
App.toastHelperComponent.inject(this)
|
||||
|
||||
sp = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
||||
nfcManager = NfcManager(this, this)
|
||||
lifecycle.addObserver(NfcLifecycleObserver(nfcManager))
|
||||
|
||||
|
|
@ -95,6 +108,8 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
|
|||
rgFee.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
etFee.isEnabled = sp.getBoolean(getString(R.string.pref_manual_editing_fee), false)
|
||||
|
||||
// set listeners
|
||||
rgFee.setOnCheckedChangeListener { _, checkedId -> doSetFee(checkedId) }
|
||||
etFee.addTextChangedListener(object : TextWatcher {
|
||||
|
|
@ -114,6 +129,9 @@ class ConfirmTransactionActivity : AppCompatActivity(), NfcAdapter.ReaderCallbac
|
|||
} else
|
||||
tvFeeEquivalent.error = null
|
||||
|
||||
if (sp.getBoolean(getString(R.string.pref_manual_editing_fee), false))
|
||||
toastHelper.showSingleToast(this@ConfirmTransactionActivity, getString(R.string.risk_delaying))
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
tvFeeEquivalent.text = ""
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/cl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.tangem.ui.ConfirmTransactionActivity"
|
||||
|
|
@ -148,35 +149,36 @@
|
|||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etAmount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:digits="0123456789.,"
|
||||
android:fontFamily="@font/maax"
|
||||
android:hint="@string/payment_amount"
|
||||
android:hint="@string/enter_amount"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="numberDecimal"
|
||||
android:padding="12dp"
|
||||
android:textColor="@color/black"
|
||||
android:textColorLink="@color/colorPrimary"
|
||||
android:textSize="@dimen/text_size_1_large"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvCurrency"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_min="150dp"
|
||||
tools:text="1.34343434343443434343434" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrency"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:fontFamily="@font/maax"
|
||||
android:text="@string/m_btc"
|
||||
android:textColor="@color/primary"
|
||||
android:textSize="@dimen/text_size_1_large"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
@ -266,7 +268,6 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:enabled="false"
|
||||
android:fontFamily="@font/maax"
|
||||
android:hint="@string/fee_amount"
|
||||
android:inputType="numberDecimal"
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@
|
|||
|
||||
<EditText
|
||||
android:id="@+id/etAmount"
|
||||
tools:text="1.34343434343443434343434"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:digits="0123456789.,"
|
||||
|
|
|
|||
|
|
@ -152,35 +152,36 @@
|
|||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etAmount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:enabled="false"
|
||||
android:digits="0123456789.,"
|
||||
android:fontFamily="@font/maax"
|
||||
android:hint="@string/payment_amount"
|
||||
android:hint="@string/enter_amount"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="numberDecimal"
|
||||
android:padding="12dp"
|
||||
android:textColor="@color/black"
|
||||
android:textColorLink="@color/colorPrimary"
|
||||
android:textSize="@dimen/text_size_1_large"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/tvCurrency"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_min="150dp"
|
||||
tools:text="1.34343434343443434343434" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCurrency"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:fontFamily="@font/maax"
|
||||
android:text="@string/m_btc"
|
||||
android:textColor="@color/primary"
|
||||
android:textSize="@dimen/text_size_1_large"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ dependencies {
|
|||
implementation project(':card-common')
|
||||
// implementation 'com.github.TangemCash.card_android-common:card_android-android:0.1.0'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
implementation 'com.scottyab:rootbeer-lib:0.0.7'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
|
|
|||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,4 +1,4 @@
|
|||
#Thu Apr 18 15:14:06 MSK 2019
|
||||
#Thu Apr 18 12:21:12 MSK 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ dependencies {
|
|||
implementation project(':card-common')
|
||||
// implementation 'com.github.TangemCash.card_android-common:card_android-android:0.1.0'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha04'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue