mirror of
https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC.git
synced 2024-12-22 20:40:16 +02:00
Merge branch 'main' into MOB-55
This commit is contained in:
commit
4096201bef
@ -68,8 +68,4 @@ dependencies {
|
|||||||
'io.jsonwebtoken:jjwt-gson:0.11.2'
|
'io.jsonwebtoken:jjwt-gson:0.11.2'
|
||||||
|
|
||||||
implementation 'com.koushikdutta.ion:ion:3.1.0'
|
implementation 'com.koushikdutta.ion:ion:3.1.0'
|
||||||
|
|
||||||
// Retrofit + Moshi Converter
|
|
||||||
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
|
|
||||||
implementation 'com.squareup.moshi:moshi-kotlin:1.9.3'
|
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import android.app.Activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.nfc.NfcAdapter
|
import android.nfc.NfcAdapter
|
||||||
|
import android.nfc.TagLostException
|
||||||
import android.nfc.tech.IsoDep
|
import android.nfc.tech.IsoDep
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
@ -33,9 +34,10 @@ class AuthFragment : Fragment() {
|
|||||||
|
|
||||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||||
|
|
||||||
private val intentParameters: ParametersViewModel by activityViewModels()
|
private val paramsModel: ParametersViewModel by activityViewModels()
|
||||||
|
|
||||||
private var binding: FragmentAuthBinding? = null
|
private var _binding: FragmentAuthBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
private val args: CanFragmentArgs by navArgs()
|
private val args: CanFragmentArgs by navArgs()
|
||||||
|
|
||||||
@ -48,8 +50,8 @@ class AuthFragment : Fragment() {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentAuthBinding.inflate(inflater, container, false)
|
_binding = FragmentAuthBinding.inflate(inflater, container, false)
|
||||||
return binding!!.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
@ -58,64 +60,87 @@ class AuthFragment : Fragment() {
|
|||||||
override fun onTick(p0: Long) {
|
override fun onTick(p0: Long) {
|
||||||
timeRemaining--
|
timeRemaining--
|
||||||
if (timeRemaining == 0) {
|
if (timeRemaining == 0) {
|
||||||
binding?.timeCounter?.text = getString(R.string.no_time)
|
binding.timeCounter.text = getString(R.string.no_time)
|
||||||
} else {
|
} else {
|
||||||
binding?.timeCounter?.text = getString(R.string.time_left, timeRemaining)
|
binding.timeCounter.text = getString(R.string.time_left, timeRemaining)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
Thread.sleep(750)
|
Thread.sleep(750)
|
||||||
goToTheStart()
|
cancelAuth()
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
//binding!!.nextButton.visibility = View.INVISIBLE
|
// The button exists in code for testing reasons, but not visible to the user anymore unless visibility is changed in the code.
|
||||||
binding!!.nextButton.setOnClickListener { goToNextFragment() }
|
binding.nextButton.visibility = View.GONE
|
||||||
binding!!.cancelButton.setOnClickListener { goToTheStart() }
|
binding.nextButton.setOnClickListener { goToNextFragment() }
|
||||||
|
binding.cancelButton.setOnClickListener { cancelAuth() }
|
||||||
val adapter = NfcAdapter.getDefaultAdapter(activity)
|
val adapter = NfcAdapter.getDefaultAdapter(activity)
|
||||||
if (adapter != null)
|
if (adapter != null)
|
||||||
getInfoFromIdCard(adapter)
|
getInfoFromIdCard(adapter)
|
||||||
|
else { // If NFC adapter can not be detected then end the auth process as it is not possible to read an ID card
|
||||||
|
cancelAuth() // It would be a good idea to show user some notification as it might be confusing if the app suddenly closes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun goToNextFragment() {
|
||||||
|
timer.cancel()
|
||||||
|
val action = AuthFragmentDirections.actionAuthFragmentToResultFragment(mobile = args.mobile)
|
||||||
|
findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cancelAuth() {
|
||||||
|
viewModel.clearUserInfo()
|
||||||
|
timer.cancel()
|
||||||
|
if (args.mobile) {
|
||||||
|
val resultIntent = Intent()
|
||||||
|
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
||||||
|
requireActivity().finish()
|
||||||
|
} else {
|
||||||
|
requireActivity().finishAndRemoveTask()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getInfoFromIdCard(adapter: NfcAdapter) {
|
private fun getInfoFromIdCard(adapter: NfcAdapter) {
|
||||||
adapter.enableReaderMode(activity, { tag ->
|
adapter.enableReaderMode(activity, { tag ->
|
||||||
timer.cancel()
|
timer.cancel()
|
||||||
requireActivity().runOnUiThread {
|
requireActivity().runOnUiThread {
|
||||||
binding!!.timeCounter.text = getString(R.string.card_detected)
|
binding.timeCounter.text = getString(R.string.card_detected)
|
||||||
}
|
}
|
||||||
val card = IsoDep.get(tag)
|
val card = IsoDep.get(tag)
|
||||||
card.timeout = 32768
|
card.timeout = 32768
|
||||||
card.use {
|
card.use {
|
||||||
try {
|
try {
|
||||||
val comms = Comms(it, viewModel.userCan)
|
val comms = Comms(it, viewModel.userCan)
|
||||||
if (args.auth) {
|
|
||||||
val jws = Authenticator(comms).authenticate(
|
val jws = Authenticator(comms).authenticate(
|
||||||
intentParameters.challenge,
|
paramsModel.challenge,
|
||||||
intentParameters.origin,
|
paramsModel.origin,
|
||||||
viewModel.userPin
|
viewModel.userPin
|
||||||
)
|
)
|
||||||
intentParameters.setToken(jws)
|
paramsModel.setToken(jws)
|
||||||
} else {
|
|
||||||
val response = comms.readPersonalData(byteArrayOf(1, 2, 6, 3, 4, 8))
|
|
||||||
viewModel.setUserFirstName(response[1])
|
|
||||||
viewModel.setUserLastName(response[0])
|
|
||||||
viewModel.setUserIdentificationNumber(response[2])
|
|
||||||
viewModel.setGender(response[3])
|
|
||||||
viewModel.setCitizenship(response[4])
|
|
||||||
viewModel.setExpiration(response[5])
|
|
||||||
}
|
|
||||||
requireActivity().runOnUiThread {
|
requireActivity().runOnUiThread {
|
||||||
binding!!.timeCounter.text = getString(R.string.data_read)
|
goToNextFragment()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
requireActivity().runOnUiThread {
|
when(e) {
|
||||||
binding!!.timeCounter.text = getString(R.string.no_success)
|
is TagLostException -> requireActivity().runOnUiThread { binding!!.timeCounter.text = getString(R.string.id_card_removed_early) }
|
||||||
|
else -> {
|
||||||
|
when ("invalid pin") {
|
||||||
|
in e.message.toString().lowercase() -> requireActivity().runOnUiThread {
|
||||||
|
val messagePieces = e.message.toString().split(" ")
|
||||||
|
binding.timeCounter.text = getString(R.string.wrong_pin, messagePieces[messagePieces.size - 1])
|
||||||
|
viewModel.deletePin(requireContext())
|
||||||
}
|
}
|
||||||
// If the CAN is wrong we will also delete the saved CAN so that the user won't use it again.
|
else -> requireActivity().runOnUiThread {
|
||||||
|
binding.timeCounter.text = getString(R.string.wrong_can_text)
|
||||||
viewModel.deleteCan(requireContext())
|
viewModel.deleteCan(requireContext())
|
||||||
// Gives user some time to read the error message
|
}
|
||||||
Thread.sleep(1000)
|
}
|
||||||
goToTheStart()
|
}
|
||||||
|
}
|
||||||
|
// Give user some time to read the error message
|
||||||
|
Thread.sleep(2000)
|
||||||
|
cancelAuth()
|
||||||
} finally {
|
} finally {
|
||||||
adapter.disableReaderMode(activity)
|
adapter.disableReaderMode(activity)
|
||||||
}
|
}
|
||||||
@ -123,35 +148,8 @@ class AuthFragment : Fragment() {
|
|||||||
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun goToNextFragment() {
|
|
||||||
timer.cancel()
|
|
||||||
if (args.auth) {
|
|
||||||
val action = AuthFragmentDirections.actionAuthFragmentToResultFragment(mobile = args.mobile)
|
|
||||||
findNavController().navigate(action)
|
|
||||||
} else {
|
|
||||||
findNavController().navigate(R.id.action_authFragment_to_userFragment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun goToTheStart() {
|
|
||||||
viewModel.clearUserInfo()
|
|
||||||
timer.cancel()
|
|
||||||
if (args.reading) {
|
|
||||||
findNavController().navigate(R.id.action_authFragment_to_homeFragment)
|
|
||||||
} else {
|
|
||||||
if (!args.mobile) {
|
|
||||||
//Currently for some reason the activity is not killed entirely. Must be looked into further.
|
|
||||||
requireActivity().finishAndRemoveTask()
|
|
||||||
} else {
|
|
||||||
val resultIntent = Intent()
|
|
||||||
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
|
||||||
requireActivity().finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,17 +3,22 @@ package com.tarkvaraprojekt.mobileauthapp
|
|||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.widget.addTextChangedListener
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentCanBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentCanBinding
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
|
import org.w3c.dom.Text
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment that deals with asking the user for a six digit CAN. If the CAN is already saved
|
* Fragment that deals with asking the user for a six digit CAN. If the CAN is already saved
|
||||||
@ -24,12 +29,11 @@ class CanFragment : Fragment() {
|
|||||||
|
|
||||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||||
|
|
||||||
private var binding: FragmentCanBinding? = null
|
private var _binding: FragmentCanBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
// Navigation arguments:
|
// Navigation arguments:
|
||||||
// saving = true means that we are navigating here from the settings menu and must return to the settings menu.
|
// saving = true means that we are navigating here from the settings menu and must return to the settings menu.
|
||||||
// reading = true means that we are only reading the information from the ID card that does not need PIN 1,
|
|
||||||
// this information is passed on to the next PinFragment.
|
|
||||||
private val args: CanFragmentArgs by navArgs()
|
private val args: CanFragmentArgs by navArgs()
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@ -37,20 +41,17 @@ class CanFragment : Fragment() {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentCanBinding.inflate(inflater, container, false)
|
_binding = FragmentCanBinding.inflate(inflater, container, false)
|
||||||
return binding!!.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
checkIfSkip()
|
checkIfSkip()
|
||||||
// If the user arrives from the settings menu then the button should say
|
binding.canTextField.editText?.addTextChangedListener {
|
||||||
// save instead of continue.
|
checkEnteredCan()
|
||||||
if (args.saving) {
|
|
||||||
binding!!.nextButton.text = getString(R.string.save_text)
|
|
||||||
}
|
}
|
||||||
binding!!.nextButton.setOnClickListener { checkEnteredCan() }
|
binding.buttonCancel.setOnClickListener { goToTheStart() }
|
||||||
binding!!.cancelButton.setOnClickListener { goToTheStart() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,66 +68,22 @@ class CanFragment : Fragment() {
|
|||||||
* Takes user to the next fragment, which is PinFragment.
|
* Takes user to the next fragment, which is PinFragment.
|
||||||
*/
|
*/
|
||||||
private fun goToTheNextFragment() {
|
private fun goToTheNextFragment() {
|
||||||
val action = CanFragmentDirections.actionCanFragmentToPinFragment(reading = args.reading, auth = args.auth, mobile = args.mobile)
|
val action = CanFragmentDirections.actionCanFragmentToPinFragment(auth = args.auth, mobile = args.mobile)
|
||||||
findNavController().navigate(action)
|
findNavController().navigate(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the user has entered a 6 digit can to the input field.
|
|
||||||
* If yes then the user is allowed to continue otherwise the user is
|
|
||||||
* allowed to modify the entered can.
|
|
||||||
*/
|
|
||||||
private fun checkEnteredCan() {
|
|
||||||
val enteredCan = binding!!.canEditText.editText?.text.toString()
|
|
||||||
if (enteredCan.length == 6) {
|
|
||||||
viewModel.setUserCan(enteredCan)
|
|
||||||
if (args.saving) {
|
|
||||||
viewModel.storeCan(requireContext())
|
|
||||||
goToTheStart()
|
|
||||||
} else {
|
|
||||||
val storeCanQuestion = getDialog()
|
|
||||||
storeCanQuestion?.show()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Toast.makeText(requireContext(), getString(R.string.length_can), Toast.LENGTH_SHORT)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds a dialog that asks the user whether the entered CAN should be saved
|
|
||||||
* on the device or not.
|
|
||||||
*/
|
|
||||||
private fun getDialog(): AlertDialog? {
|
|
||||||
return activity?.let { frag ->
|
|
||||||
val builder = AlertDialog.Builder(frag)
|
|
||||||
builder.apply {
|
|
||||||
// If response is positive then save the CAN on the device.
|
|
||||||
setPositiveButton(R.string.save_text) { _, _ ->
|
|
||||||
viewModel.storeCan(
|
|
||||||
requireContext()
|
|
||||||
)
|
|
||||||
goToTheNextFragment()
|
|
||||||
}
|
|
||||||
setNegativeButton(R.string.deny_text) { _, _ ->
|
|
||||||
goToTheNextFragment()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.setMessage(R.string.can_save_request)
|
|
||||||
builder.setTitle(R.string.save_can_title)
|
|
||||||
builder.create()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigates the user back to the start depending on where the user arrived.
|
* Navigates the user back to the start depending on where the user arrived.
|
||||||
* If the user arrived from the settings menu then the start is the settings menu
|
* If the user arrived from the settings menu then the start is the settings menu
|
||||||
* not the HomeFragment.
|
* not the HomeFragment.
|
||||||
*/
|
*/
|
||||||
private fun goToTheStart() {
|
private fun goToTheStart() {
|
||||||
// TODO: Needs special handling when the app is launched with intent. Temporary solution at the moment.
|
|
||||||
if (args.saving) {
|
if (args.saving) {
|
||||||
|
if (args.fromhome) {
|
||||||
|
findNavController().navigate(R.id.action_canFragment_to_homeFragment)
|
||||||
|
} else {
|
||||||
findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
|
findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
|
||||||
|
}
|
||||||
} else if (args.auth || args.mobile) {
|
} else if (args.auth || args.mobile) {
|
||||||
if (args.mobile) {
|
if (args.mobile) {
|
||||||
val resultIntent = Intent()
|
val resultIntent = Intent()
|
||||||
@ -140,8 +97,37 @@ class CanFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that creates and shows a snackbar that tells the user that CAN has been saved
|
||||||
|
*/
|
||||||
|
private fun showSnackbar() {
|
||||||
|
val snackbar = Snackbar.make(requireView(), R.string.can_status_saved, Snackbar.LENGTH_SHORT)
|
||||||
|
val snackbarText: TextView = snackbar.view.findViewById(R.id.snackbar_text)
|
||||||
|
snackbarText.setTextSize(TypedValue.COMPLEX_UNIT_SP, resources.getDimension(R.dimen.small_text))
|
||||||
|
snackbar.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the user has entered a 6 digit can to the input field.
|
||||||
|
* If yes then the user is allowed to continue otherwise the user is
|
||||||
|
* allowed to modify the entered can.
|
||||||
|
*/
|
||||||
|
private fun checkEnteredCan() {
|
||||||
|
val enteredCan = binding.canTextField.editText?.text.toString()
|
||||||
|
if (enteredCan.length == 6) {
|
||||||
|
viewModel.setUserCan(enteredCan)
|
||||||
|
viewModel.storeCan(requireContext()) //Maybe storeCan should always automatically call setUserCan method as well because these methods usually are used together
|
||||||
|
showSnackbar()
|
||||||
|
if (args.saving) {
|
||||||
|
goToTheStart()
|
||||||
|
} else {
|
||||||
|
goToTheNextFragment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,20 +1,30 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp
|
package com.tarkvaraprojekt.mobileauthapp
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import android.nfc.NfcAdapter
|
||||||
|
import android.nfc.TagLostException
|
||||||
|
import android.nfc.tech.IsoDep
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.NFC.Comms
|
||||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.ParametersViewModel
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.net.URLDecoder
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HomeFragment is only shown to the user when then the user launches the application. When the application
|
* HomeFragment is only shown to the user when then the user launches the application. When the application
|
||||||
@ -29,33 +39,68 @@ class HomeFragment : Fragment() {
|
|||||||
|
|
||||||
private val intentParams: ParametersViewModel by activityViewModels()
|
private val intentParams: ParametersViewModel by activityViewModels()
|
||||||
|
|
||||||
private var binding: FragmentHomeBinding? = null
|
private var _binding: FragmentHomeBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
// The ID card reader mode is enabled on the home fragment when can is saved.
|
||||||
|
private var canSaved: Boolean = false
|
||||||
|
|
||||||
|
// Is the app used for authentication
|
||||||
|
private var auth: Boolean = false
|
||||||
|
|
||||||
|
private var receiver: BroadcastReceiver? = null
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentHomeBinding.inflate(inflater, container, false)
|
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||||
// Making settings menu active again
|
// Making settings menu active again
|
||||||
(activity as MainActivity).menuAvailable = true
|
(activity as MainActivity).menuAvailable = true
|
||||||
return binding!!.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
initialChecks()
|
initialChecks()
|
||||||
var auth = false
|
|
||||||
if (requireActivity().intent.data?.getQueryParameter("action") != null) {
|
if (requireActivity().intent.data?.getQueryParameter("action") != null) {
|
||||||
// Currently we only support authentication not signing.
|
// Currently we only support authentication not signing.
|
||||||
auth = true
|
auth = true
|
||||||
}
|
}
|
||||||
val mobile = requireActivity().intent.getBooleanExtra("mobile", false)
|
val mobile = requireActivity().intent.getBooleanExtra("mobile", false)
|
||||||
if (auth || mobile){
|
if (auth || mobile) {
|
||||||
|
startAuthentication(mobile)
|
||||||
|
} else {
|
||||||
|
receiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(p0: Context?, p1: Intent?) {
|
||||||
|
updateAction(canSaved)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val filter = IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)
|
||||||
|
requireActivity().registerReceiver(receiver, filter)
|
||||||
|
updateAction(canSaved)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the process of interacting with the ID card by sending user to the CAN fragment.
|
||||||
|
*/
|
||||||
|
private fun goToTheNextFragment(mobile: Boolean = false) {
|
||||||
|
(activity as MainActivity).menuAvailable = false
|
||||||
|
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(auth = true, mobile = mobile)
|
||||||
|
findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that starts the authentication use case.
|
||||||
|
*
|
||||||
|
* NOTE: Comment out try-catch block when testing without backend
|
||||||
|
*/
|
||||||
|
private fun startAuthentication(mobile: Boolean) {
|
||||||
try {
|
try {
|
||||||
if (mobile) {
|
if (mobile) {
|
||||||
// We use !! because we want an exception when something is not right.
|
// We use !! to get extras because we want an exception to be thrown when something is missing.
|
||||||
intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!)
|
intentParams.setChallenge(requireActivity().intent.getStringExtra("challenge")!!)
|
||||||
intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!)
|
intentParams.setAuthUrl(requireActivity().intent.getStringExtra("authUrl")!!)
|
||||||
intentParams.setOrigin(requireActivity().intent.getStringExtra("originUrl")!!)
|
intentParams.setOrigin(requireActivity().intent.getStringExtra("originUrl")!!)
|
||||||
@ -67,41 +112,56 @@ class HomeFragment : Fragment() {
|
|||||||
intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!)
|
intentParams.setAuthUrl(requireActivity().intent.data!!.getQueryParameter("authUrl")!!)
|
||||||
intentParams.setOrigin(requireActivity().intent.data!!.getQueryParameter("originUrl")!!)
|
intentParams.setOrigin(requireActivity().intent.data!!.getQueryParameter("originUrl")!!)
|
||||||
}
|
}
|
||||||
|
goToTheNextFragment(mobile)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// There was a problem with parameters, which means that authentication is not possible.
|
// There was a problem with parameters, which means that authentication is not possible.
|
||||||
|
// In that case we will cancel the authentication immediately as it would be waste of the user's time to carry on
|
||||||
|
// before getting an inevitable error.
|
||||||
|
val message = MaterialAlertDialogBuilder(requireContext())
|
||||||
|
message.setTitle(getString(R.string.problem_parameters))
|
||||||
|
if (intentParams.challenge == "") {
|
||||||
|
message.setMessage(getString(R.string.problem_challenge))
|
||||||
|
} else if (intentParams.authUrl == "") {
|
||||||
|
message.setMessage(getString(R.string.problem_authurl))
|
||||||
|
} else if (intentParams.origin == "") {
|
||||||
|
message.setMessage(getString(R.string.problem_originurl))
|
||||||
|
} else {
|
||||||
|
message.setMessage(getString(R.string.problem_other))
|
||||||
|
}
|
||||||
|
message.setPositiveButton(getString(R.string.continue_button)) {_, _ ->
|
||||||
val resultIntent = Intent()
|
val resultIntent = Intent()
|
||||||
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
}
|
}
|
||||||
goToTheNextFragment(true, mobile)
|
message.show()
|
||||||
}
|
}
|
||||||
binding!!.beginButton.setOnClickListener { goToTheNextFragment() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method where all the initial checks that should be done before any user input is accepted should be added.
|
* Checks the state of the CAN, saved or not saved. Updates the text and logo.
|
||||||
*/
|
*/
|
||||||
private fun initialChecks() {
|
private fun canState() {
|
||||||
viewModel.checkCan(requireContext())
|
if (viewModel.userCan.length == 6) {
|
||||||
viewModel.checkPin(requireContext())
|
binding.canStatusText.text = getString(R.string.can_status_saved)
|
||||||
displayStates()
|
binding.canStatusLogo.setImageResource(R.drawable.ic_check_logo)
|
||||||
}
|
canSaved = true
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the process of interacting with the ID card by sending user to the CAN fragment.
|
|
||||||
*/
|
|
||||||
private fun goToTheNextFragment(auth: Boolean = false, mobile: Boolean = false) {
|
|
||||||
// Making settings menu inactive
|
|
||||||
(activity as MainActivity).menuAvailable = false
|
|
||||||
// Currently saving is true because the application is not yet integrated with
|
|
||||||
// other applications or websites.
|
|
||||||
// TODO: Check the navigation action default values. Not everything has to be declared explicitly.
|
|
||||||
if (auth) {
|
|
||||||
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = false, auth = true, mobile = mobile)
|
|
||||||
findNavController().navigate(action)
|
|
||||||
} else {
|
} else {
|
||||||
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = true, auth = false, mobile = mobile)
|
binding.canStatusText.text = getString(R.string.can_status_negative)
|
||||||
findNavController().navigate(action)
|
binding.canStatusLogo.setImageResource(R.drawable.ic_info_logo)
|
||||||
|
canSaved = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the state of the PIN 1, saved or not saved. Updates the text and logo.
|
||||||
|
*/
|
||||||
|
private fun pinState() {
|
||||||
|
if (viewModel.userPin.length in 4..12) {
|
||||||
|
binding.pinStatusText.text = getString(R.string.pin_status_saved)
|
||||||
|
binding.pinStatusLogo.setImageResource(R.drawable.ic_check_logo)
|
||||||
|
} else {
|
||||||
|
binding.pinStatusText.text = getString(R.string.pin_status_negative)
|
||||||
|
binding.pinStatusLogo.setImageResource(R.drawable.ic_info_logo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,33 +176,117 @@ class HomeFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the state of the CAN, saved or not saved. Updates the text and logo.
|
* Method where all the initial checks that should be completed before any user input is accepted should be conducted.
|
||||||
*/
|
*/
|
||||||
private fun canState() {
|
private fun initialChecks() {
|
||||||
if (viewModel.userCan.length == 6) {
|
viewModel.checkCan(requireContext())
|
||||||
binding!!.canStatusText.text = getString(R.string.can_status_saved)
|
viewModel.checkPin(requireContext())
|
||||||
binding!!.canStatusLogo.setImageResource(R.drawable.ic_check_logo)
|
displayStates()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a help message to the user explaining what the CAN is
|
||||||
|
*/
|
||||||
|
private fun displayMessage(title: String, message: String) {
|
||||||
|
val dialog = MaterialAlertDialogBuilder(requireContext())
|
||||||
|
.setTitle(title)
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton(R.string.return_text){_, _ -> }
|
||||||
|
.show()
|
||||||
|
val title = dialog.findViewById<TextView>(R.id.alertTitle)
|
||||||
|
title?.textSize = 24F
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs user whether the ID card can be detected or not.
|
||||||
|
*/
|
||||||
|
private fun updateAction(canIsSaved: Boolean) {
|
||||||
|
if (canIsSaved) {
|
||||||
|
binding.detectionActionText.text = getString(R.string.action_detect)
|
||||||
|
enableReaderMode()
|
||||||
|
binding.homeActionButton.visibility = View.GONE
|
||||||
|
binding.homeHelpButton.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
binding!!.canStatusText.text = getString(R.string.can_status_negative)
|
binding.detectionActionText.text = getString(R.string.action_detect_unavailable)
|
||||||
binding!!.canStatusLogo.setImageResource(R.drawable.ic_info_logo)
|
binding.homeActionButton.text = getString(R.string.add_can_text)
|
||||||
|
binding.homeActionButton.setOnClickListener {
|
||||||
|
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(saving = true, fromhome = true)
|
||||||
|
findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
binding.homeHelpButton.setOnClickListener {
|
||||||
|
displayMessage(getString(R.string.can_question), getString(R.string.can_explanation))
|
||||||
|
}
|
||||||
|
binding.homeActionButton.visibility = View.VISIBLE
|
||||||
|
binding.homeHelpButton.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the state of the PIN 1, saved or not saved. Updates the text and logo.
|
* Resets the error message and allows the user to try again
|
||||||
*/
|
*/
|
||||||
private fun pinState() {
|
private fun reset() {
|
||||||
if (viewModel.userPin.length in 4..12) {
|
binding.homeActionButton.text = getString(R.string.try_again_text)
|
||||||
binding!!.pinStatusText.text = getString(R.string.pin_status_saved)
|
binding.homeActionButton.setOnClickListener {
|
||||||
binding!!.pinStatusLogo.setImageResource(R.drawable.ic_check_logo)
|
updateAction(canSaved)
|
||||||
|
}
|
||||||
|
binding.homeActionButton.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that enables the NFC reader mode, which allows the app to communicate with the ID card and retrieve information.
|
||||||
|
*/
|
||||||
|
private fun enableReaderMode() {
|
||||||
|
val adapter = NfcAdapter.getDefaultAdapter(activity)
|
||||||
|
if (adapter == null || !adapter.isEnabled) {
|
||||||
|
binding.detectionActionText.text = getString(R.string.nfc_not_available)
|
||||||
} else {
|
} else {
|
||||||
binding!!.pinStatusText.text = getString(R.string.pin_status_negative)
|
adapter.enableReaderMode(activity, { tag ->
|
||||||
binding!!.pinStatusLogo.setImageResource(R.drawable.ic_info_logo)
|
requireActivity().runOnUiThread {
|
||||||
|
binding.detectionActionText.text = getString(R.string.card_detected)
|
||||||
|
}
|
||||||
|
val card = IsoDep.get(tag)
|
||||||
|
card.timeout = 32768
|
||||||
|
card.use {
|
||||||
|
try {
|
||||||
|
val comms = Comms(it, viewModel.userCan)
|
||||||
|
val response = comms.readPersonalData(byteArrayOf(1, 2, 6, 3, 4, 8))
|
||||||
|
viewModel.setUserFirstName(response[1])
|
||||||
|
viewModel.setUserLastName(response[0])
|
||||||
|
viewModel.setUserIdentificationNumber(response[2])
|
||||||
|
viewModel.setGender(response[3])
|
||||||
|
viewModel.setCitizenship(response[4])
|
||||||
|
viewModel.setExpiration(response[5])
|
||||||
|
requireActivity().runOnUiThread {
|
||||||
|
val action = HomeFragmentDirections.actionHomeFragmentToUserFragment()
|
||||||
|
findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
when(e) {
|
||||||
|
is TagLostException -> requireActivity().runOnUiThread {
|
||||||
|
binding.detectionActionText.text = getString(R.string.id_card_removed_early)
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
else -> requireActivity().runOnUiThread {
|
||||||
|
binding.detectionActionText.text = getString(R.string.nfc_reading_error)
|
||||||
|
viewModel.deleteCan(requireContext())
|
||||||
|
canState()
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
adapter.disableReaderMode(activity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
binding = null
|
if (receiver != null) {
|
||||||
|
requireActivity().unregisterReceiver(receiver)
|
||||||
|
}
|
||||||
|
_binding = null
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,6 +20,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
// If true the settings menu can be accessed from the toolbar in the upper part of the screen.
|
// If true the settings menu can be accessed from the toolbar in the upper part of the screen.
|
||||||
var menuAvailable: Boolean = true
|
var menuAvailable: Boolean = true
|
||||||
|
|
||||||
|
var inMenu: Boolean = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val binding = ActivityMainBinding.inflate(layoutInflater)
|
val binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
@ -40,9 +42,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
R.id.menu_settings_option -> {
|
R.id.menu_settings_option -> {
|
||||||
if (menuAvailable) {
|
if (menuAvailable) {
|
||||||
navigationController.navigate(R.id.action_homeFragment_to_settingsFragment)
|
navigationController.navigate(R.id.action_homeFragment_to_settingsFragment)
|
||||||
|
menuAvailable = false
|
||||||
|
inMenu = true
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this, getString(R.string.unavailable), Toast.LENGTH_SHORT).show()
|
if (!inMenu) {
|
||||||
|
Toast.makeText(this, getString(R.string.menu_unavailable_message), Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,23 +19,24 @@ class Pin2Fragment : Fragment() {
|
|||||||
|
|
||||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||||
|
|
||||||
private var binding: FragmentPin2Binding? = null
|
private var _binding: FragmentPin2Binding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentPin2Binding.inflate(inflater, container, false)
|
_binding = FragmentPin2Binding.inflate(inflater, container, false)
|
||||||
return binding!!.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding!!.nextButton.setOnClickListener {
|
binding.nextButton.setOnClickListener {
|
||||||
checkPin2Length()
|
checkPin2Length()
|
||||||
}
|
}
|
||||||
binding!!.cancelButton.setOnClickListener {
|
binding.cancelButton.setOnClickListener {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,7 +46,7 @@ class Pin2Fragment : Fragment() {
|
|||||||
* then it is saved to the viewModel.
|
* then it is saved to the viewModel.
|
||||||
*/
|
*/
|
||||||
private fun checkPin2Length() {
|
private fun checkPin2Length() {
|
||||||
val enteredPin2 = binding!!.pin2EditText.editText?.text.toString()
|
val enteredPin2 = binding.pin2EditText.editText?.text.toString()
|
||||||
if (enteredPin2.length in 5..12) {
|
if (enteredPin2.length in 5..12) {
|
||||||
viewModel.setUserPin2(enteredPin2)
|
viewModel.setUserPin2(enteredPin2)
|
||||||
} else {
|
} else {
|
||||||
@ -66,7 +67,7 @@ class Pin2Fragment : Fragment() {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,17 +1,22 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp
|
package com.tarkvaraprojekt.mobileauthapp
|
||||||
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentPinBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentPinBinding
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
|
|
||||||
@ -24,110 +29,67 @@ class PinFragment : Fragment() {
|
|||||||
|
|
||||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||||
|
|
||||||
private var binding: FragmentPinBinding? = null
|
private var _binding: FragmentPinBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
// Navigation arguments:
|
// Navigation arguments:
|
||||||
// saving = true means that the user must be returned to the settings menu
|
// saving = true means that the user must be returned to the settings menu
|
||||||
// reading = true means that we are reading information from the ID card that does
|
|
||||||
// not require PIN 1 so it is not necessary to ask it.
|
|
||||||
private val args: PinFragmentArgs by navArgs()
|
private val args: PinFragmentArgs by navArgs()
|
||||||
|
|
||||||
|
private var saveToggle = true
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentPinBinding.inflate(inflater, container, false)
|
_binding = FragmentPinBinding.inflate(inflater, container, false)
|
||||||
return binding!!.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
checkIfSkip()
|
checkIfSkip()
|
||||||
// If the user arrives from the settings menu then the button says
|
// Switch should be not visible when user is in savings mode
|
||||||
// save instead of continue.
|
|
||||||
if (args.saving) {
|
if (args.saving) {
|
||||||
binding!!.nextButton.text = getString(R.string.save_text)
|
binding.savePinQuestion.visibility = View.GONE
|
||||||
|
binding.saveLayout.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
saveToggle =
|
||||||
|
activity?.getPreferences(Context.MODE_PRIVATE)?.getBoolean("saveToggle", true) == true //Android Studio recommendation to get rid of Boolean?.
|
||||||
|
if (!saveToggle) {
|
||||||
|
binding.saveSwitch.isChecked = false
|
||||||
}
|
}
|
||||||
binding!!.nextButton.setOnClickListener { checkEnteredPin() }
|
binding.saveSwitch.setOnCheckedChangeListener { _, isChecked ->
|
||||||
binding!!.cancelButton.setOnClickListener { goToTheStart() }
|
if (isChecked) {
|
||||||
|
binding.saveStatus.text = getString(R.string.pin_save_on)
|
||||||
|
activity?.getPreferences(Context.MODE_PRIVATE)?.edit()?.putBoolean("saveToggle", true)?.apply()
|
||||||
|
} else {
|
||||||
|
binding.saveStatus.text = getString(R.string.pin_save_off)
|
||||||
|
activity?.getPreferences(Context.MODE_PRIVATE)?.edit()?.putBoolean("saveToggle", false)?.apply()
|
||||||
}
|
}
|
||||||
|
saveToggle = !saveToggle
|
||||||
/**
|
|
||||||
* Checks if the current fragment can be skipped or not.
|
|
||||||
* If the user has PIN 1 saved on the device or PIN 1 is not required
|
|
||||||
* then the PIN 1 won't be asked.
|
|
||||||
*/
|
|
||||||
private fun checkIfSkip() {
|
|
||||||
if (args.reading) {
|
|
||||||
goToTheNextFragment()
|
|
||||||
} else if (viewModel.userPin.length in 4..12) {
|
|
||||||
goToTheNextFragment()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
binding.buttonContinue.setOnClickListener { checkEnteredPin() }
|
||||||
|
binding.buttonCancel.setOnClickListener { goToTheStart() }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes user to the next fragment, which is AuthFragment.
|
* Takes user to the next fragment, which is AuthFragment.
|
||||||
*/
|
*/
|
||||||
private fun goToTheNextFragment() {
|
private fun goToTheNextFragment() {
|
||||||
val action = PinFragmentDirections.actionPinFragmentToAuthFragment(reading = args.reading, auth = args.auth, mobile = args.mobile)
|
val action = PinFragmentDirections.actionPinFragmentToAuthFragment(auth = args.auth, mobile = args.mobile)
|
||||||
findNavController().navigate(action)
|
findNavController().navigate(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the user has entered a PIN 1 with length between [4, 12] in the
|
|
||||||
* input field. If yes then the user is allowed to continue otherwise the user is
|
|
||||||
* allowed to modify the entered PIN 1.
|
|
||||||
*/
|
|
||||||
private fun checkEnteredPin() {
|
|
||||||
val enteredPin = binding!!.pinEditText.editText?.text.toString()
|
|
||||||
if (enteredPin.length in 4..12) {
|
|
||||||
viewModel.setUserPin(enteredPin)
|
|
||||||
if (args.saving) {
|
|
||||||
viewModel.storePin(requireContext())
|
|
||||||
goToTheStart()
|
|
||||||
} else {
|
|
||||||
val storePinQuestion = getDialog()
|
|
||||||
storePinQuestion?.show()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Toast.makeText(requireContext(), getString(R.string.length_pin), Toast.LENGTH_SHORT)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds a dialog that asks the user whether the entered PIN 1 should be saved
|
|
||||||
* on the device or not.
|
|
||||||
*/
|
|
||||||
private fun getDialog(): AlertDialog? {
|
|
||||||
return activity?.let { frag ->
|
|
||||||
val builder = AlertDialog.Builder(frag)
|
|
||||||
builder.apply {
|
|
||||||
// If response is positive save the PIN 1 on the device.
|
|
||||||
setPositiveButton(R.string.save_text) { _, _ ->
|
|
||||||
viewModel.storePin(
|
|
||||||
requireContext()
|
|
||||||
)
|
|
||||||
goToTheNextFragment()
|
|
||||||
}
|
|
||||||
setNegativeButton(R.string.deny_text) { _, _ ->
|
|
||||||
goToTheNextFragment()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.setMessage(R.string.pin_save_request)
|
|
||||||
builder.setTitle(R.string.save_pin_title)
|
|
||||||
builder.create()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns user to the start. If the user arrived from the settings menu then the start is
|
* Returns user to the start. If the user arrived from the settings menu then the start is
|
||||||
* settings menu not the HomeFragment.
|
* settings menu not the HomeFragment.
|
||||||
*/
|
*/
|
||||||
private fun goToTheStart() {
|
private fun goToTheStart() {
|
||||||
if (args.saving) {
|
if (args.saving) {
|
||||||
findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
|
findNavController().navigate(R.id.action_pinFragment_to_settingsFragment)
|
||||||
} else if (args.auth || args.mobile) {
|
} else if (args.auth || args.mobile) {
|
||||||
if (args.mobile) {
|
if (args.mobile) {
|
||||||
val resultIntent = Intent()
|
val resultIntent = Intent()
|
||||||
@ -141,8 +103,55 @@ class PinFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current fragment can be skipped or not.
|
||||||
|
* If the user has PIN 1 saved on the device or PIN 1 is not required
|
||||||
|
* then the PIN 1 won't be asked.
|
||||||
|
*/
|
||||||
|
private fun checkIfSkip() {
|
||||||
|
if (viewModel.userPin.length in 4..12) {
|
||||||
|
goToTheNextFragment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that creates and shows a snackbar that tells the user that PIN 1 has been saved
|
||||||
|
*/
|
||||||
|
private fun showSnackbar() {
|
||||||
|
val snackbar = Snackbar.make(requireView(), R.string.pin_status_saved, Snackbar.LENGTH_SHORT)
|
||||||
|
val snackbarText: TextView = snackbar.view.findViewById(R.id.snackbar_text)
|
||||||
|
snackbarText.setTextSize(TypedValue.COMPLEX_UNIT_SP, resources.getDimension(R.dimen.small_text))
|
||||||
|
snackbar.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the user has entered a PIN 1 with length between [4, 12] in the
|
||||||
|
* input field. If yes then the user is allowed to continue otherwise the user is
|
||||||
|
* allowed to modify the entered PIN 1.
|
||||||
|
*/
|
||||||
|
private fun checkEnteredPin() {
|
||||||
|
val enteredPin = binding.pinTextField.editText?.text.toString()
|
||||||
|
if (enteredPin.length in 4..12) {
|
||||||
|
viewModel.setUserPin(enteredPin)
|
||||||
|
if (args.saving) {
|
||||||
|
viewModel.storePin(requireContext())
|
||||||
|
showSnackbar()
|
||||||
|
goToTheStart()
|
||||||
|
} else {
|
||||||
|
if (saveToggle) {
|
||||||
|
viewModel.storePin(requireContext())
|
||||||
|
showSnackbar()
|
||||||
|
}
|
||||||
|
goToTheNextFragment()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(requireContext(), getString(R.string.pin_helper_text), Toast.LENGTH_SHORT)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,7 +24,8 @@ class ResultFragment : Fragment() {
|
|||||||
|
|
||||||
private val paramsModel: ParametersViewModel by activityViewModels()
|
private val paramsModel: ParametersViewModel by activityViewModels()
|
||||||
|
|
||||||
private var binding: FragmentResultBinding? = null
|
private var _binding: FragmentResultBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
private val args: ResultFragmentArgs by navArgs()
|
private val args: ResultFragmentArgs by navArgs()
|
||||||
|
|
||||||
@ -33,16 +34,27 @@ class ResultFragment : Fragment() {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentResultBinding.inflate(inflater, container, false)
|
_binding = FragmentResultBinding.inflate(inflater, container, false)
|
||||||
return binding!!.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding!!.resultBackButton.visibility = View.GONE
|
|
||||||
postToken()
|
postToken()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only used when the MobileAuthApp was launched by an app. Not for website use.
|
||||||
|
*/
|
||||||
|
private fun createResponse(success: Boolean = true, result: String = "noResult", token: String = "noToken") {
|
||||||
|
val responseCode = if (success) AppCompatActivity.RESULT_OK else AppCompatActivity.RESULT_CANCELED
|
||||||
|
val resultIntent = Intent()
|
||||||
|
resultIntent.putExtra("result", result)
|
||||||
|
resultIntent.putExtra("token", token)
|
||||||
|
requireActivity().setResult(responseCode, resultIntent)
|
||||||
|
requireActivity().finish()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a POST request to the backend server with a tokenItem
|
* Makes a POST request to the backend server with a tokenItem
|
||||||
*/
|
*/
|
||||||
@ -57,17 +69,13 @@ class ResultFragment : Fragment() {
|
|||||||
.setJsonObjectBody(json)
|
.setJsonObjectBody(json)
|
||||||
.asJsonObject()
|
.asJsonObject()
|
||||||
.setCallback { e, result ->
|
.setCallback { e, result ->
|
||||||
// do stuff with the result or error
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
// TODO: Set auth message failed and close the app
|
|
||||||
Log.i("Log thingy fail", "result was null")
|
|
||||||
if (args.mobile) {
|
if (args.mobile) {
|
||||||
createResponse(false)
|
createResponse(false)
|
||||||
} else {
|
} else {
|
||||||
requireActivity().finishAndRemoveTask()
|
requireActivity().finishAndRemoveTask()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.i("POST request response", result.toString())
|
|
||||||
if (args.mobile) {
|
if (args.mobile) {
|
||||||
createResponse(true, result.toString(), paramsModel.token)
|
createResponse(true, result.toString(), paramsModel.token)
|
||||||
} else {
|
} else {
|
||||||
@ -77,21 +85,9 @@ class ResultFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Only used when the MobileAuthApp was launched by an app. Not for website use.
|
|
||||||
*/
|
|
||||||
private fun createResponse(success: Boolean = true, result: String = "noResult", token: String = "noToken") {
|
|
||||||
val responseCode = if (success) AppCompatActivity.RESULT_OK else AppCompatActivity.RESULT_CANCELED
|
|
||||||
val resultIntent = Intent()
|
|
||||||
resultIntent.putExtra("result", result)
|
|
||||||
resultIntent.putExtra("token", token)
|
|
||||||
requireActivity().setResult(responseCode, resultIntent)
|
|
||||||
requireActivity().finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -20,33 +20,34 @@ class UserFragment : Fragment() {
|
|||||||
|
|
||||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||||
|
|
||||||
private var binding: FragmentUserBinding? = null
|
private var _binding: FragmentUserBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentUserBinding.inflate(inflater, container, false)
|
_binding = FragmentUserBinding.inflate(inflater, container, false)
|
||||||
return binding!!.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
displayInformation()
|
displayInformation()
|
||||||
binding!!.clearButton.setOnClickListener { goToTheStart() }
|
binding.clearButton.setOnClickListener { goToTheStart() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigns text values to the fields in order to display user information.
|
* Assigns text values to the fields in order to display user information.
|
||||||
*/
|
*/
|
||||||
private fun displayInformation() {
|
private fun displayInformation() {
|
||||||
binding!!.userName.text =
|
binding.userName.text =
|
||||||
getString(R.string.user_name, viewModel.userFirstName, viewModel.userLastName)
|
getString(R.string.user_name, viewModel.userFirstName, viewModel.userLastName)
|
||||||
binding!!.identificationNumber.text = viewModel.userIdentificationNumber
|
binding.identificationNumber.text = viewModel.userIdentificationNumber
|
||||||
binding!!.gender.text = viewModel.gender
|
binding.gender.text = viewModel.gender
|
||||||
binding!!.expiration.text = viewModel.expiration.replace(" ", "/")
|
binding.expiration.text = viewModel.expiration.replace(" ", "/")
|
||||||
binding!!.citizenship.text = viewModel.citizenship
|
binding.citizenship.text = viewModel.citizenship
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +60,6 @@ class UserFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,13 +1,17 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp.menu
|
package com.tarkvaraprojekt.mobileauthapp.menu
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.MainActivity
|
||||||
import com.tarkvaraprojekt.mobileauthapp.R
|
import com.tarkvaraprojekt.mobileauthapp.R
|
||||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentSettingsBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentSettingsBinding
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
@ -21,7 +25,8 @@ class SettingsFragment : Fragment() {
|
|||||||
|
|
||||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||||
|
|
||||||
private var binding: FragmentSettingsBinding? = null
|
private var _binding: FragmentSettingsBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
private var showPin: Boolean = false
|
private var showPin: Boolean = false
|
||||||
|
|
||||||
@ -30,8 +35,8 @@ class SettingsFragment : Fragment() {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentSettingsBinding.inflate(inflater, container, false)
|
_binding = FragmentSettingsBinding.inflate(inflater, container, false)
|
||||||
return binding!!.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
@ -39,10 +44,20 @@ class SettingsFragment : Fragment() {
|
|||||||
showCanField()
|
showCanField()
|
||||||
showPinField()
|
showPinField()
|
||||||
togglePinButton()
|
togglePinButton()
|
||||||
binding!!.canMenuAction.setOnClickListener { canAction() }
|
binding.canMenuAction.setOnClickListener { canAction() }
|
||||||
binding!!.pinMenuAction.setOnClickListener { pinAction() }
|
binding.pinMenuAction.setOnClickListener { pinAction() }
|
||||||
binding!!.pinMenuShow.setOnClickListener { togglePin() }
|
binding.pinMenuShow.setOnClickListener { togglePin() }
|
||||||
binding!!.returnButton.setOnClickListener { backToHome() }
|
binding.returnButton.setOnClickListener { backToHome() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for showing a snackbar with a message that is given as a parameter
|
||||||
|
*/
|
||||||
|
private fun showSnackbar(message: String) {
|
||||||
|
val snackbar = Snackbar.make(requireView(), message, Snackbar.LENGTH_SHORT)
|
||||||
|
val snackbarText: TextView = snackbar.view.findViewById(R.id.snackbar_text)
|
||||||
|
snackbarText.setTextSize(TypedValue.COMPLEX_UNIT_SP, resources.getDimension(R.dimen.small_text))
|
||||||
|
snackbar.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,11 +65,11 @@ class SettingsFragment : Fragment() {
|
|||||||
*/
|
*/
|
||||||
private fun showCanField() {
|
private fun showCanField() {
|
||||||
if (viewModel.userCan.length == 6) {
|
if (viewModel.userCan.length == 6) {
|
||||||
binding!!.canSaved.text = getString(R.string.saved_can, viewModel.userCan)
|
binding.canSaved.text = getString(R.string.saved_can, viewModel.userCan)
|
||||||
binding!!.canMenuAction.text = getString(R.string.can_delete)
|
binding.canMenuAction.text = getString(R.string.can_delete)
|
||||||
} else {
|
} else {
|
||||||
binding!!.canSaved.text = getString(R.string.saved_can, getString(R.string.missing))
|
binding.canSaved.text = getString(R.string.saved_can, getString(R.string.missing))
|
||||||
binding!!.canMenuAction.text = getString(R.string.can_add)
|
binding.canMenuAction.text = getString(R.string.add_can_text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +81,9 @@ class SettingsFragment : Fragment() {
|
|||||||
if (viewModel.userCan.length == 6) {
|
if (viewModel.userCan.length == 6) {
|
||||||
viewModel.deleteCan(requireContext())
|
viewModel.deleteCan(requireContext())
|
||||||
showCanField()
|
showCanField()
|
||||||
|
showSnackbar(getString(R.string.can_deleted))
|
||||||
} else {
|
} else {
|
||||||
|
(activity as MainActivity).inMenu = false
|
||||||
val action = SettingsFragmentDirections.actionSettingsFragmentToCanFragment(saving = true)
|
val action = SettingsFragmentDirections.actionSettingsFragmentToCanFragment(saving = true)
|
||||||
findNavController().navigate(action)
|
findNavController().navigate(action)
|
||||||
}
|
}
|
||||||
@ -79,16 +96,16 @@ class SettingsFragment : Fragment() {
|
|||||||
*/
|
*/
|
||||||
private fun showPinField() {
|
private fun showPinField() {
|
||||||
if (viewModel.userPin.length in 4..12) {
|
if (viewModel.userPin.length in 4..12) {
|
||||||
binding!!.pinMenuShow.visibility = Button.VISIBLE
|
binding.pinMenuShow.visibility = Button.VISIBLE
|
||||||
if (showPin)
|
if (showPin)
|
||||||
binding!!.pinSaved.text = getString(R.string.saved_pin, viewModel.userPin)
|
binding.pinSaved.text = getString(R.string.saved_pin, viewModel.userPin)
|
||||||
else
|
else
|
||||||
binding!!.pinSaved.text = getString(R.string.saved_pin, getString(R.string.hidden_pin))
|
binding.pinSaved.text = getString(R.string.saved_pin, getString(R.string.hidden_pin))
|
||||||
binding!!.pinMenuAction.text = getString(R.string.pin1_delete)
|
binding.pinMenuAction.text = getString(R.string.pin1_delete)
|
||||||
} else {
|
} else {
|
||||||
binding!!.pinMenuShow.visibility = Button.GONE
|
binding.pinMenuShow.visibility = Button.GONE
|
||||||
binding!!.pinSaved.text = getString(R.string.saved_pin, getString(R.string.missing))
|
binding.pinSaved.text = getString(R.string.saved_pin, getString(R.string.missing))
|
||||||
binding!!.pinMenuAction.text = getString(R.string.pin1_add)
|
binding.pinMenuAction.text = getString(R.string.pin1_add)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +117,9 @@ class SettingsFragment : Fragment() {
|
|||||||
if (viewModel.userPin.length in 4..12) {
|
if (viewModel.userPin.length in 4..12) {
|
||||||
viewModel.deletePin(requireContext())
|
viewModel.deletePin(requireContext())
|
||||||
showPinField()
|
showPinField()
|
||||||
|
showSnackbar(getString(R.string.pin_deleted))
|
||||||
} else {
|
} else {
|
||||||
|
(activity as MainActivity).inMenu = false
|
||||||
val action = SettingsFragmentDirections.actionSettingsFragmentToPinFragment(saving = true)
|
val action = SettingsFragmentDirections.actionSettingsFragmentToPinFragment(saving = true)
|
||||||
findNavController().navigate(action)
|
findNavController().navigate(action)
|
||||||
}
|
}
|
||||||
@ -120,9 +139,9 @@ class SettingsFragment : Fragment() {
|
|||||||
*/
|
*/
|
||||||
private fun togglePinButton() {
|
private fun togglePinButton() {
|
||||||
if (showPin) {
|
if (showPin) {
|
||||||
binding!!.pinMenuShow.text = getString(R.string.hide)
|
binding.pinMenuShow.text = getString(R.string.hide)
|
||||||
} else {
|
} else {
|
||||||
binding!!.pinMenuShow.text = getString(R.string.show)
|
binding.pinMenuShow.text = getString(R.string.show)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,12 +149,13 @@ class SettingsFragment : Fragment() {
|
|||||||
* Navigates back to home fragment.
|
* Navigates back to home fragment.
|
||||||
*/
|
*/
|
||||||
private fun backToHome() {
|
private fun backToHome() {
|
||||||
|
(activity as MainActivity).inMenu = false
|
||||||
findNavController().navigate(R.id.action_settingsFragment_to_homeFragment)
|
findNavController().navigate(R.id.action_settingsFragment_to_homeFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,34 +0,0 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp.network
|
|
||||||
|
|
||||||
import com.squareup.moshi.Moshi
|
|
||||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
|
||||||
import retrofit2.Response
|
|
||||||
import retrofit2.Retrofit
|
|
||||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
|
||||||
import retrofit2.http.Body
|
|
||||||
import retrofit2.http.GET
|
|
||||||
import retrofit2.http.Headers
|
|
||||||
import retrofit2.http.POST
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for making HTTP requests
|
|
||||||
* Based on https://developer.android.com/courses/pathways/android-basics-kotlin-unit-4-pathway-2
|
|
||||||
*/
|
|
||||||
const val BASE_URL =
|
|
||||||
"https://6bb0-85-253-195-252.ngrok.io"
|
|
||||||
|
|
||||||
private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
|
||||||
private val retrofit = Retrofit.Builder().addConverterFactory(MoshiConverterFactory.create(moshi))
|
|
||||||
.baseUrl(BASE_URL).build()
|
|
||||||
|
|
||||||
interface TokenApiService {
|
|
||||||
@Headers("Content-Type: application/json")
|
|
||||||
@POST("/auth/authentication")
|
|
||||||
suspend fun postToken(@Body data: String): Response<TokenItem>
|
|
||||||
}
|
|
||||||
|
|
||||||
object TokenApi {
|
|
||||||
val retrofitService : TokenApiService by lazy {
|
|
||||||
retrofit.create(TokenApiService::class.java)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp.network
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TokenItem for making POST request.
|
|
||||||
*/
|
|
||||||
data class TokenItem (
|
|
||||||
val token: String,
|
|
||||||
val challenge: String,
|
|
||||||
)
|
|
@ -5,7 +5,7 @@
|
|||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#3DDC84"
|
android:fillColor="#001970"
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#00000000"
|
android:fillColor="#00000000"
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="24dp"
|
android:padding="@dimen/padding"
|
||||||
tools:context=".AuthFragment">
|
tools:context=".AuthFragment">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/card_view"
|
android:id="@+id/card_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="@dimen/margin"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@ -23,31 +23,32 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="20sp">
|
android:padding="@dimen/padding_small">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/auth_fragment_instruction"
|
android:id="@+id/auth_fragment_instruction"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="6dp"
|
android:layout_margin="@dimen/margin"
|
||||||
android:gravity="center"
|
android:gravity="left"
|
||||||
android:text="@string/auth_instruction_text"
|
android:text="@string/auth_instruction_text"
|
||||||
android:textSize="20sp" />
|
android:textSize="@dimen/regular_text" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/nfc_logo"
|
android:id="@+id/nfc_logo"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="@dimen/logo_big"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="@dimen/logo_big"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_margin="6dp"
|
android:layout_margin="@dimen/margin"
|
||||||
|
android:padding="@dimen/margin_huge"
|
||||||
android:src="@drawable/nfc_logo" />
|
android:src="@drawable/nfc_logo" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/time_counter"
|
android:id="@+id/time_counter"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="6dp"
|
android:layout_margin="@dimen/margin"
|
||||||
android:textSize="14sp"
|
android:textSize="@dimen/regular_text"
|
||||||
app:layout_constraintTop_toBottomOf="@id/auth_fragment_instruction"
|
app:layout_constraintTop_toBottomOf="@id/auth_fragment_instruction"
|
||||||
tools:text="@string/time_left" />
|
tools:text="@string/time_left" />
|
||||||
|
|
||||||
@ -60,9 +61,9 @@
|
|||||||
android:id="@+id/next_button"
|
android:id="@+id/next_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="@dimen/margin_big"
|
||||||
android:text="@string/next_text"
|
android:text="@string/continue_button"
|
||||||
android:textSize="15sp"
|
android:textSize="@dimen/regular_text"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/cancel_button"
|
app:layout_constraintStart_toEndOf="@id/cancel_button"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
||||||
@ -71,10 +72,10 @@
|
|||||||
android:id="@+id/cancel_button"
|
android:id="@+id/cancel_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="@dimen/margin_big"
|
||||||
|
android:layout_marginStart="@dimen/padding_tiny"
|
||||||
android:text="@string/cancel_text"
|
android:text="@string/cancel_text"
|
||||||
android:textSize="15sp"
|
android:textSize="@dimen/regular_text"
|
||||||
app:layout_constraintEnd_toStartOf="@id/next_button"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
||||||
|
|
||||||
|
@ -4,82 +4,57 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="24dp"
|
android:padding="@dimen/padding"
|
||||||
tools:context=".CanFragment">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
|
||||||
android:id="@+id/card_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="8dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:strokeWidth="1dp"
|
|
||||||
app:strokeColor="@color/stroke_color"
|
|
||||||
app:cardElevation="0dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="20sp">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/enter_can"
|
android:id="@+id/title_text"
|
||||||
|
android:text="@string/can_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="6dp"
|
android:textSize="@dimen/headline_text"
|
||||||
android:text="@string/enter_can"
|
android:layout_margin="@dimen/margin_big"
|
||||||
android:textSize="20sp" />
|
android:fontFamily="sans-serif"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/can_edit_text"
|
android:id="@+id/canTextField"
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="6dp"
|
android:layout_margin="@dimen/margin_big"
|
||||||
android:hint="@string/text_can"
|
android:hint="@string/can_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/title_text"
|
||||||
|
app:helperTextEnabled="true"
|
||||||
|
app:helperText="@string/can_helper_text"
|
||||||
|
app:helperTextTextAppearance="@style/helper"
|
||||||
app:counterEnabled="true"
|
app:counterEnabled="true"
|
||||||
app:counterMaxLength="6"
|
app:counterMaxLength="6"
|
||||||
app:endIconMode="password_toggle"
|
app:counterTextAppearance="@style/helper"
|
||||||
app:errorEnabled="true"
|
app:counterOverflowTextAppearance="@style/helper"
|
||||||
app:helperText="@string/example_can"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
|
||||||
app:helperTextEnabled="true"
|
|
||||||
app:startIconDrawable="@drawable/can_logo">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="numberPassword"
|
android:textSize="@dimen/regular_text"
|
||||||
android:textSize="14sp" />
|
android:fontFamily="sans-serif"
|
||||||
|
android:inputType="number"
|
||||||
|
android:singleLine="true"
|
||||||
|
/>
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/next_button"
|
android:id="@+id/button_cancel"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:text="@string/next_text"
|
|
||||||
android:textSize="15sp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/cancel_button"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/cancel_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:text="@string/cancel_text"
|
android:text="@string/cancel_text"
|
||||||
android:textSize="15sp"
|
android:textSize="@dimen/regular_text"
|
||||||
app:layout_constraintEnd_toStartOf="@id/next_button"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/margin_big"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
app:layout_constraintTop_toBottomOf="@id/canTextField" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="24dp"
|
android:padding="@dimen/padding"
|
||||||
tools:context=".HomeFragment">
|
tools:context=".HomeFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -20,7 +20,7 @@
|
|||||||
android:id="@+id/can_status"
|
android:id="@+id/can_status"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="12dp"
|
android:layout_margin="@dimen/margin_big"
|
||||||
app:strokeWidth="1dp"
|
app:strokeWidth="1dp"
|
||||||
app:strokeColor="@color/stroke_color"
|
app:strokeColor="@color/stroke_color"
|
||||||
app:cardElevation="0dp">
|
app:cardElevation="0dp">
|
||||||
@ -32,14 +32,14 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/can_status_logo"
|
android:id="@+id/can_status_logo"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="@dimen/margin"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/can_status_text"
|
android:id="@+id/can_status_text"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:padding="12dp"
|
android:padding="@dimen/margin"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
@ -51,7 +51,7 @@
|
|||||||
android:id="@+id/pin_status"
|
android:id="@+id/pin_status"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="12dp"
|
android:layout_margin="@dimen/margin_big"
|
||||||
app:strokeWidth="1dp"
|
app:strokeWidth="1dp"
|
||||||
app:strokeColor="@color/stroke_color"
|
app:strokeColor="@color/stroke_color"
|
||||||
app:cardElevation="0dp">
|
app:cardElevation="0dp">
|
||||||
@ -63,14 +63,14 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/pin_status_logo"
|
android:id="@+id/pin_status_logo"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="@dimen/margin"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/pin_status_text"
|
android:id="@+id/pin_status_text"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:padding="12dp"
|
android:padding="@dimen/margin"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
@ -80,15 +80,49 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/id_card_detection"
|
||||||
|
android:layout_margin="@dimen/margin_big"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/saved_states"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/detection_action_text"
|
||||||
|
android:layout_margin="@dimen/margin_big"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
|
android:text="@string/action_detect"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/begin_button"
|
android:id="@+id/home_action_button"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
|
android:text="@string/try_again_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/begin_text"
|
android:layout_marginTop="@dimen/margin_small"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginStart="@dimen/margin_huge"
|
||||||
android:textSize="15sp"
|
android:visibility="gone"
|
||||||
app:layout_constraintTop_toBottomOf="@id/saved_states"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintTop_toBottomOf="@id/id_card_detection"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/home_help_button"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
|
android:text="@string/help_text"
|
||||||
|
android:layout_marginTop="@dimen/margin_small"
|
||||||
|
android:layout_marginStart="@dimen/margin_huge"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="?attr/materialButtonOutlinedStyle"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/home_action_button"/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -4,81 +4,111 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="24dp"
|
android:padding="@dimen/padding"
|
||||||
tools:context=".PinFragment">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
|
||||||
android:id="@+id/card_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="8dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:strokeWidth="1dp"
|
|
||||||
app:strokeColor="@color/stroke_color"
|
|
||||||
app:cardElevation="0dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="20dp">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/pin_fragment_text"
|
android:id="@+id/title_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="6dp"
|
android:layout_margin="@dimen/margin_big"
|
||||||
android:text="@string/pin_fragment" />
|
android:fontFamily="sans-serif"
|
||||||
|
android:text="@string/pin_view"
|
||||||
|
android:textSize="@dimen/headline_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/pin_edit_text"
|
android:id="@+id/pinTextField"
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="6dp"
|
android:layout_margin="@dimen/margin_big"
|
||||||
android:hint="@string/enter_pin"
|
android:hint="@string/hint_pin"
|
||||||
app:counterEnabled="true"
|
app:counterEnabled="true"
|
||||||
app:counterMaxLength="12"
|
app:counterMaxLength="12"
|
||||||
|
app:counterOverflowTextAppearance="@style/helper"
|
||||||
|
app:counterTextAppearance="@style/helper"
|
||||||
app:endIconMode="password_toggle"
|
app:endIconMode="password_toggle"
|
||||||
app:errorEnabled="true"
|
app:helperText="@string/pin_helper_text"
|
||||||
app:helperText="@string/example_pin"
|
|
||||||
app:helperTextEnabled="true"
|
app:helperTextEnabled="true"
|
||||||
app:startIconDrawable="@drawable/can_logo">
|
app:helperTextTextAppearance="@style/helper"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/title_text">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
android:inputType="numberPassword"
|
android:inputType="numberPassword"
|
||||||
android:textSize="14sp" />
|
android:singleLine="true"
|
||||||
|
android:textSize="@dimen/regular_text" />
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/save_pin_question"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/margin_big"
|
||||||
|
android:paddingTop="@dimen/padding"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:text="@string/save_pin"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/pinTextField" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/save_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/save_pin_question">
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/save_switch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/margin_big"
|
||||||
|
android:checked="true"
|
||||||
|
android:minWidth="48dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:layout_gravity="center_vertical"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/save_status"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/margin_big"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:text="@string/pin_save_on"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
|
android:layout_gravity="center_vertical"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/next_button"
|
android:id="@+id/button_continue"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_margin="@dimen/margin_big"
|
||||||
android:text="@string/next_text"
|
android:fontFamily="sans-serif"
|
||||||
android:textSize="15sp"
|
android:text="@string/continue_button"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:textSize="@dimen/regular_text"
|
||||||
app:layout_constraintStart_toEndOf="@id/cancel_button"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/cancel_button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:text="@string/cancel_text"
|
|
||||||
android:textSize="15sp"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/next_button"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
app:layout_constraintTop_toBottomOf="@id/save_layout" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button_cancel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/margin_big"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:text="@string/cancel_text"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/button_continue" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -64,7 +64,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
android:text="@string/next_text"
|
android:text="@string/continue_button"
|
||||||
android:textSize="15sp"
|
android:textSize="15sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/cancel_button"
|
app:layout_constraintStart_toEndOf="@id/cancel_button"
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="24dp"
|
android:padding="@dimen/padding"
|
||||||
tools:context=".ResultFragment">
|
tools:context=".ResultFragment">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/can_status"
|
android:id="@+id/can_status"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="12dp"
|
android:layout_margin="@dimen/margin"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
@ -27,33 +27,23 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/result_text"
|
android:id="@+id/result_text"
|
||||||
android:text="@string/result_text"
|
android:text="@string/result_text"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:padding="12dp"
|
android:padding="@dimen/padding_small"
|
||||||
android:layout_marginVertical="6dp"
|
android:layout_marginVertical="@dimen/margin_small"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/result_info_text"
|
android:id="@+id/result_info_text"
|
||||||
android:text="@string/result_info"
|
android:text="@string/result_info"
|
||||||
android:padding="12dp"
|
android:padding="@dimen/padding_small"
|
||||||
android:textSize="16sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:layout_marginVertical="6dp"
|
android:layout_marginVertical="@dimen/margin_small"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/result_back_button"
|
|
||||||
android:text="@string/return_text"
|
|
||||||
android:layout_marginHorizontal="12dp"
|
|
||||||
android:layout_marginVertical="6dp"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_margin="12dp"
|
android:layout_margin="@dimen/padding"
|
||||||
tools:context=".menu.SettingsFragment">
|
tools:context=".menu.SettingsFragment">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
@ -22,44 +22,46 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="12dp">
|
android:padding="@dimen/padding_small">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/can_saved"
|
android:id="@+id/can_saved"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:padding="12dp"
|
android:padding="@dimen/margin_small"
|
||||||
android:text="@string/saved_can" />
|
android:text="@string/saved_can" />
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/can_menu_action"
|
android:id="@+id/can_menu_action"
|
||||||
android:layout_margin="12dp"
|
android:layout_margin="@dimen/margin_small"
|
||||||
android:textSize="15sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/pin_saved"
|
android:id="@+id/pin_saved"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:padding="12dp"
|
android:padding="@dimen/margin_small"
|
||||||
android:text="@string/saved_pin"/>
|
android:text="@string/saved_pin"/>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="vertical">
|
||||||
<Button
|
|
||||||
android:id="@+id/pin_menu_action"
|
|
||||||
android:layout_margin="12dp"
|
|
||||||
android:textSize="15sp"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/pin_menu_show"
|
android:id="@+id/pin_menu_show"
|
||||||
android:layout_margin="12dp"
|
android:layout_marginHorizontal="@dimen/margin"
|
||||||
android:textSize="15sp"
|
android:layout_marginVertical="@dimen/margin_small"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="gone"/>
|
android:visibility="gone"/>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/pin_menu_action"
|
||||||
|
android:layout_marginHorizontal="@dimen/margin"
|
||||||
|
android:layout_marginVertical="@dimen/margin_small"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
@ -69,8 +71,9 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/return_text"
|
android:text="@string/return_text"
|
||||||
android:layout_margin="24dp"
|
android:layout_marginVertical="@dimen/margin"
|
||||||
android:textSize="15sp"
|
android:layout_marginStart="@dimen/padding"
|
||||||
|
android:textSize="@dimen/regular_text"
|
||||||
app:layout_constraintTop_toBottomOf="@id/settings_card"
|
app:layout_constraintTop_toBottomOf="@id/settings_card"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:padding="24dp"
|
android:padding="@dimen/padding"
|
||||||
tools:context=".UserFragment">
|
tools:context=".UserFragment">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/card_view"
|
android:id="@+id/card_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="@dimen/margin"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
@ -23,86 +26,86 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="20sp">
|
android:padding="@dimen/padding_tiny">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/user_name_label"
|
android:id="@+id/user_name_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/user_name_label"
|
android:text="@string/user_name_label"
|
||||||
android:textSize="14sp" />
|
android:textSize="@dimen/regular_text" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/user_name"
|
android:id="@+id/user_name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="@dimen/margin_small"
|
||||||
android:text="@string/user_name"
|
android:text="@string/user_name"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/identification_number_label"
|
android:id="@+id/identification_number_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="@dimen/margin_big"
|
||||||
android:text="@string/identification_number_label"
|
android:text="@string/identification_number_label"
|
||||||
android:textSize="14sp" />
|
android:textSize="@dimen/regular_text" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/identification_number"
|
android:id="@+id/identification_number"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="@dimen/margin_small"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/gender_label"
|
android:id="@+id/gender_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="@dimen/margin_big"
|
||||||
android:text="@string/gender_label"
|
android:text="@string/gender_label"
|
||||||
android:textSize="14sp" />
|
android:textSize="@dimen/regular_text" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/gender"
|
android:id="@+id/gender"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="@dimen/margin_small"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/expiration_label"
|
android:id="@+id/expiration_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="@dimen/margin_big"
|
||||||
android:text="@string/expiration_label"
|
android:text="@string/expiration_label"
|
||||||
android:textSize="14sp" />
|
android:textSize="@dimen/regular_text" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/expiration"
|
android:id="@+id/expiration"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="@dimen/margin_small"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/citizenship_label"
|
android:id="@+id/citizenship_label"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="@dimen/margin_big"
|
||||||
android:text="@string/citizenship_label"
|
android:text="@string/citizenship_label"
|
||||||
android:textSize="14sp" />
|
android:textSize="@dimen/regular_text" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/citizenship"
|
android:id="@+id/citizenship"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="@dimen/margin_small"
|
||||||
android:textSize="20sp"
|
android:textSize="@dimen/regular_text"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@ -113,11 +116,12 @@
|
|||||||
android:id="@+id/clear_button"
|
android:id="@+id/clear_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="@dimen/margin_big"
|
||||||
android:text="@string/clear_button"
|
android:text="@string/return_text"
|
||||||
android:textSize="18sp"
|
android:textSize="@dimen/regular_text"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</ScrollView>
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@drawable/ic_check_logo" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@drawable/ic_check_logo" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
@ -18,6 +18,9 @@
|
|||||||
android:id="@+id/action_homeFragment_to_canFragment"
|
android:id="@+id/action_homeFragment_to_canFragment"
|
||||||
app:destination="@id/canFragment"
|
app:destination="@id/canFragment"
|
||||||
app:popUpTo="@id/homeFragment" />
|
app:popUpTo="@id/homeFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_homeFragment_to_userFragment"
|
||||||
|
app:destination="@id/userFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/pinFragment"
|
android:id="@+id/pinFragment"
|
||||||
@ -42,10 +45,6 @@
|
|||||||
android:id="@+id/action_pinFragment_to_authFragment"
|
android:id="@+id/action_pinFragment_to_authFragment"
|
||||||
app:destination="@id/authFragment"
|
app:destination="@id/authFragment"
|
||||||
app:popUpTo="@id/homeFragment" />
|
app:popUpTo="@id/homeFragment" />
|
||||||
<argument
|
|
||||||
android:name="reading"
|
|
||||||
app:argType="boolean"
|
|
||||||
android:defaultValue="false" />
|
|
||||||
<argument
|
<argument
|
||||||
android:name="auth"
|
android:name="auth"
|
||||||
app:argType="boolean"
|
app:argType="boolean"
|
||||||
@ -78,10 +77,6 @@
|
|||||||
android:id="@+id/action_canFragment_to_pinFragment"
|
android:id="@+id/action_canFragment_to_pinFragment"
|
||||||
app:destination="@id/pinFragment"
|
app:destination="@id/pinFragment"
|
||||||
app:popUpTo="@id/homeFragment" />
|
app:popUpTo="@id/homeFragment" />
|
||||||
<argument
|
|
||||||
android:name="reading"
|
|
||||||
app:argType="boolean"
|
|
||||||
android:defaultValue="false" />
|
|
||||||
<argument
|
<argument
|
||||||
android:name="auth"
|
android:name="auth"
|
||||||
app:argType="boolean"
|
app:argType="boolean"
|
||||||
@ -90,6 +85,10 @@
|
|||||||
android:name="mobile"
|
android:name="mobile"
|
||||||
app:argType="boolean"
|
app:argType="boolean"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
|
<argument
|
||||||
|
android:name="fromhome"
|
||||||
|
app:argType="boolean"
|
||||||
|
android:defaultValue="false" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/authFragment"
|
android:id="@+id/authFragment"
|
||||||
@ -113,10 +112,6 @@
|
|||||||
android:name="auth"
|
android:name="auth"
|
||||||
app:argType="boolean"
|
app:argType="boolean"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
<argument
|
|
||||||
android:name="reading"
|
|
||||||
app:argType="boolean"
|
|
||||||
android:defaultValue="false" />
|
|
||||||
<argument
|
<argument
|
||||||
android:name="mobile"
|
android:name="mobile"
|
||||||
app:argType="boolean"
|
app:argType="boolean"
|
||||||
|
@ -1,29 +1,46 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<!-- Must translate to English, but should work now -->
|
<!-- Must translate to English, but should work now -->
|
||||||
<string name="app_name">NFC authentication</string>
|
<string name="app_name">NFC authenticator</string>
|
||||||
<string name="home_fragment">Work in progress</string>
|
|
||||||
|
<!-- BUTTONS -->
|
||||||
|
<string name="cancel_text">CANCEL</string>
|
||||||
|
<string name="return_text">BACK</string>
|
||||||
|
<string name="add_can_text">ADD CAN</string>
|
||||||
|
<string name="try_again_text">TRY AGAIN</string>
|
||||||
|
<string name="continue_button">CONTINUE</string>
|
||||||
|
|
||||||
|
<!-- Card Detection related -->
|
||||||
|
<string name="card_detected">Card detected. Hold it against the phone.</string>
|
||||||
|
<string name="data_read">Data read. You can continue.</string>
|
||||||
|
<string name="wrong_can_text">Wrong CAN</string>
|
||||||
|
<string name="action_detect">Put the ID card against the phone to detect it</string>
|
||||||
|
<string name="action_detect_unavailable">CAN must be added before ID card can be detected</string>
|
||||||
|
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
|
||||||
|
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
|
||||||
|
<string name="id_card_removed_early">ID card was removed too early</string>
|
||||||
|
<string name="wrong_pin">Wrong PIN 1. Tries on the card left %s</string>
|
||||||
|
|
||||||
<!-- string resources for HomeFragment -->
|
<!-- string resources for HomeFragment -->
|
||||||
<string name="pin_status_saved">PIN 1 saved</string>
|
<string name="pin_status_saved">PIN 1 saved</string>
|
||||||
<string name="pin_status_negative">PIN 1 not saved</string>
|
<string name="pin_status_negative">PIN 1 not saved</string>
|
||||||
<string name="can_status_saved">CAN saved</string>
|
<string name="can_status_saved">CAN saved</string>
|
||||||
<string name="can_status_negative">CAN not saved</string>
|
<string name="can_status_negative">CAN not saved</string>
|
||||||
|
<string name="help_text">HELP</string>
|
||||||
<string name="begin_text">READ ID CARD</string>
|
<string name="can_question">What is CAN?</string>
|
||||||
<string name="next_text">NEXT</string>
|
<string name="can_explanation">CAN is a 6 digit code that is needed to communicate with an ID card. It can be found on the ID card under the card holder\'s picture with a title KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string>
|
||||||
<string name="cancel_text">CANCEL</string>
|
<string name="problem_parameters">Problem with parameters</string>
|
||||||
<string name="save_text">SAVE</string>
|
<string name="problem_challenge">Challenge is missing</string>
|
||||||
<string name="deny_text">NO</string>
|
<string name="problem_authurl">AuthUrl is missing</string>
|
||||||
<string name="return_text">BACK</string>
|
<string name="problem_originurl">OriginUrl is missing</string>
|
||||||
|
<string name="problem_other">Unspecified problem with parameters</string>
|
||||||
<!-- string resources for PinFragment -->
|
<!-- string resources for PinFragment -->
|
||||||
<string name="pin_fragment">Please enter PIN 1</string>
|
<string name="pin_view">Please enter PIN 1</string>
|
||||||
<string name="enter_pin">PIN 1</string>
|
<string name="hint_pin">PIN 1</string>
|
||||||
<string name="example_pin">Example. 1234</string>
|
<string name="pin_helper_text">PIN 1 must be 4–12 digits long</string>
|
||||||
<string name="length_pin">Allowed length for PIN 1 is 4..12</string>
|
<string name="save_pin">Save PIN 1</string>
|
||||||
<string name="pin_save_request">PIN 1 is currently not saved. Do you wish to save the entered PIN 1? Saved PIN 1 will be entered automatically in the future. Saved PIN 1 can be changed and deleted in the settings menu.</string>
|
<string name="pin_save_on">On</string>
|
||||||
<string name="save_pin_title">Save PIN 1</string>
|
<string name="pin_save_off">Off</string>
|
||||||
|
|
||||||
<!-- string resources for Pin2Fragment -->
|
<!-- string resources for Pin2Fragment -->
|
||||||
<string name="pin2_fragment">Please enter PIN 2</string>
|
<string name="pin2_fragment">Please enter PIN 2</string>
|
||||||
@ -32,19 +49,14 @@
|
|||||||
<string name="length_pin2">Allowed length for PIN 2 is 5..12</string>
|
<string name="length_pin2">Allowed length for PIN 2 is 5..12</string>
|
||||||
|
|
||||||
<!-- string resources for CanFragment -->
|
<!-- string resources for CanFragment -->
|
||||||
<string name="example_can">Example. 123456</string>
|
<string name="can_view">Please enter CAN</string>
|
||||||
<string name="text_can">CAN</string>
|
<string name="can_text">CAN</string>
|
||||||
<string name="enter_can">Enter ID card\'s CAN (Card Access Number)</string>
|
<string name="can_helper_text">CAN must be 6 digits long</string>
|
||||||
<string name="length_can">Length of the CAN is wrong</string>
|
|
||||||
<string name="card_detected">Card detected. Hold it against the phone.</string>
|
|
||||||
<string name="data_read">Data read. You can continue.</string>
|
|
||||||
<string name="save_can_title">Save CAN</string>
|
|
||||||
|
|
||||||
<!-- string resources for AuthFragment layout -->
|
<!-- string resources for AuthFragment layout -->
|
||||||
<string name="auth_instruction_text">Put the ID card against the phone to establish connection</string>
|
<string name="auth_instruction_text">Put the ID card against the phone</string>
|
||||||
<string name="time_left">Time left %d sek</string>
|
<string name="time_left">Time left %d sek</string>
|
||||||
<string name="no_time">No time left</string>
|
<string name="no_time">No time left</string>
|
||||||
<string name="no_success">Wrong CAN</string>
|
|
||||||
|
|
||||||
<!-- string resources for UserFragment layout -->
|
<!-- string resources for UserFragment layout -->
|
||||||
<string name="user_name_label">NAME</string>
|
<string name="user_name_label">NAME</string>
|
||||||
@ -53,18 +65,14 @@
|
|||||||
<string name="expiration_label">DATE OF EXPIRY</string>
|
<string name="expiration_label">DATE OF EXPIRY</string>
|
||||||
<string name="citizenship_label">CITIZENSHIP</string>
|
<string name="citizenship_label">CITIZENSHIP</string>
|
||||||
<string name="gender_label">SEX</string>
|
<string name="gender_label">SEX</string>
|
||||||
<string name="clear_button">FORGET</string>
|
|
||||||
|
|
||||||
<!-- string resources for ResultFragment layout-->
|
<!-- string resources for ResultFragment layout-->
|
||||||
<string name="result_text">Controlling the created token</string>
|
<string name="result_text">Controlling the created token</string>
|
||||||
<string name="result_info">Wait for the app to close</string>
|
<string name="result_info">The app will close automatically</string>
|
||||||
|
|
||||||
<!-- menu -->
|
<!-- menu -->
|
||||||
<string name="menu_settings_title">Settings</string>
|
<string name="menu_settings_title">Settings</string>
|
||||||
<string name="menu_language_title">Language</string>
|
|
||||||
<string name="menu_action_unavailable">Currently unavailable</string>
|
|
||||||
<string name="saved_can">CAN: %s</string>
|
<string name="saved_can">CAN: %s</string>
|
||||||
<string name="can_add">Add CAN</string>
|
|
||||||
<string name="can_delete">Delete CAN</string>
|
<string name="can_delete">Delete CAN</string>
|
||||||
<string name="saved_pin">PIN1: %s</string>
|
<string name="saved_pin">PIN1: %s</string>
|
||||||
<string name="pin1_add">Add PIN1</string>
|
<string name="pin1_add">Add PIN1</string>
|
||||||
@ -73,6 +81,7 @@
|
|||||||
<string name="show">SHOW</string>
|
<string name="show">SHOW</string>
|
||||||
<string name="hide">HIDE</string>
|
<string name="hide">HIDE</string>
|
||||||
<string name="hidden_pin">****</string>
|
<string name="hidden_pin">****</string>
|
||||||
<string name="unavailable">Settings currently unavailabe</string>
|
<string name="menu_unavailable_message">Settings are currently unavailable</string>
|
||||||
<string name="can_save_request">CAN is currently not saved. Do you wish to save the CAN? Saved CAN will be entered automatically in the future. Saved CAN can be changed and deleted in the settings menu.</string>
|
<string name="can_deleted">CAN deleted</string>
|
||||||
|
<string name="pin_deleted">PIN 1 deleted</string>
|
||||||
</resources>
|
</resources>
|
@ -1,28 +1,45 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">NFC authentication</string>
|
<string name="app_name">NFC autentija</string>
|
||||||
<string name="home_fragment">Work in progress</string>
|
|
||||||
|
|
||||||
<string name="begin_text">LOE ID KAARTI</string>
|
<!-- Buttons -->
|
||||||
<string name="next_text">EDASI</string>
|
|
||||||
<string name="cancel_text">KATKESTA</string>
|
<string name="cancel_text">KATKESTA</string>
|
||||||
<string name="save_text">SALVESTA</string>
|
|
||||||
<string name="deny_text">EI</string>
|
|
||||||
<string name="return_text">TAGASI</string>
|
<string name="return_text">TAGASI</string>
|
||||||
|
<string name="add_can_text">LISA CAN</string>
|
||||||
|
<string name="try_again_text">ÜRITA UUESTI</string>
|
||||||
|
<string name="continue_button">JÄTKA</string>
|
||||||
|
|
||||||
|
<!-- Card Detection related -->
|
||||||
|
<string name="card_detected">Kaart tuvastatud. Hoia kaarti vastu telefoni.</string>
|
||||||
|
<string name="data_read">Andmed loetud, võid jätkata.</string>
|
||||||
|
<string name="wrong_can_text">Vale CAN</string>
|
||||||
|
<string name="action_detect">ID kaardi tuvastamiseks pane kaart vastu telefoni</string>
|
||||||
|
<string name="action_detect_unavailable">ID kaardi tuvastamiseks peab olema CAN lisatud</string>
|
||||||
|
<string name="nfc_not_available">NFC ei ole sisse lülitatud või puudub telefonil NFC võimekus</string>
|
||||||
|
<string name="nfc_reading_error">Sisestatud CAN ei ole vastavuses ID kaardiga</string>
|
||||||
|
<string name="id_card_removed_early">ID kaart eemaldati liiga vara</string>
|
||||||
|
<string name="wrong_pin">Vale PIN 1. ID kaardil PIN 1 sisetamise kordi alles: %s</string>
|
||||||
|
|
||||||
<!-- string resources for HomeFragment -->
|
<!-- string resources for HomeFragment -->
|
||||||
<string name="pin_status_saved">PIN 1 on salvestatud</string>
|
<string name="pin_status_saved">PIN 1 on salvestatud</string>
|
||||||
<string name="pin_status_negative">PIN 1 ei ole salvestatud</string>
|
<string name="pin_status_negative">PIN 1 ei ole salvestatud</string>
|
||||||
<string name="can_status_saved">CAN on salvestatud</string>
|
<string name="can_status_saved">CAN on salvestatud</string>
|
||||||
<string name="can_status_negative">CAN ei ole salvestatud</string>
|
<string name="can_status_negative">CAN ei ole salvestatud</string>
|
||||||
|
<string name="help_text">INFO</string>
|
||||||
|
<string name="can_question">Mis on CAN?</string>
|
||||||
|
<string name="can_explanation">CAN on 6 kohaline numbritest koosnev kood, mida on vaja ID kaardiga suhtlemiseks. CAN-i leiab ID kaardilt omaniku pildi alt pealkirjaga KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string>
|
||||||
|
<string name="problem_parameters">Probleem parameetritega</string>
|
||||||
|
<string name="problem_challenge">Puudub challenge parameeter</string>
|
||||||
|
<string name="problem_authurl">Puudub AuthUrl parameeter</string>
|
||||||
|
<string name="problem_originurl">Puudub OriginUrl parameeter</string>
|
||||||
|
<string name="problem_other">Täpsustamata probleem parameetritega</string>
|
||||||
<!-- string resources for PinFragment -->
|
<!-- string resources for PinFragment -->
|
||||||
<string name="pin_fragment">Palun sisesta PIN 1</string>
|
<string name="pin_view">Palun sisesta PIN 1</string>
|
||||||
<string name="enter_pin">PIN 1</string>
|
<string name="hint_pin">PIN 1</string>
|
||||||
<string name="example_pin">Näide. 1234</string>
|
<string name="pin_helper_text">PIN 1 lubatud pikkus on 4..12</string>
|
||||||
<string name="length_pin">PIN 1 lubatud pikkus on 4..12</string>
|
<string name="save_pin">Save PIN 1</string>
|
||||||
<string name="pin_save_request">Praegu ei ole rakenduses PIN 1 salvestatud. Kas sa soovid sisestatud PIN 1-te salvestada? Sellisel juhul sisestatakse see järgmisel korral automaatselt. Salvestatud PIN 1-te saab alati menüüs muuta ja kustutada.</string>
|
<string name="pin_save_on">On</string>
|
||||||
<string name="save_pin_title">Salvesta PIN 1</string>
|
<string name="pin_save_off">Off</string>
|
||||||
|
|
||||||
<!-- string resources for Pin2Fragment -->
|
<!-- string resources for Pin2Fragment -->
|
||||||
<string name="pin2_fragment">Palun sisesta PIN 2</string>
|
<string name="pin2_fragment">Palun sisesta PIN 2</string>
|
||||||
@ -31,25 +48,19 @@
|
|||||||
<string name="length_pin2">PIN 2 lubatud pikkus on 5..12</string>
|
<string name="length_pin2">PIN 2 lubatud pikkus on 5..12</string>
|
||||||
|
|
||||||
<!-- string resources for CanFragment -->
|
<!-- string resources for CanFragment -->
|
||||||
<string name="example_can">Näide. 123456</string>
|
<string name="can_view">Please enter CAN</string>
|
||||||
<string name="text_can">CAN</string>
|
<string name="can_text">CAN</string>
|
||||||
<string name="enter_can">Sisesta ID kaardi CAN (Card Access Number)</string>
|
<string name="can_helper_text">CAN must be 6 digits long</string>
|
||||||
<string name="length_can">CANi pikkus on vale</string>
|
|
||||||
<string name="card_detected">Kaart on tuvastatud. Hoia kaarti vastu telefoni.</string>
|
|
||||||
<string name="data_read">Andmed loetud. Võid edasi minna.</string>
|
|
||||||
<string name="can_save_request">Praegu ei ole rakenduses CAN salvestatud. Kas sa soovid sisestatud CANi salvestada? Sellisel juhul sisestatakse see järgmisel korral automaatselt. Salvestatud CANi saab alati menüüs muuta ja kustutada.</string> <string name="save_can_title">Salvesta CAN</string>
|
|
||||||
|
|
||||||
<!-- string resources for AuthFragment layout -->
|
<!-- string resources for AuthFragment layout -->
|
||||||
<string name="auth_instruction_text">ID kaardiga ühenduse loomiseks pane kaart vastu telefoni</string>
|
<string name="auth_instruction_text">Pane ID kaart vastu telefoni</string>
|
||||||
<string name="time_left">Aega on jäänud %d sek</string>
|
<string name="time_left">Aega on jäänud %d sek</string>
|
||||||
<string name="no_time">Aeg on otsas</string>
|
<string name="no_time">Aeg on otsas</string>
|
||||||
<string name="no_success">Vale CAN</string>
|
|
||||||
|
|
||||||
<!-- string resources for UserFragment layout -->
|
<!-- string resources for UserFragment layout -->
|
||||||
<string name="user_name_label">NIMI</string>
|
<string name="user_name_label">NIMI</string>
|
||||||
<string name="user_name">%1$s %2$s</string>
|
<string name="user_name">%1$s %2$s</string>
|
||||||
<string name="identification_number_label">ISIKUKOOD</string>
|
<string name="identification_number_label">ISIKUKOOD</string>
|
||||||
<string name="clear_button">UNUSTA</string>
|
|
||||||
<string name="expiration_label">KEHTIV KUNI</string>
|
<string name="expiration_label">KEHTIV KUNI</string>
|
||||||
<string name="citizenship_label">KODAKONDSUS</string>
|
<string name="citizenship_label">KODAKONDSUS</string>
|
||||||
<string name="gender_label">SUGU</string>
|
<string name="gender_label">SUGU</string>
|
||||||
@ -60,10 +71,7 @@
|
|||||||
|
|
||||||
<!-- menu -->
|
<!-- menu -->
|
||||||
<string name="menu_settings_title">Seaded</string>
|
<string name="menu_settings_title">Seaded</string>
|
||||||
<string name="menu_language_title">Keel</string>
|
|
||||||
<string name="menu_action_unavailable">Toiming pole hetkel saadaval</string>
|
|
||||||
<string name="saved_can">CAN: %s</string>
|
<string name="saved_can">CAN: %s</string>
|
||||||
<string name="can_add">Lisa CAN</string>
|
|
||||||
<string name="can_delete">Kustuta CAN</string>
|
<string name="can_delete">Kustuta CAN</string>
|
||||||
<string name="saved_pin">PIN1: %s</string>
|
<string name="saved_pin">PIN1: %s</string>
|
||||||
<string name="pin1_add">Lisa PIN1</string>
|
<string name="pin1_add">Lisa PIN1</string>
|
||||||
@ -72,5 +80,7 @@
|
|||||||
<string name="show">NÄITA</string>
|
<string name="show">NÄITA</string>
|
||||||
<string name="hide">PEIDA</string>
|
<string name="hide">PEIDA</string>
|
||||||
<string name="hidden_pin">****</string>
|
<string name="hidden_pin">****</string>
|
||||||
<string name="unavailable">Seaded pole hetkel saadaval</string>
|
<string name="menu_unavailable_message">Seaded pole hetkel saadaval</string>
|
||||||
|
<string name="can_deleted">CAN kustatud</string>
|
||||||
|
<string name="pin_deleted">PIN 1 kustatud</string>
|
||||||
</resources>
|
</resources>
|
@ -8,9 +8,9 @@
|
|||||||
<color name="black">#FF000000</color>
|
<color name="black">#FF000000</color>
|
||||||
<color name="white">#FFFFFFFF</color>
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
|
||||||
<color name="blue_200">#90caf9</color>
|
<color name="blue_200">#d1d9ff</color>
|
||||||
<color name="blue_500">#2196f3</color>
|
<color name="blue_500">#002984</color>
|
||||||
<color name="blue_700">#1976d2</color>
|
<color name="blue_700">#001970</color>
|
||||||
<color name="orange_200">#ffcc80</color>
|
<color name="orange_200">#ffab91</color>
|
||||||
<color name="orange_700">#f57c00</color>
|
<color name="orange_700">#f57c00</color>
|
||||||
</resources>
|
</resources>
|
15
MobileAuthApp/app/src/main/res/values/dimens.xml
Normal file
15
MobileAuthApp/app/src/main/res/values/dimens.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<dimen name="margin_small">4dp</dimen>
|
||||||
|
<dimen name="margin">8dp</dimen>
|
||||||
|
<dimen name="margin_big">16dp</dimen>
|
||||||
|
<dimen name="margin_huge">32dp</dimen>
|
||||||
|
<dimen name="padding_tiny">8dp</dimen>
|
||||||
|
<dimen name="padding_small">16dp</dimen>
|
||||||
|
<dimen name="padding">24dp</dimen>
|
||||||
|
<dimen name="regular_text">24sp</dimen>
|
||||||
|
<dimen name="headline_text">32sp</dimen>
|
||||||
|
<dimen name="helper_text">16sp</dimen>
|
||||||
|
<dimen name="small_text">8sp</dimen>
|
||||||
|
<dimen name="logo_big">128dp</dimen>
|
||||||
|
</resources>
|
@ -1,27 +1,44 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">NFC authentication</string>
|
<string name="app_name">NFC authenticator</string>
|
||||||
<string name="home_fragment">Work in progress</string>
|
|
||||||
|
|
||||||
<string name="begin_text">READ ID CARD</string>
|
<!-- BUTTONS -->
|
||||||
<string name="next_text">NEXT</string>
|
|
||||||
<string name="cancel_text">CANCEL</string>
|
<string name="cancel_text">CANCEL</string>
|
||||||
<string name="save_text">SAVE</string>
|
|
||||||
<string name="deny_text">NO</string>
|
|
||||||
<string name="return_text">BACK</string>
|
<string name="return_text">BACK</string>
|
||||||
|
<string name="add_can_text">ADD CAN</string>
|
||||||
|
<string name="try_again_text">TRY AGAIN</string>
|
||||||
|
<string name="continue_button">CONTINUE</string>
|
||||||
|
|
||||||
|
<!-- Card Detection related -->
|
||||||
|
<string name="card_detected">Card detected. Hold it against the phone.</string>
|
||||||
|
<string name="data_read">Data read. You can continue.</string>
|
||||||
|
<string name="wrong_can_text">Wrong CAN</string>
|
||||||
|
<string name="action_detect">Put the ID card against the phone to detect it</string>
|
||||||
|
<string name="action_detect_unavailable">CAN must be added before ID card can be detected</string>
|
||||||
|
<string name="nfc_not_available">NFC is not turned on or is not supported by the phone</string>
|
||||||
|
<string name="nfc_reading_error">The provided CAN does not match the ID card</string>
|
||||||
|
<string name="id_card_removed_early">ID card was removed too early</string>
|
||||||
|
<string name="wrong_pin">Wrong PIN 1. Tries on the card left %s</string>
|
||||||
|
|
||||||
<!-- string resources for HomeFragment -->
|
<!-- string resources for HomeFragment -->
|
||||||
<string name="pin_status_saved">PIN 1 saved</string>
|
<string name="pin_status_saved">PIN 1 saved</string>
|
||||||
<string name="pin_status_negative">PIN 1 not saved</string>
|
<string name="pin_status_negative">PIN 1 not saved</string>
|
||||||
<string name="can_status_saved">CAN saved</string>
|
<string name="can_status_saved">CAN saved</string>
|
||||||
<string name="can_status_negative">CAN not saved</string>
|
<string name="can_status_negative">CAN not saved</string>
|
||||||
|
<string name="help_text">HELP</string>
|
||||||
|
<string name="can_question">What is CAN?</string>
|
||||||
|
<string name="can_explanation">CAN is a 6 digit code that is needed to communicate with an ID card. It can be found on the ID card under the card holder\'s picture with a title KASUTAJA ALLKIRI/HOLDER\'S SIGNATURE.</string>
|
||||||
|
<string name="problem_parameters">Problem with parameters</string>
|
||||||
|
<string name="problem_challenge">Challenge is missing</string>
|
||||||
|
<string name="problem_authurl">AuthUrl is missing</string>
|
||||||
|
<string name="problem_originurl">OriginUrl is missing</string>
|
||||||
|
<string name="problem_other">Unspecified problem with parameters</string>
|
||||||
<!-- string resources for PinFragment -->
|
<!-- string resources for PinFragment -->
|
||||||
<string name="pin_fragment">Please enter PIN 1</string>
|
<string name="pin_view">Please enter PIN 1</string>
|
||||||
<string name="enter_pin">PIN 1</string>
|
<string name="hint_pin">PIN 1</string>
|
||||||
<string name="example_pin">Example. 1234</string>
|
<string name="pin_helper_text">PIN 1 must be 4–12 digits long</string>
|
||||||
<string name="length_pin">Allowed length for PIN 1 is 4..12</string>
|
<string name="save_pin">Save PIN 1</string>
|
||||||
<string name="pin_save_request">PIN 1 is currently not saved. Do you wish to save the entered PIN 1? Saved PIN 1 will be entered automatically in the future. Saved PIN 1 can be changed and deleted in the settings menu.</string>
|
<string name="pin_save_on">On</string>
|
||||||
<string name="save_pin_title">Save PIN 1</string>
|
<string name="pin_save_off">Off</string>
|
||||||
|
|
||||||
<!-- string resources for Pin2Fragment -->
|
<!-- string resources for Pin2Fragment -->
|
||||||
<string name="pin2_fragment">Please enter PIN 2</string>
|
<string name="pin2_fragment">Please enter PIN 2</string>
|
||||||
@ -30,20 +47,14 @@
|
|||||||
<string name="length_pin2">Allowed length for PIN 2 is 5..12</string>
|
<string name="length_pin2">Allowed length for PIN 2 is 5..12</string>
|
||||||
|
|
||||||
<!-- string resources for CanFragment -->
|
<!-- string resources for CanFragment -->
|
||||||
<string name="example_can">Example. 123456</string>
|
<string name="can_view">Please enter CAN</string>
|
||||||
<string name="text_can">CAN</string>
|
<string name="can_text">CAN</string>
|
||||||
<string name="enter_can">Enter ID card\'s CAN (Card Access Number)</string>
|
<string name="can_helper_text">CAN must be 6 digits long</string>
|
||||||
<string name="length_can">Length of the CAN is wrong</string>
|
|
||||||
<string name="card_detected">Card detected. Hold it against the phone.</string>
|
|
||||||
<string name="data_read">Data read. You can continue.</string>
|
|
||||||
<string name="can_save_request">CAN is currently not saved. Do you wish to save the CAN? Saved CAN will be entered automatically in the future. Saved CAN can be changed and deleted in the settings menu.</string>
|
|
||||||
<string name="save_can_title">Save CAN</string>
|
|
||||||
|
|
||||||
<!-- string resources for AuthFragment layout -->
|
<!-- string resources for AuthFragment layout -->
|
||||||
<string name="auth_instruction_text">Put the ID card against the phone to establish connection</string>
|
<string name="auth_instruction_text">Put the ID card against the phone</string>
|
||||||
<string name="time_left">Time left %d sek</string>
|
<string name="time_left">Time left %d sek</string>
|
||||||
<string name="no_time">No time left</string>
|
<string name="no_time">No time left</string>
|
||||||
<string name="no_success">Wrong CAN</string>
|
|
||||||
|
|
||||||
<!-- string resources for UserFragment layout -->
|
<!-- string resources for UserFragment layout -->
|
||||||
<string name="user_name_label">NAME</string>
|
<string name="user_name_label">NAME</string>
|
||||||
@ -52,18 +63,14 @@
|
|||||||
<string name="expiration_label">DATE OF EXPIRY</string>
|
<string name="expiration_label">DATE OF EXPIRY</string>
|
||||||
<string name="citizenship_label">CITIZENSHIP</string>
|
<string name="citizenship_label">CITIZENSHIP</string>
|
||||||
<string name="gender_label">SEX</string>
|
<string name="gender_label">SEX</string>
|
||||||
<string name="clear_button">FORGET</string>
|
|
||||||
|
|
||||||
<!-- string resources for ResultFragment layout-->
|
<!-- string resources for ResultFragment layout-->
|
||||||
<string name="result_text">Controlling the created token</string>
|
<string name="result_text">Controlling the created token</string>
|
||||||
<string name="result_info">Wait for the app to close</string>
|
<string name="result_info">The app will close automatically</string>
|
||||||
|
|
||||||
<!-- menu -->
|
<!-- menu -->
|
||||||
<string name="menu_settings_title">Settings</string>
|
<string name="menu_settings_title">Settings</string>
|
||||||
<string name="menu_language_title">Language</string>
|
|
||||||
<string name="menu_action_unavailable">Currently unavailable</string>
|
|
||||||
<string name="saved_can">CAN: %s</string>
|
<string name="saved_can">CAN: %s</string>
|
||||||
<string name="can_add">Add CAN</string>
|
|
||||||
<string name="can_delete">Delete CAN</string>
|
<string name="can_delete">Delete CAN</string>
|
||||||
<string name="saved_pin">PIN1: %s</string>
|
<string name="saved_pin">PIN1: %s</string>
|
||||||
<string name="pin1_add">Add PIN 1</string>
|
<string name="pin1_add">Add PIN 1</string>
|
||||||
@ -72,5 +79,7 @@
|
|||||||
<string name="show">SHOW</string>
|
<string name="show">SHOW</string>
|
||||||
<string name="hide">HIDE</string>
|
<string name="hide">HIDE</string>
|
||||||
<string name="hidden_pin">****</string>
|
<string name="hidden_pin">****</string>
|
||||||
<string name="unavailable">Settings currently unavailable</string>
|
<string name="menu_unavailable_message">Settings are currently unavailable</string>
|
||||||
|
<string name="can_deleted">CAN deleted</string>
|
||||||
|
<string name="pin_deleted">PIN 1 deleted</string>
|
||||||
</resources>
|
</resources>
|
7
MobileAuthApp/app/src/main/res/values/styles.xml
Normal file
7
MobileAuthApp/app/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<style name="helper">
|
||||||
|
<item name="android:fontFamily">sans-serif</item>
|
||||||
|
<item name="android:textSize">@dimen/helper_text</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
@ -9,7 +9,6 @@ import android.view.View
|
|||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import com.example.testmobileapp.databinding.ActivityMainBinding
|
import com.example.testmobileapp.databinding.ActivityMainBinding
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import com.koushikdutta.ion.Ion
|
import com.koushikdutta.ion.Ion
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
@ -35,9 +34,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
authLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { response ->
|
authLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { response ->
|
||||||
if (response.resultCode == Activity.RESULT_OK) {
|
if (response.resultCode == Activity.RESULT_OK) {
|
||||||
// Currently we are not actually checking whether we get a valid token.
|
|
||||||
// For testing purposes only, to make sure that we are able to get a response at all.
|
|
||||||
binding.loginTextView.text = getString(R.string.auth_success)
|
binding.loginTextView.text = getString(R.string.auth_success)
|
||||||
|
// Logs are used to show what information can be retrieved from the mobileauthapp.
|
||||||
Log.i("getResult", response.data?.getStringExtra("token").toString())
|
Log.i("getResult", response.data?.getStringExtra("token").toString())
|
||||||
Log.i("getResult", response.data?.getStringExtra("result").toString())
|
Log.i("getResult", response.data?.getStringExtra("result").toString())
|
||||||
var user = ""
|
var user = ""
|
||||||
@ -48,14 +46,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
Log.i("getResult", "unable to retrieve name from principal")
|
Log.i("getResult", "unable to retrieve name from principal")
|
||||||
}
|
}
|
||||||
showResult(user)
|
showResult(user)
|
||||||
/*
|
|
||||||
binding.loginOptionNfcButton.text = "Log Out"
|
|
||||||
binding.loginOptionNfcButton.setOnClickListener {
|
|
||||||
binding.loginOptionNfcButton.text = "NFC auth"
|
|
||||||
binding.loginOptionNfcButton.setOnClickListener { getData() }
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
if (response.resultCode == Activity.RESULT_CANCELED) {
|
if (response.resultCode == Activity.RESULT_CANCELED) {
|
||||||
binding.loginTextView.text = getString(R.string.auth_failure)
|
binding.loginTextView.text = getString(R.string.auth_failure)
|
||||||
@ -114,6 +104,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
binding.resultLayout.visibility = View.VISIBLE
|
binding.resultLayout.visibility = View.VISIBLE
|
||||||
binding.resultObject.text = getString(R.string.hello, user)
|
binding.resultObject.text = getString(R.string.hello, user)
|
||||||
binding.buttonForget.setOnClickListener {
|
binding.buttonForget.setOnClickListener {
|
||||||
|
binding.loginTextView.text = getString(R.string.login_text)
|
||||||
binding.resultObject.text = ""
|
binding.resultObject.text = ""
|
||||||
binding.resultLayout.visibility = View.GONE
|
binding.resultLayout.visibility = View.GONE
|
||||||
binding.loginOptions.visibility = View.VISIBLE
|
binding.loginOptions.visibility = View.VISIBLE
|
||||||
|
Loading…
Reference in New Issue
Block a user