Implemented changing TAN medium (HKTAU) in UI and entering ATC, but job result after changing TAN medium doesn't get passed on to UI yet
This commit is contained in:
parent
cb557812c4
commit
fc2a5e6cf9
|
@ -8,8 +8,10 @@ import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.Toolbar
|
import android.support.v7.widget.Toolbar
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
|
import net.dankito.banking.fints4java.android.mapper.fints4javaModelMapper
|
||||||
import net.dankito.banking.fints4java.android.ui.MainWindowPresenter
|
import net.dankito.banking.fints4java.android.ui.MainWindowPresenter
|
||||||
import net.dankito.banking.fints4java.android.ui.dialogs.AddAccountDialog
|
import net.dankito.banking.fints4java.android.ui.dialogs.AddAccountDialog
|
||||||
|
import net.dankito.banking.fints4java.android.ui.dialogs.EnterAtcDialog
|
||||||
import net.dankito.banking.fints4java.android.ui.dialogs.EnterTanDialog
|
import net.dankito.banking.fints4java.android.ui.dialogs.EnterTanDialog
|
||||||
import net.dankito.fints.FinTsClientCallback
|
import net.dankito.fints.FinTsClientCallback
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
|
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
|
||||||
|
@ -18,6 +20,7 @@ import net.dankito.fints.model.EnterTanGeneratorAtcResult
|
||||||
import net.dankito.fints.model.TanChallenge
|
import net.dankito.fints.model.TanChallenge
|
||||||
import net.dankito.fints.model.TanProcedure
|
import net.dankito.fints.model.TanProcedure
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +40,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun enterTanGeneratorAtc(customer: CustomerData, tanMedium: TanGeneratorTanMedium): EnterTanGeneratorAtcResult? {
|
override fun enterTanGeneratorAtc(customer: CustomerData, tanMedium: TanGeneratorTanMedium): EnterTanGeneratorAtcResult? {
|
||||||
return null
|
return getAtcFromUserOffUiThread(customer, tanMedium)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -96,18 +99,34 @@ class MainActivity : AppCompatActivity() {
|
||||||
val account = presenter.getAccountForCustomer(customer)
|
val account = presenter.getAccountForCustomer(customer)
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
EnterTanDialog().show(account, tanChallenge, this@MainActivity, false) {
|
EnterTanDialog().show(account, tanChallenge, presenter, this@MainActivity, false) {
|
||||||
enteredTan.set(it)
|
enteredTan.set(it)
|
||||||
tanEnteredLatch.countDown()
|
tanEnteredLatch.countDown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try { tanEnteredLatch.await() } catch (ignored: Exception) { }
|
||||||
tanEnteredLatch.await()
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return enteredTan.get()
|
return enteredTan.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getAtcFromUserOffUiThread(customer: CustomerData, tanMedium: TanGeneratorTanMedium): EnterTanGeneratorAtcResult? {
|
||||||
|
val enteredTan = AtomicReference<String>(null)
|
||||||
|
val enteredAtc = AtomicInteger()
|
||||||
|
val tanEnteredLatch = CountDownLatch(1)
|
||||||
|
|
||||||
|
runOnUiThread {
|
||||||
|
// TODO: don't create a fints4javaModelMapper instance here, let MainWindowPresenter do the job
|
||||||
|
EnterAtcDialog().show(fints4javaModelMapper().mapTanMedium(tanMedium), this@MainActivity, false) { tan, atc ->
|
||||||
|
enteredTan.set(tan)
|
||||||
|
atc?.let { enteredAtc.set(atc) }
|
||||||
|
tanEnteredLatch.countDown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try { tanEnteredLatch.await() } catch (ignored: Exception) { }
|
||||||
|
|
||||||
|
return if (enteredTan.get() == null) null else EnterTanGeneratorAtcResult(enteredTan.get(), enteredAtc.get())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,11 +103,16 @@ open class fints4javaModelMapper {
|
||||||
|
|
||||||
protected open fun getDisplayNameForTanMedium(tanMedium: net.dankito.fints.messages.datenelemente.implementierte.tan.TanMedium): String {
|
protected open fun getDisplayNameForTanMedium(tanMedium: net.dankito.fints.messages.datenelemente.implementierte.tan.TanMedium): String {
|
||||||
if (tanMedium is TanGeneratorTanMedium) {
|
if (tanMedium is TanGeneratorTanMedium) {
|
||||||
tanMedium.mediaName?.let { mediaName ->
|
var cardNumber = tanMedium.cardNumber
|
||||||
return "$mediaName ${tanMedium.cardNumber}"
|
tanMedium.followUpCardNumber?.let {
|
||||||
|
cardNumber += " (Folgenummer $it)" // TODO: translate
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Card ${tanMedium.cardNumber}" // TODO: translate
|
tanMedium.mediaName?.let { mediaName ->
|
||||||
|
return "$mediaName $cardNumber"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Karte $cardNumber" // TODO: translate
|
||||||
}
|
}
|
||||||
|
|
||||||
return tanMedium.mediumClass.name
|
return tanMedium.mediumClass.name
|
||||||
|
|
|
@ -3,11 +3,13 @@ package net.dankito.banking.fints4java.android.ui
|
||||||
import net.dankito.banking.ui.model.Account
|
import net.dankito.banking.ui.model.Account
|
||||||
import net.dankito.banking.ui.model.AccountTransaction
|
import net.dankito.banking.ui.model.AccountTransaction
|
||||||
import net.dankito.banking.ui.model.BankAccount
|
import net.dankito.banking.ui.model.BankAccount
|
||||||
|
import net.dankito.banking.ui.model.TanMedium
|
||||||
import net.dankito.banking.ui.model.responses.AddAccountResponse
|
import net.dankito.banking.ui.model.responses.AddAccountResponse
|
||||||
import net.dankito.banking.ui.model.responses.GetTransactionsResponse
|
import net.dankito.banking.ui.model.responses.GetTransactionsResponse
|
||||||
import net.dankito.fints.FinTsClientCallback
|
import net.dankito.fints.FinTsClientCallback
|
||||||
import net.dankito.fints.FinTsClientForCustomer
|
import net.dankito.fints.FinTsClientForCustomer
|
||||||
import net.dankito.fints.banks.BankFinder
|
import net.dankito.fints.banks.BankFinder
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
|
||||||
import net.dankito.fints.model.BankInfo
|
import net.dankito.fints.model.BankInfo
|
||||||
import net.dankito.fints.model.BankTransferData
|
import net.dankito.fints.model.BankTransferData
|
||||||
import net.dankito.fints.model.CustomerData
|
import net.dankito.fints.model.CustomerData
|
||||||
|
@ -142,6 +144,16 @@ open class MainWindowPresenter(protected val base64Service: IBase64Service,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun changeTanMediumAsync(newUsedTanMedium: TanMedium, account: Account, callback: (FinTsClientResponse) -> Unit) {
|
||||||
|
(newUsedTanMedium.originalObject as? TanGeneratorTanMedium)?.let { tanGeneratorTanMedium ->
|
||||||
|
getClientForAccount(account)?.changeTanMedium(tanGeneratorTanMedium, callback)
|
||||||
|
// TODO: find a way to update account.tanMedia afterwards
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: what to do if newActiveTanMedium.originalObject is not of type TanGeneratorTanMedium?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
open fun searchForBankAsync(enteredBankCode: String, callback: (List<BankInfo>) -> Unit) {
|
open fun searchForBankAsync(enteredBankCode: String, callback: (List<BankInfo>) -> Unit) {
|
||||||
threadPool.runAsync {
|
threadPool.runAsync {
|
||||||
callback(searchForBank(enteredBankCode))
|
callback(searchForBank(enteredBankCode))
|
||||||
|
@ -181,6 +193,11 @@ open class MainWindowPresenter(protected val base64Service: IBase64Service,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open fun getErrorToShowToUser(response: FinTsClientResponse): String? {
|
||||||
|
return fints4javaModelMapper.mapErrorToShowToUser(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
open val allTransactions: List<AccountTransaction>
|
open val allTransactions: List<AccountTransaction>
|
||||||
get() = accounts.keys.flatMap { it.transactions }.sortedByDescending { it.bookingDate } // TODO: someday add unbooked transactions
|
get() = accounts.keys.flatMap { it.transactions }.sortedByDescending { it.bookingDate } // TODO: someday add unbooked transactions
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,12 @@ import net.dankito.utils.android.ui.adapter.ListAdapter
|
||||||
open class TanMediumAdapter : ListAdapter<TanMedium>() {
|
open class TanMediumAdapter : ListAdapter<TanMedium>() {
|
||||||
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View? {
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View? {
|
||||||
val procedure = getItem(position)
|
val tanMedium = getItem(position)
|
||||||
|
|
||||||
val view = convertView ?: parent?.context?.asActivity()?.layoutInflater?.inflate(
|
val view = convertView ?: parent?.context?.asActivity()?.layoutInflater?.inflate(
|
||||||
R.layout.list_item_tan_medium, parent, false)
|
R.layout.list_item_tan_medium, parent, false)
|
||||||
|
|
||||||
view?.findViewById<TextView>(R.id.txtTanMediumDisplayName)?.text = procedure.displayName
|
view?.findViewById<TextView>(R.id.txtTanMediumDisplayName)?.text = tanMedium.displayName
|
||||||
|
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ open class BankTransferDialog : DialogFragment() {
|
||||||
else {
|
else {
|
||||||
context.getString(R.string.dialog_bank_transfer_message_transfer_failed,
|
context.getString(R.string.dialog_bank_transfer_message_transfer_failed,
|
||||||
String.format("%.02f", transferData.amount), "€", transferData.creditorName, // TODO: where to get currency from?
|
String.format("%.02f", transferData.amount), "€", transferData.creditorName, // TODO: where to get currency from?
|
||||||
response.exception ?: response.errorsToShowToUser.joinToString("\n")
|
presenter.getErrorToShowToUser(response)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
package net.dankito.banking.fints4java.android.ui.dialogs
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v4.app.DialogFragment
|
||||||
|
import android.support.v7.app.AlertDialog
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
|
import android.text.Html
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import kotlinx.android.synthetic.main.dialog_enter_atc.view.*
|
||||||
|
import net.dankito.banking.fints4java.android.R
|
||||||
|
import net.dankito.banking.ui.model.TanMedium
|
||||||
|
|
||||||
|
|
||||||
|
open class EnterAtcDialog : DialogFragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val DialogTag = "EnterAtcDialog"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected lateinit var tanMedium: TanMedium
|
||||||
|
|
||||||
|
protected lateinit var atcEnteredCallback: (tan: String?, atc: Int?) -> Unit
|
||||||
|
|
||||||
|
|
||||||
|
open fun show(tanMedium: TanMedium, activity: AppCompatActivity,
|
||||||
|
fullscreen: Boolean = false, atcEnteredCallback: (tan: String?, atc: Int?) -> Unit) {
|
||||||
|
|
||||||
|
this.tanMedium = tanMedium
|
||||||
|
this.atcEnteredCallback = atcEnteredCallback
|
||||||
|
|
||||||
|
val style = if(fullscreen) R.style.FullscreenDialogWithStatusBar else R.style.Dialog
|
||||||
|
setStyle(STYLE_NORMAL, style)
|
||||||
|
|
||||||
|
show(activity.supportFragmentManager, DialogTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
val rootView = inflater.inflate(R.layout.dialog_enter_atc, container, false)
|
||||||
|
|
||||||
|
setupUI(rootView)
|
||||||
|
|
||||||
|
return rootView
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun setupUI(rootView: View) {
|
||||||
|
val explanationHtml = rootView.context.getString(R.string.dialog_enter_atc_explanation, tanMedium.displayName)
|
||||||
|
rootView.txtAtcExplanationToShowToUser.text = Html.fromHtml(explanationHtml, Html.FROM_HTML_MODE_LEGACY)
|
||||||
|
|
||||||
|
rootView.btnCancel.setOnClickListener { enteringAtcDone(null, null) }
|
||||||
|
|
||||||
|
rootView.btnEnteringAtcDone.setOnClickListener { enteringAtcDone(rootView.edtxtEnteredTan.text.toString(), rootView.edtxtEnteredAtc.text.toString()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun enteringAtcDone(enteredTan: String?, enteredAtcString: String?) {
|
||||||
|
var enteredAtc: Int? = null
|
||||||
|
|
||||||
|
if (enteredAtcString != null) {
|
||||||
|
try {
|
||||||
|
enteredAtc = enteredAtcString.toInt()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showEnteredAtcIsNotANumberError(enteredAtcString)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
atcEnteredCallback(enteredTan, enteredAtc)
|
||||||
|
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun showEnteredAtcIsNotANumberError(enteredAtcString: String) {
|
||||||
|
activity?.let { context ->
|
||||||
|
AlertDialog.Builder(context)
|
||||||
|
.setMessage(context.getString(R.string.dialog_enter_atc_error_entered_atc_is_not_a_number, enteredAtcString))
|
||||||
|
.setPositiveButton(android.R.string.ok) { dialog, _ -> dialog.dismiss() }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
package net.dankito.banking.fints4java.android.ui.dialogs
|
package net.dankito.banking.fints4java.android.ui.dialogs
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.DialogFragment
|
import android.support.v4.app.DialogFragment
|
||||||
|
import android.support.v7.app.AlertDialog
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -9,11 +11,15 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import kotlinx.android.synthetic.main.dialog_enter_tan.view.*
|
import kotlinx.android.synthetic.main.dialog_enter_tan.view.*
|
||||||
import net.dankito.banking.fints4java.android.R
|
import net.dankito.banking.fints4java.android.R
|
||||||
|
import net.dankito.banking.fints4java.android.ui.MainWindowPresenter
|
||||||
import net.dankito.banking.fints4java.android.ui.adapter.TanMediumAdapter
|
import net.dankito.banking.fints4java.android.ui.adapter.TanMediumAdapter
|
||||||
|
import net.dankito.banking.fints4java.android.ui.listener.ListItemSelectedListener
|
||||||
import net.dankito.banking.ui.model.Account
|
import net.dankito.banking.ui.model.Account
|
||||||
|
import net.dankito.banking.ui.model.TanMedium
|
||||||
import net.dankito.banking.ui.model.TanMediumStatus
|
import net.dankito.banking.ui.model.TanMediumStatus
|
||||||
import net.dankito.fints.model.TanChallenge
|
import net.dankito.fints.model.TanChallenge
|
||||||
import net.dankito.fints.model.TanProcedureType
|
import net.dankito.fints.model.TanProcedureType
|
||||||
|
import net.dankito.fints.response.client.FinTsClientResponse
|
||||||
import net.dankito.fints.tan.FlickercodeDecoder
|
import net.dankito.fints.tan.FlickercodeDecoder
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,16 +34,19 @@ open class EnterTanDialog : DialogFragment() {
|
||||||
|
|
||||||
protected lateinit var tanChallenge: TanChallenge
|
protected lateinit var tanChallenge: TanChallenge
|
||||||
|
|
||||||
|
protected lateinit var presenter: MainWindowPresenter
|
||||||
|
|
||||||
protected lateinit var tanEnteredCallback: (String?) -> Unit
|
protected lateinit var tanEnteredCallback: (String?) -> Unit
|
||||||
|
|
||||||
protected val tanMediumAdapter = TanMediumAdapter()
|
protected val tanMediumAdapter = TanMediumAdapter()
|
||||||
|
|
||||||
|
|
||||||
open fun show(account: Account, tanChallenge: TanChallenge, activity: AppCompatActivity,
|
open fun show(account: Account, tanChallenge: TanChallenge, presenter: MainWindowPresenter, activity: AppCompatActivity,
|
||||||
fullscreen: Boolean = false, tanEnteredCallback: (String?) -> Unit) {
|
fullscreen: Boolean = false, tanEnteredCallback: (String?) -> Unit) {
|
||||||
|
|
||||||
this.account = account
|
this.account = account
|
||||||
this.tanChallenge = tanChallenge
|
this.tanChallenge = tanChallenge
|
||||||
|
this.presenter = presenter
|
||||||
this.tanEnteredCallback = tanEnteredCallback
|
this.tanEnteredCallback = tanEnteredCallback
|
||||||
|
|
||||||
val style = if(fullscreen) R.style.FullscreenDialogWithStatusBar else R.style.Dialog
|
val style = if(fullscreen) R.style.FullscreenDialogWithStatusBar else R.style.Dialog
|
||||||
|
@ -60,9 +69,7 @@ open class EnterTanDialog : DialogFragment() {
|
||||||
|
|
||||||
if (tanChallenge.tanProcedure.type == TanProcedureType.ChipTanOptisch) {
|
if (tanChallenge.tanProcedure.type == TanProcedureType.ChipTanOptisch) {
|
||||||
if (account.tanMedia.isNotEmpty()) {
|
if (account.tanMedia.isNotEmpty()) {
|
||||||
rootView.lytTanMedium.visibility = View.VISIBLE
|
setupSelectTanMediumView(rootView)
|
||||||
tanMediumAdapter.setItems(account.tanMedia.sortedByDescending { it.status == TanMediumStatus.Used })
|
|
||||||
rootView.spnTanMedium.adapter = tanMediumAdapter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flickerCodeView.visibility = View.VISIBLE
|
flickerCodeView.visibility = View.VISIBLE
|
||||||
|
@ -78,6 +85,48 @@ open class EnterTanDialog : DialogFragment() {
|
||||||
rootView.btnEnteringTanDone.setOnClickListener { enteringTanDone(rootView.edtxtEnteredTan.text.toString()) }
|
rootView.btnEnteringTanDone.setOnClickListener { enteringTanDone(rootView.edtxtEnteredTan.text.toString()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun setupSelectTanMediumView(rootView: View) {
|
||||||
|
rootView.lytTanMedium.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
tanMediumAdapter.setItems(account.tanMedia.sortedByDescending { it.status == TanMediumStatus.Used })
|
||||||
|
|
||||||
|
rootView.spnTanMedium.adapter = tanMediumAdapter
|
||||||
|
rootView.spnTanMedium.onItemSelectedListener = ListItemSelectedListener(tanMediumAdapter) { selectedTanMedium ->
|
||||||
|
if (selectedTanMedium.status != TanMediumStatus.Used) {
|
||||||
|
presenter.changeTanMediumAsync(selectedTanMedium, account) { response ->
|
||||||
|
handleChangeTanMediumResponse(selectedTanMedium, response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleChangeTanMediumResponse(newUsedTanMedium: TanMedium, response: FinTsClientResponse) {
|
||||||
|
activity?.let { activity ->
|
||||||
|
activity.runOnUiThread {
|
||||||
|
handleChangeTanMediumResponseOnUiThread(activity, newUsedTanMedium, response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun handleChangeTanMediumResponseOnUiThread(context: Context, newUsedTanMedium: TanMedium, response: FinTsClientResponse) {
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
dismiss()
|
||||||
|
|
||||||
|
AlertDialog.Builder(context)
|
||||||
|
.setMessage(context.getString(R.string.dialog_enter_tan_tan_medium_successfully_changed, newUsedTanMedium.displayName))
|
||||||
|
.setPositiveButton(android.R.string.ok) { dialog, _ -> dialog.dismiss() }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AlertDialog.Builder(context)
|
||||||
|
.setMessage(context.getString(R.string.dialog_enter_tan_error_changing_tan_medium, newUsedTanMedium.displayName, presenter.getErrorToShowToUser(response)))
|
||||||
|
.setPositiveButton(android.R.string.ok) { dialog, _ -> dialog.dismiss() }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected open fun enteringTanDone(enteredTan: String?) {
|
protected open fun enteringTanDone(enteredTan: String?) {
|
||||||
tanEnteredCallback(enteredTan)
|
tanEnteredCallback(enteredTan)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package net.dankito.banking.fints4java.android.ui.listener
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.AdapterView
|
||||||
|
|
||||||
|
|
||||||
|
open class ItemSelectedListener(val itemSelected: (position: Int) -> Unit) : AdapterView.OnItemSelectedListener {
|
||||||
|
|
||||||
|
override fun onNothingSelected(parent: AdapterView<*>?) { }
|
||||||
|
|
||||||
|
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||||
|
itemSelected(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package net.dankito.banking.fints4java.android.ui.listener
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import net.dankito.utils.android.ui.adapter.ListAdapter
|
||||||
|
|
||||||
|
|
||||||
|
open class ListItemSelectedListener<T>(val adapter: ListAdapter<T>, val itemSelected: (item: T) -> Unit) : AdapterView.OnItemSelectedListener {
|
||||||
|
|
||||||
|
override fun onNothingSelected(parent: AdapterView<*>?) { }
|
||||||
|
|
||||||
|
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||||
|
itemSelected(adapter.getItem(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="@dimen/dialog_enter_atc_padding"
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtAtcExplanationToShowToUser"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dialog_enter_atc_enter_value_field_height"
|
||||||
|
android:layout_marginBottom="@dimen/dialog_enter_atc_enter_value_field_margin_bottom"
|
||||||
|
>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:text="@string/dialog_enter_atc_tan_label"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/edtxtEnteredTan"
|
||||||
|
android:layout_width="@dimen/dialog_enter_atc_enter_value_field_value_width"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="@dimen/dialog_enter_atc_enter_value_field_value_margin_left"
|
||||||
|
android:layout_marginStart="@dimen/dialog_enter_atc_enter_value_field_value_margin_left"
|
||||||
|
android:inputType="number"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dialog_enter_atc_enter_value_field_height"
|
||||||
|
android:layout_marginBottom="@dimen/dialog_enter_atc_enter_value_field_margin_bottom"
|
||||||
|
>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:text="@string/dialog_enter_atc_atc_label"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/edtxtEnteredAtc"
|
||||||
|
android:layout_width="@dimen/dialog_enter_atc_enter_value_field_value_width"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="@dimen/dialog_enter_atc_enter_value_field_value_margin_left"
|
||||||
|
android:layout_marginStart="@dimen/dialog_enter_atc_enter_value_field_value_margin_left"
|
||||||
|
android:inputType="number"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/lytButtonBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnEnteringAtcDone"
|
||||||
|
android:layout_width="@dimen/dialog_enter_atc_buttons_width"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
style="?android:attr/buttonBarButtonStyle"
|
||||||
|
android:text="@android:string/ok"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnCancel"
|
||||||
|
android:layout_width="@dimen/dialog_enter_atc_buttons_width"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_toLeftOf="@+id/btnEnteringAtcDone"
|
||||||
|
android:layout_toStartOf="@+id/btnEnteringAtcDone"
|
||||||
|
style="?android:attr/buttonBarButtonStyle"
|
||||||
|
android:text="@string/cancel"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -21,6 +21,8 @@
|
||||||
android:text="@string/dialog_enter_tan_select_tan_medium"
|
android:text="@string/dialog_enter_tan_select_tan_medium"
|
||||||
android:layout_marginRight="@dimen/dialog_enter_tan_tan_medium_label_right_margin"
|
android:layout_marginRight="@dimen/dialog_enter_tan_tan_medium_label_right_margin"
|
||||||
android:layout_marginEnd="@dimen/dialog_enter_tan_tan_medium_label_right_margin"
|
android:layout_marginEnd="@dimen/dialog_enter_tan_tan_medium_label_right_margin"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textSize="@dimen/view_change_tan_medium_text_size"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Spinner
|
<Spinner
|
||||||
|
@ -28,6 +30,7 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
<TextView
|
<TextView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/txtTanMediumDisplayName"
|
android:id="@+id/txtTanMediumDisplayName"
|
||||||
style="@style/TextAppearance.AppCompat.Small"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
style="@style/TextAppearance.AppCompat.Small"
|
||||||
|
android:textSize="@dimen/view_change_tan_medium_text_size"
|
||||||
|
android:singleLine="true"
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
|
android:padding="@dimen/list_item_tan_medium_padding"
|
||||||
/>
|
/>
|
|
@ -59,4 +59,15 @@
|
||||||
<dimen name="dialog_enter_tan_enter_tan_margin_bottom">8dp</dimen>
|
<dimen name="dialog_enter_tan_enter_tan_margin_bottom">8dp</dimen>
|
||||||
<dimen name="dialog_enter_tan_buttons_width">120dp</dimen>
|
<dimen name="dialog_enter_tan_buttons_width">120dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="view_change_tan_medium_text_size">15sp</dimen>
|
||||||
|
|
||||||
|
<dimen name="list_item_tan_medium_padding">4dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="dialog_enter_atc_padding">4dp</dimen>
|
||||||
|
<dimen name="dialog_enter_atc_enter_value_field_height">50dp</dimen>
|
||||||
|
<dimen name="dialog_enter_atc_enter_value_field_margin_bottom">8dp</dimen>
|
||||||
|
<dimen name="dialog_enter_atc_enter_value_field_value_width">110dp</dimen>
|
||||||
|
<dimen name="dialog_enter_atc_enter_value_field_value_margin_left">6dp</dimen>
|
||||||
|
<dimen name="dialog_enter_atc_buttons_width">120dp</dimen>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -60,5 +60,19 @@
|
||||||
|
|
||||||
<string name="dialog_enter_tan_select_tan_medium">TAN medium</string>
|
<string name="dialog_enter_tan_select_tan_medium">TAN medium</string>
|
||||||
<string name="dialog_enter_tan_enter_tan">Enter TAN:</string>
|
<string name="dialog_enter_tan_enter_tan">Enter TAN:</string>
|
||||||
|
<string name="dialog_enter_tan_tan_medium_successfully_changed">TAN medium successfully changed to \'%s\'.</string>
|
||||||
|
<string name="dialog_enter_tan_error_changing_tan_medium">Could not change TAN medium to \'%s\':\n%s.</string>
|
||||||
|
|
||||||
|
<!-- Removed <p></p> from last paragraph as otherwise TextView has some padding at the end -->
|
||||||
|
<string name="dialog_enter_atc_explanation"><![CDATA[
|
||||||
|
<p>Your bank asks you to synchronize your TAN generator.</p>
|
||||||
|
<p>Please insert the card \'%s\' into your TAN generator.</p>
|
||||||
|
<p>Then press the \'TAN\' button for a few seconds till \'aktiviert\' gets displayed.</p>
|
||||||
|
<p>Then either press the \'TAN\' button again or enter the start code \'103\', press the \'OK\' twice and then the \'\' button (depends on your model).</p>
|
||||||
|
Now the values for \'TAN\' and \'ATC\' should be displayed. Enter these two values below:
|
||||||
|
]]></string>
|
||||||
|
<string name="dialog_enter_atc_tan_label">TAN:</string>
|
||||||
|
<string name="dialog_enter_atc_atc_label">ATC:</string>
|
||||||
|
<string name="dialog_enter_atc_error_entered_atc_is_not_a_number">ATC has to be a number.\n\nBut entered ATC value \'%s\' cannot be converted to a number.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue