Updated on 2026-08-14
This commit is contained in:
parent
005f7295b5
commit
e82a584e8b
15 changed files with 272 additions and 144 deletions
|
|
@ -38,9 +38,9 @@ dependencies {
|
|||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'com.google.android.material:material:1.1.0-beta01'
|
||||
implementation 'com.skyfishjy.ripplebackground:library:1.0.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.1.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
|
||||
implementation "androidx.lifecycle:lifecycle-runtime:2.1.0"
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:2.1.0"
|
||||
|
|
|
|||
|
|
@ -1,66 +1,117 @@
|
|||
package com.tangem.tangem_sdk_new
|
||||
|
||||
import android.view.View
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.tangem.CardManagerDelegate
|
||||
import com.tangem.Log
|
||||
import com.tangem.tasks.Task
|
||||
import com.tangem.LoggerInterface
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.tangem_sdk_new.nfc.NfcReader
|
||||
import com.tangem.tangem_sdk_new.ui.NfcEnableDialog
|
||||
import com.tangem.tangem_sdk_new.ui.TouchCardAnimation
|
||||
import com.tangem.tasks.TaskError
|
||||
import kotlinx.android.synthetic.main.layout_touch_card.*
|
||||
import kotlinx.android.synthetic.main.nfc_bottom_sheet.*
|
||||
|
||||
|
||||
class DefaultCardManagerDelegate(private val activity: FragmentActivity, private val reader: NfcReader) : CardManagerDelegate {
|
||||
class DefaultCardManagerDelegate(private val reader: NfcReader) : CardManagerDelegate {
|
||||
|
||||
private var dialog: BottomSheetDialog? = null
|
||||
lateinit var activity: FragmentActivity
|
||||
private var readingDialog: BottomSheetDialog? = null
|
||||
private var nfcEnableDialog: NfcEnableDialog? = null
|
||||
|
||||
private var task: Task<*>? = null
|
||||
|
||||
override fun showSecurityDelay(ms: Int) {
|
||||
// activity.runOnUiThread{
|
||||
// activity.tv_security_delay?.text = "Security delay. $ms left."
|
||||
// }
|
||||
init {
|
||||
setLogger()
|
||||
}
|
||||
|
||||
override fun requestPin(success: () -> String, error: (cardError: TaskError.CardError) -> TaskError.CardError) {
|
||||
override fun onTaskStarted() {
|
||||
// reader.isoDep = null
|
||||
reader.readingCancelled = false
|
||||
postUI { showReadingDialog(activity) }
|
||||
if (!reader.nfcEnabled) showNFCEnableDialog()
|
||||
}
|
||||
|
||||
private fun showReadingDialog(activity: FragmentActivity) {
|
||||
val dialogView = activity.getLayoutInflater().inflate(R.layout.nfc_bottom_sheet, null)
|
||||
readingDialog = BottomSheetDialog(activity)
|
||||
readingDialog?.setContentView(dialogView)
|
||||
readingDialog?.dismissWithAnimation = true
|
||||
readingDialog?.create()
|
||||
readingDialog?.setOnShowListener {
|
||||
readingDialog?.rippleBackgroundNfc?.startRippleAnimation()
|
||||
val nfcDeviceAntenna = TouchCardAnimation(
|
||||
activity, readingDialog!!.ivHandCardHorizontal,
|
||||
readingDialog!!.ivHandCardVertical, readingDialog!!.llHand, readingDialog!!.llNfc)
|
||||
nfcDeviceAntenna.init()
|
||||
}
|
||||
readingDialog?.setOnCancelListener {
|
||||
reader.readingCancelled = true
|
||||
// reader.closeSession()
|
||||
Log.i(this::class.simpleName!!, "readingCancelled is set to true")
|
||||
}
|
||||
readingDialog?.show()
|
||||
}
|
||||
|
||||
private fun showNFCEnableDialog() {
|
||||
nfcEnableDialog = NfcEnableDialog()
|
||||
activity.supportFragmentManager.let { nfcEnableDialog?.show(it, NfcEnableDialog.TAG) }
|
||||
}
|
||||
|
||||
override fun showSecurityDelay(ms: Int) {
|
||||
postUI {
|
||||
readingDialog?.lTouchCard?.visibility = View.GONE
|
||||
readingDialog?.tvRemainingTime?.text = ms.div(100).toString()
|
||||
readingDialog?.flSecurityDelay?.visibility = View.VISIBLE
|
||||
readingDialog?.tvTaskTitle?.text = activity.getText(R.string.dialog_security_delay)
|
||||
readingDialog?.tvTaskText?.text =
|
||||
activity.getText(R.string.dialog_security_delay_description)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTaskCompleted() {
|
||||
reader.closeSession()
|
||||
postUI {
|
||||
readingDialog?.lTouchCard?.visibility = View.GONE
|
||||
readingDialog?.flSecurityDelay?.visibility = View.GONE
|
||||
readingDialog?.flCompletion?.visibility = View.VISIBLE
|
||||
readingDialog?.ivCompletion?.setImageDrawable(activity.getDrawable(R.drawable.ic_done_135dp))
|
||||
}
|
||||
postUI(300) { readingDialog?.dismiss() }
|
||||
}
|
||||
|
||||
override fun onTaskError(error: TaskError?) {
|
||||
reader.closeSession()
|
||||
postUI {
|
||||
readingDialog?.lTouchCard?.visibility = View.GONE
|
||||
readingDialog?.flSecurityDelay?.visibility = View.GONE
|
||||
readingDialog?.flCompletion?.visibility = View.VISIBLE
|
||||
readingDialog?.ivCompletion?.setImageDrawable(activity.getDrawable(R.drawable.ic_error_outline_135dp))
|
||||
readingDialog?.tvTaskTitle?.text = activity.getText(R.string.dialog_error)
|
||||
readingDialog?.tvTaskText?.text = if (error != null) error::class.simpleName else ""
|
||||
}
|
||||
}
|
||||
|
||||
override fun requestPin(callback: (result: CompletionResult<String>) -> Unit) {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun openNfcPopup() {
|
||||
|
||||
private fun setLogger() {
|
||||
Log.setLogger(
|
||||
object : LoggerInterface {
|
||||
override fun i(logTag: String, message: String) {
|
||||
android.util.Log.i(logTag, message)
|
||||
}
|
||||
|
||||
activity.runOnUiThread {
|
||||
val dialogView = activity.getLayoutInflater().inflate(R.layout.nfc_bottom_sheet, null)
|
||||
|
||||
dialog = BottomSheetDialog(activity)
|
||||
dialog?.setContentView(dialogView)
|
||||
dialog?.dismissWithAnimation
|
||||
dialog?.create()
|
||||
// .setTitle("NFC reader mode")
|
||||
dialog?.setOnShowListener {
|
||||
dialog!!.rippleBackgroundNfc?.startRippleAnimation()
|
||||
|
||||
// init NFC Antenna
|
||||
val nfcDeviceAntenna = TouchCardAnimation(
|
||||
activity, dialog!!.ivHandCardHorizontal,
|
||||
dialog!!.ivHandCardVertical, dialog!!.llHand, dialog!!.llNfc)
|
||||
nfcDeviceAntenna.init()
|
||||
}
|
||||
dialog?.setOnDismissListener {
|
||||
reader.readingCancelled = false
|
||||
task = null
|
||||
Log.i(this::class.simpleName!!, "readingCancelled is set to true")
|
||||
}
|
||||
dialog?.show()
|
||||
}
|
||||
Log.i(this::class.simpleName!!, "Nfc PopUp is opened")
|
||||
}
|
||||
|
||||
override fun closeNfcPopup() {
|
||||
task = null
|
||||
activity.runOnUiThread {
|
||||
dialog?.dismiss()
|
||||
}
|
||||
Log.i(this::class.simpleName!!, "Nfc PopUp is closed")
|
||||
override fun e(logTag: String, message: String) {
|
||||
android.util.Log.e(logTag, message)
|
||||
}
|
||||
|
||||
override fun v(logTag: String, message: String) {
|
||||
android.util.Log.v(logTag, message)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +1,26 @@
|
|||
package com.tangem.tangem_sdk_new
|
||||
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.OnLifecycleEvent
|
||||
import com.tangem.tangem_sdk_new.nfc.NfcManager
|
||||
|
||||
|
||||
class NfcLifecycleObserver(private var nfcManager: NfcManager) : DefaultLifecycleObserver {
|
||||
class NfcLifecycleObserver(private var nfcManager: NfcManager) : LifecycleObserver {
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
super.onResume(owner)
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
fun onResume(owner: LifecycleOwner) {
|
||||
nfcManager.onResume()
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
super.onPause(owner)
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
||||
fun onPause(owner: LifecycleOwner) {
|
||||
nfcManager.onPause()
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
super.onStop(owner)
|
||||
nfcManager.onStop()
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
|
||||
fun onDestroy(owner: LifecycleOwner) {
|
||||
nfcManager.onDestroy()
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,8 @@ package com.tangem.tangem_sdk_new
|
|||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
||||
|
||||
val uiHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
fun postUI(msTime: Long = 0, func: () -> Unit) {
|
||||
internal fun postUI(msTime: Long = 0, func: () -> Unit) {
|
||||
if (msTime > 0) uiHandler.postDelayed({ func() }, msTime) else uiHandler.post(func)
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangem_sdk_new
|
||||
package com.tangem.tangem_sdk_new.nfc
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
|
|
@ -10,20 +10,17 @@ import android.nfc.tech.IsoDep
|
|||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.tangem.Log
|
||||
|
||||
class NfcManager(private val reader: NfcReader) : NfcAdapter.ReaderCallback {
|
||||
|
||||
class NfcManager : NfcAdapter.ReaderCallback {
|
||||
|
||||
val reader = NfcReader()
|
||||
private var activity: FragmentActivity? = null
|
||||
private var nfcAdapter: NfcAdapter? = null
|
||||
private var readerCallback: NfcAdapter.ReaderCallback? = null
|
||||
// private var nfcEnableDialog: NfcEnableDialog? = null
|
||||
|
||||
|
||||
fun setCurrentActivity(activity: FragmentActivity, readerCallback: NfcAdapter.ReaderCallback) {
|
||||
fun setCurrentActivity(activity: FragmentActivity) {
|
||||
this.activity = activity
|
||||
nfcAdapter = NfcAdapter.getDefaultAdapter(activity)
|
||||
this.readerCallback = readerCallback
|
||||
}
|
||||
|
||||
private val mBroadcastReceiver = object : BroadcastReceiver() {
|
||||
|
|
@ -37,7 +34,7 @@ class NfcManager(private val reader: NfcReader) : NfcAdapter.ReaderCallback {
|
|||
}
|
||||
|
||||
override fun onTagDiscovered(tag: Tag?) {
|
||||
// reader.isoDep = IsoDep.get(tag)
|
||||
Log.i(this::class.simpleName!!, "Nfc tag is discovered")
|
||||
if (reader.readingActive) reader.onTagDiscovered(tag) else ignoreTag(tag)
|
||||
}
|
||||
|
||||
|
|
@ -46,10 +43,12 @@ class NfcManager(private val reader: NfcReader) : NfcAdapter.ReaderCallback {
|
|||
val filter = IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)
|
||||
activity?.registerReceiver(mBroadcastReceiver, filter)
|
||||
|
||||
if (nfcAdapter == null || nfcAdapter?.isEnabled != true)
|
||||
// showNFCEnableDialog()
|
||||
else
|
||||
if ((nfcAdapter == null || nfcAdapter?.isEnabled != true)) {
|
||||
reader.nfcEnabled = false
|
||||
} else {
|
||||
reader.nfcEnabled = true
|
||||
enableReaderMode()
|
||||
}
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
|
|
@ -57,31 +56,22 @@ class NfcManager(private val reader: NfcReader) : NfcAdapter.ReaderCallback {
|
|||
disableReaderMode()
|
||||
}
|
||||
|
||||
fun onStop() {
|
||||
// nfcEnableDialog?.dismiss()
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
activity = null
|
||||
nfcAdapter = null
|
||||
readerCallback = null
|
||||
}
|
||||
|
||||
// private fun showNFCEnableDialog() {
|
||||
// nfcEnableDialog = NfcEnableDialog()
|
||||
// activity?.supportFragmentManager?.let { nfcEnableDialog?.show(it, NfcEnableDialog.TAG) }
|
||||
// }
|
||||
|
||||
private fun enableReaderMode() {
|
||||
val options = Bundle()
|
||||
nfcAdapter?.enableReaderMode(activity, readerCallback, READER_FLAGS, options)
|
||||
nfcAdapter?.enableReaderMode(activity, activity as NfcAdapter.ReaderCallback, READER_FLAGS, options)
|
||||
}
|
||||
|
||||
private fun disableReaderMode() {
|
||||
nfcAdapter?.disableReaderMode(activity)
|
||||
}
|
||||
|
||||
fun ignoreTag(tag: Tag?) {
|
||||
private fun ignoreTag(tag: Tag?) {
|
||||
Log.i(this::class.simpleName!!, "Nfc tag is ignored")
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
nfcAdapter?.ignore(tag, 1500, null, null)
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangem_sdk_new
|
||||
package com.tangem.tangem_sdk_new.nfc
|
||||
|
||||
import android.nfc.Tag
|
||||
import android.nfc.tech.IsoDep
|
||||
|
|
@ -11,19 +11,29 @@ import com.tangem.tasks.TaskError
|
|||
|
||||
class NfcReader : CardReader {
|
||||
|
||||
override var readingActive = false
|
||||
var nfcEnabled = false
|
||||
var isoDep: IsoDep? = null
|
||||
set(value) {
|
||||
// if tag is received, call connect first before transceiving data
|
||||
if (field == null) {
|
||||
field = value
|
||||
connect()
|
||||
}
|
||||
// don't reassign when there's an active tag already
|
||||
if (value == null) field = value
|
||||
}
|
||||
override var readingActive = false
|
||||
|
||||
var readingCancelled = false
|
||||
set(value) {
|
||||
if (value) readingActive = false
|
||||
field = value
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
if (value) {
|
||||
// Stops reading and sends failure callback to a task
|
||||
// if reading is cancelled (when user closes nfc bottom sheet dialog).
|
||||
readingActive = false
|
||||
callback?.invoke(CompletionResult.Failure(TaskError.UserCancelledError()))
|
||||
}
|
||||
}
|
||||
|
||||
var data: ByteArray? = null
|
||||
var callback: ((response: CompletionResult<ResponseApdu>) -> Unit)? = null
|
||||
|
|
@ -33,15 +43,16 @@ class NfcReader : CardReader {
|
|||
readingCancelled = false
|
||||
}
|
||||
|
||||
override fun closeSession() {
|
||||
isoDep = null
|
||||
readingActive = false
|
||||
}
|
||||
|
||||
override fun transceiveApdu(apdu: CommandApdu, callback: (response: CompletionResult<ResponseApdu>) -> Unit) {
|
||||
data = apdu.apduData
|
||||
this.callback = callback
|
||||
if (isoDep != null) {
|
||||
try {
|
||||
transceiveData()
|
||||
} catch (exception: Exception) {
|
||||
isoDep = null
|
||||
}
|
||||
transceiveData()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,11 +61,18 @@ class NfcReader : CardReader {
|
|||
callback?.invoke(CompletionResult.Failure(TaskError.UserCancelledError()))
|
||||
return
|
||||
}
|
||||
val rawResponse = isoDep?.transceive(data)
|
||||
if (data == null) return
|
||||
|
||||
val rawResponse: ByteArray?
|
||||
try {
|
||||
rawResponse = isoDep?.transceive(data)
|
||||
} catch (exception: Exception) {
|
||||
isoDep = null
|
||||
return
|
||||
}
|
||||
if (rawResponse != null) {
|
||||
Log.i(this::class.simpleName!!, "Nfc response is received")
|
||||
data = null
|
||||
readingActive = false
|
||||
}
|
||||
rawResponse?.let { callback?.invoke(CompletionResult.Success(ResponseApdu(it))) }
|
||||
}
|
||||
|
|
@ -69,7 +87,7 @@ class NfcReader : CardReader {
|
|||
isoDep?.connect()
|
||||
isoDep?.close()
|
||||
isoDep?.connect()
|
||||
isoDep?.timeout = 120000
|
||||
isoDep?.timeout = 240000
|
||||
Log.i(this::class.simpleName!!, "Nfc session is started")
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.tangem.tangem_sdk_new.ui
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.tangem.tangem_sdk_new.R
|
||||
|
||||
class NfcEnableDialog : DialogFragment() {
|
||||
companion object {
|
||||
val TAG: String = NfcEnableDialog::class.java.simpleName
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(requireContext())
|
||||
builder.setCancelable(false)
|
||||
.setIcon(R.drawable.ic_action_nfc_gray)
|
||||
.setTitle(R.string.dialog_nfc_enable_title)
|
||||
.setMessage(R.string.dialog_nfc_enable_text)
|
||||
.setPositiveButton(R.string.general_ok
|
||||
) { _, _ ->
|
||||
activity?.startActivity(Intent(Settings.ACTION_NFC_SETTINGS))
|
||||
}
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangem_sdk_new
|
||||
package com.tangem.tangem_sdk_new.ui
|
||||
|
||||
enum class NfcLocation(val codename: String, val fullName: String, val orientation: Int, val x: Int, val y: Int, val z: Int) {
|
||||
model1("sailfish", "Google Pixel", 0, 65, 25, 0),
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tangem_sdk_new
|
||||
package com.tangem.tangem_sdk_new.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
|
|
@ -39,7 +39,7 @@ class TouchCardAnimation(private var context: Context,
|
|||
val lp = llHand.layoutParams as RelativeLayout.LayoutParams
|
||||
val lp2 = llNfc.layoutParams as RelativeLayout.LayoutParams
|
||||
val dp = context.resources.displayMetrics.density
|
||||
val lm = dp * (69 + x * 75)
|
||||
val lm = dp * (47 + x * 75)
|
||||
lp.topMargin = (dp * (-100 + y * 250)).toInt()
|
||||
lp2.topMargin = (dp * (-125 + y * 250)).toInt()
|
||||
llNfc.layoutParams = lp2
|
||||
|
|
@ -91,8 +91,8 @@ class TouchCardAnimation(private var context: Context,
|
|||
|
||||
// set card z position
|
||||
when (z) {
|
||||
TouchCardAnimation.CARD_ON_BACK -> llHand.elevation = 0.0f
|
||||
TouchCardAnimation.CARD_ON_FRONT -> llHand.elevation = 30.0f
|
||||
CARD_ON_BACK -> llHand.elevation = 0.0f
|
||||
CARD_ON_FRONT -> llHand.elevation = 30.0f
|
||||
}
|
||||
}
|
||||
|
||||
BIN
tangem-sdk-new/src/main/res/drawable/ic_action_nfc_gray.png
Normal file
BIN
tangem-sdk-new/src/main/res/drawable/ic_action_nfc_gray.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 536 B |
9
tangem-sdk-new/src/main/res/drawable/ic_done_135dp.xml
Normal file
9
tangem-sdk-new/src/main/res/drawable/ic_done_135dp.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="135dp"
|
||||
android:height="135dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="@color/colorPrimary"
|
||||
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<vector android:height="135dp" android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0" android:width="135dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/holo_red_dark" android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
|
||||
</vector>
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout 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="400dp"
|
||||
android:layout_height="250dp"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
>
|
||||
android:gravity="center_vertical|center_horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -69,38 +67,4 @@
|
|||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<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="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:alpha="0.75"
|
||||
android:background="@android:color/white" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:alpha="1"
|
||||
android:text="@string/general_status_reading"
|
||||
android:textColor="@color/colorPrimary"
|
||||
android:textSize="12dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="@dimen/size_progress_bar_big"
|
||||
android:layout_height="@dimen/size_progress_bar_big"
|
||||
android:layout_centerInParent="true"
|
||||
android:alpha="1"
|
||||
android:elevation="1dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
@ -1,18 +1,77 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTaskTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="Ready to Scan"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
|
||||
<include
|
||||
android:id="@+id/lTouchCard"
|
||||
layout="@layout/layout_touch_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="250dp"
|
||||
android:layout_height="200dp"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flSecurityDelay"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="200dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvRemainingTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textSize="40dp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pbSecurityDelay"
|
||||
android:layout_width="135dp"
|
||||
android:layout_height="135dp"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flCompletion"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="200dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivCompletion"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_done_135dp"
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTaskText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:text="\nScan card with your phone as shown above\n"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -1,4 +1,10 @@
|
|||
<resources>
|
||||
<string name="app_name">Tangem Sdk</string>
|
||||
<string name="general_status_reading">READING…</string>
|
||||
<string name="general_ok">OK</string>
|
||||
<string name="dialog_nfc_enable_title">Enable NFC?</string>
|
||||
<string name="dialog_nfc_enable_text">This app is useless when NFC is disabled. Reader mode depends on it. Hit OK to go to Settings, where you can enable NFC.</string>
|
||||
<string name="dialog_security_delay">Security delay</string>
|
||||
<string name="dialog_security_delay_description">This banknote has enforced security delay. Please hold the banknote firmly until the operation is completed…</string>
|
||||
<string name="dialog_error">Error</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue