mirror of
https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC.git
synced 2024-11-16 19:00:59 +02:00
commit
71db5cc9e6
@ -59,4 +59,7 @@ dependencies {
|
|||||||
//For cryptography
|
//For cryptography
|
||||||
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69'
|
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69'
|
||||||
|
|
||||||
|
//SecureDataStoring
|
||||||
|
implementation("androidx.security:security-crypto:1.0.0")
|
||||||
|
|
||||||
}
|
}
|
@ -78,10 +78,13 @@ class AuthFragment : Fragment() {
|
|||||||
card.use {
|
card.use {
|
||||||
try {
|
try {
|
||||||
val comms = Comms(it, viewModel.userCan)
|
val comms = Comms(it, viewModel.userCan)
|
||||||
val response = comms.readPersonalData(byteArrayOf(1, 2, 6))
|
val response = comms.readPersonalData(byteArrayOf(1, 2, 6, 3, 4, 8))
|
||||||
viewModel.setUserFirstName(response[1])
|
viewModel.setUserFirstName(response[1])
|
||||||
viewModel.setUserLastName(response[0])
|
viewModel.setUserLastName(response[0])
|
||||||
viewModel.setUserIdentificationNumber(response[2])
|
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)
|
binding!!.timeCounter.text = getString(R.string.data_read)
|
||||||
}
|
}
|
||||||
@ -89,6 +92,8 @@ class AuthFragment : Fragment() {
|
|||||||
requireActivity().runOnUiThread {
|
requireActivity().runOnUiThread {
|
||||||
binding!!.timeCounter.text = getString(R.string.no_success)
|
binding!!.timeCounter.text = getString(R.string.no_success)
|
||||||
}
|
}
|
||||||
|
// If the CAN is wrong we will also delete the saved CAN so that the user won't use it again.
|
||||||
|
viewModel.deleteCan(requireContext())
|
||||||
// Gives user some time to read the error message
|
// Gives user some time to read the error message
|
||||||
Thread.sleep(1000)
|
Thread.sleep(1000)
|
||||||
goToTheStart()
|
goToTheStart()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp
|
package com.tarkvaraprojekt.mobileauthapp
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -8,11 +9,14 @@ import android.widget.Toast
|
|||||||
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 com.tarkvaraprojekt.mobileauthapp.databinding.FragmentCanBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentCanBinding
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment that deals with asking the user for six digit CAN
|
* Fragment that deals with asking the user for a six digit CAN. If the CAN is already saved
|
||||||
|
* then the fragment is skipped immediately and if the CAN is not saved then the user
|
||||||
|
* is asked whether it should be saved for the future or not before continuing.
|
||||||
*/
|
*/
|
||||||
class CanFragment : Fragment() {
|
class CanFragment : Fragment() {
|
||||||
|
|
||||||
@ -20,6 +24,12 @@ class CanFragment : Fragment() {
|
|||||||
|
|
||||||
private var binding: FragmentCanBinding? = null
|
private var binding: FragmentCanBinding? = null
|
||||||
|
|
||||||
|
// Navigation arguments:
|
||||||
|
// 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()
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
@ -31,27 +41,92 @@ class CanFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
checkIfSkip()
|
||||||
binding!!.nextButton.setOnClickListener { goToNextFragment() }
|
// If the user arrives from the settings menu then the button should say
|
||||||
|
// save instead of continue.
|
||||||
|
if (args.saving) {
|
||||||
|
binding!!.nextButton.text = getString(R.string.save_text)
|
||||||
|
}
|
||||||
|
binding!!.nextButton.setOnClickListener { checkEnteredCan() }
|
||||||
binding!!.cancelButton.setOnClickListener { goToTheStart() }
|
binding!!.cancelButton.setOnClickListener { goToTheStart() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun goToNextFragment() {
|
/**
|
||||||
val enteredCan = binding!!.canEditText.editText?.text.toString()
|
* Checks if the current fragment can be skipped or not.
|
||||||
if (enteredCan.length != 6) {
|
* If the user has CAN saved on the device there is no need to ask it again.
|
||||||
Toast.makeText(requireContext(), getString(R.string.length_can), Toast.LENGTH_SHORT)
|
*/
|
||||||
.show()
|
private fun checkIfSkip() {
|
||||||
} else {
|
if (viewModel.userCan.length == 6) {
|
||||||
viewModel.setUserCan(
|
goToTheNextFragment()
|
||||||
binding!!.canEditText.editText?.text.toString()
|
|
||||||
)
|
|
||||||
findNavController().navigate(R.id.action_canFragment_to_authFragment)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes user to the next fragment, which is PinFragment.
|
||||||
|
*/
|
||||||
|
private fun goToTheNextFragment() {
|
||||||
|
val action = CanFragmentDirections.actionCanFragmentToPinFragment(reading = args.reading)
|
||||||
|
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.
|
||||||
|
* If the user arrived from the settings menu then the start is the settings menu
|
||||||
|
* not the HomeFragment.
|
||||||
|
*/
|
||||||
private fun goToTheStart() {
|
private fun goToTheStart() {
|
||||||
viewModel.clearUserInfo()
|
if (args.saving) {
|
||||||
findNavController().navigate(R.id.action_canFragment_to_homeFragment)
|
findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
|
||||||
|
} else {
|
||||||
|
findNavController().navigate(R.id.action_canFragment_to_homeFragment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
@ -10,6 +10,13 @@ import androidx.navigation.fragment.findNavController
|
|||||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HomeFragment is only shown to the user when then the user launches the application. When the application
|
||||||
|
* is launched by another application or a website then this Fragment will be skipped.
|
||||||
|
* This fragment uses the fields from the MainActivity by casting the activity to MainActivity.
|
||||||
|
* This might not be the best practice, but the application uses a single activity design so it should
|
||||||
|
* always work.
|
||||||
|
*/
|
||||||
class HomeFragment : Fragment() {
|
class HomeFragment : Fragment() {
|
||||||
|
|
||||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||||
@ -22,17 +29,72 @@ class HomeFragment : Fragment() {
|
|||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = FragmentHomeBinding.inflate(inflater, container, false)
|
binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||||
|
// Making settings menu active again
|
||||||
|
(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()
|
||||||
binding!!.beginButton.setOnClickListener { goToNextFragment() }
|
binding!!.beginButton.setOnClickListener { goToTheNextFragment() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun goToNextFragment() {
|
/**
|
||||||
findNavController().navigate(R.id.action_homeFragment_to_pinFragment)
|
* Method where all the initial checks that should be done before any user input is accepted should be added.
|
||||||
|
*/
|
||||||
|
private fun initialChecks() {
|
||||||
|
viewModel.checkCan(requireContext())
|
||||||
|
viewModel.checkPin(requireContext())
|
||||||
|
displayStates()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the process of interacting with the ID card by sending user to the CAN fragment.
|
||||||
|
*/
|
||||||
|
private fun goToTheNextFragment() {
|
||||||
|
// 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.
|
||||||
|
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = true)
|
||||||
|
findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays texts that inform the user whether the CAN and PIN 1 are saved on the device or not.
|
||||||
|
* This might help the user to save some time as checking menu is not necessary unless the user
|
||||||
|
* wishes to make changes to the saved CAN or PIN 1.
|
||||||
|
*/
|
||||||
|
private fun displayStates() {
|
||||||
|
canState()
|
||||||
|
pinState()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the state of the CAN, saved or not saved. Updates the text and logo.
|
||||||
|
*/
|
||||||
|
private fun canState() {
|
||||||
|
if (viewModel.userCan.length == 6) {
|
||||||
|
binding!!.canStatusText.text = getString(R.string.can_status_saved)
|
||||||
|
binding!!.canStatusLogo.setImageResource(R.drawable.ic_check_logo)
|
||||||
|
} else {
|
||||||
|
binding!!.canStatusText.text = getString(R.string.can_status_negative)
|
||||||
|
binding!!.canStatusLogo.setImageResource(R.drawable.ic_info_logo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -1,24 +1,51 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp
|
package com.tarkvaraprojekt.mobileauthapp
|
||||||
|
|
||||||
import android.nfc.NfcAdapter
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import com.tarkvaraprojekt.mobileauthapp.databinding.ActivityMainBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.ActivityMainBinding
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The only activity of the application (single activity design).
|
||||||
|
*/
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var navigationController: NavController
|
private lateinit var navigationController: NavController
|
||||||
|
|
||||||
|
// If true the settings menu can be accessed from the toolbar in the upper part of the screen.
|
||||||
|
var menuAvailable: Boolean = true
|
||||||
|
|
||||||
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)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
setSupportActionBar(binding.toolbar)
|
||||||
|
|
||||||
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||||
navigationController = navHostFragment.navController
|
navigationController = navHostFragment.navController
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
|
menuInflater.inflate(R.menu.menu, menu)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
|
||||||
|
R.id.menu_settings_option -> {
|
||||||
|
if (menuAvailable) {
|
||||||
|
navigationController.navigate(R.id.action_homeFragment_to_settingsFragment)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, getString(R.string.unavailable), Toast.LENGTH_SHORT).show()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp
|
package com.tarkvaraprojekt.mobileauthapp
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -8,11 +9,14 @@ import android.widget.Toast
|
|||||||
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 com.tarkvaraprojekt.mobileauthapp.databinding.FragmentPinBinding
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentPinBinding
|
||||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment that deals with asking the user for PIN1
|
* Fragment that deals with asking the user for PIN 1. If the user has already saved the PIN 1 then it is not asked again
|
||||||
|
* and the fragment is skipped and if the PIN 1 is not saved then the user is asked whether it should be saved or
|
||||||
|
* not before continuing.
|
||||||
*/
|
*/
|
||||||
class PinFragment : Fragment() {
|
class PinFragment : Fragment() {
|
||||||
|
|
||||||
@ -20,6 +24,12 @@ class PinFragment : Fragment() {
|
|||||||
|
|
||||||
private var binding: FragmentPinBinding? = null
|
private var binding: FragmentPinBinding? = null
|
||||||
|
|
||||||
|
// Navigation arguments:
|
||||||
|
// 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: CanFragmentArgs by navArgs()
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
@ -31,33 +41,94 @@ class PinFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
checkIfSkip()
|
||||||
binding!!.nextButton.setOnClickListener { goToNextFragment() }
|
// If the user arrives from the settings menu then the button says
|
||||||
|
// save instead of continue.
|
||||||
|
if (args.saving) {
|
||||||
|
binding!!.nextButton.text = getString(R.string.save_text)
|
||||||
|
}
|
||||||
|
binding!!.nextButton.setOnClickListener { checkEnteredPin() }
|
||||||
binding!!.cancelButton.setOnClickListener { goToTheStart() }
|
binding!!.cancelButton.setOnClickListener { goToTheStart() }
|
||||||
// Currently PIN 1 is not required and thus this step is immediately skipped.
|
|
||||||
// In the future the UI flow will be changed in the nav_graph.
|
|
||||||
goToNextFragment()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun goToNextFragment() {
|
/**
|
||||||
val enteredPin1 = binding!!.pinEditText.editText?.text.toString()
|
* Checks if the current fragment can be skipped or not.
|
||||||
if (enteredPin1.length in 4..12) {
|
* If the user has PIN 1 saved on the device or PIN 1 is not required
|
||||||
viewModel.setUserPin(
|
* then the PIN 1 won't be asked.
|
||||||
binding!!.pinEditText.editText?.text.toString()
|
*/
|
||||||
)
|
private fun checkIfSkip() {
|
||||||
findNavController().navigate(R.id.action_pinFragment_to_canFragment)
|
if (args.reading) {
|
||||||
} else {
|
goToTheNextFragment()
|
||||||
// Currently it is not important to enter PIN1 so we will allow the user to leave this field empty
|
} else if (viewModel.userPin.length in 4..12) {
|
||||||
//Toast.makeText(requireContext(), getString(R.string.length_pin), Toast.LENGTH_SHORT)
|
goToTheNextFragment()
|
||||||
// .show()
|
|
||||||
viewModel.setUserPin("1234")
|
|
||||||
findNavController().navigate(R.id.action_pinFragment_to_canFragment)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes user to the next fragment, which is AuthFragment.
|
||||||
|
*/
|
||||||
|
private fun goToTheNextFragment() {
|
||||||
|
findNavController().navigate(R.id.action_pinFragment_to_authFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* settings menu not the HomeFragment.
|
||||||
|
*/
|
||||||
private fun goToTheStart() {
|
private fun goToTheStart() {
|
||||||
viewModel.clearUserInfo()
|
if (args.saving) {
|
||||||
findNavController().navigate(R.id.action_pinFragment_to_homeFragment)
|
findNavController().navigate(R.id.action_pinFragment_to_settingsFragment)
|
||||||
|
} else {
|
||||||
|
viewModel.clearUserInfo()
|
||||||
|
findNavController().navigate(R.id.action_pinFragment_to_homeFragment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
@ -33,13 +33,25 @@ class UserFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
displayInformation()
|
||||||
binding!!.userName.text =
|
|
||||||
getString(R.string.user_name, viewModel.userFirstName, viewModel.userLastName)
|
|
||||||
binding!!.identificationNumber.text = viewModel.userIdentificationNumber
|
|
||||||
binding!!.clearButton.setOnClickListener { goToTheStart() }
|
binding!!.clearButton.setOnClickListener { goToTheStart() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns text values to the fields in order to display user information.
|
||||||
|
*/
|
||||||
|
private fun displayInformation() {
|
||||||
|
binding!!.userName.text =
|
||||||
|
getString(R.string.user_name, viewModel.userFirstName, viewModel.userLastName)
|
||||||
|
binding!!.identificationNumber.text = viewModel.userIdentificationNumber
|
||||||
|
binding!!.gender.text = viewModel.gender
|
||||||
|
binding!!.expiration.text = viewModel.expiration.replace(" ", "/")
|
||||||
|
binding!!.citizenship.text = viewModel.citizenship
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates user back to the start and also deletes any temporary information.
|
||||||
|
*/
|
||||||
private fun goToTheStart() {
|
private fun goToTheStart() {
|
||||||
viewModel.clearUserInfo()
|
viewModel.clearUserInfo()
|
||||||
findNavController().navigate(R.id.action_userFragment_to_homeFragment)
|
findNavController().navigate(R.id.action_userFragment_to_homeFragment)
|
||||||
|
@ -0,0 +1,141 @@
|
|||||||
|
package com.tarkvaraprojekt.mobileauthapp.menu
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Button
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.R
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentSettingsBinding
|
||||||
|
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This fragment allows the user to save the CAN and the PIN 1 and also to delete them if necessary.
|
||||||
|
* Should only be accessible for the user from the HomeFragment and not during the
|
||||||
|
* authentication process itself.
|
||||||
|
*/
|
||||||
|
class SettingsFragment : Fragment() {
|
||||||
|
|
||||||
|
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||||
|
|
||||||
|
private var binding: FragmentSettingsBinding? = null
|
||||||
|
|
||||||
|
private var showPin: Boolean = false
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
binding = FragmentSettingsBinding.inflate(inflater, container, false)
|
||||||
|
return binding!!.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
showCanField()
|
||||||
|
showPinField()
|
||||||
|
togglePinButton()
|
||||||
|
binding!!.canMenuAction.setOnClickListener { canAction() }
|
||||||
|
binding!!.pinMenuAction.setOnClickListener { pinAction() }
|
||||||
|
binding!!.pinMenuShow.setOnClickListener { togglePin() }
|
||||||
|
binding!!.returnButton.setOnClickListener { backToHome() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for showing the CAN field to the user and can be used to refresh the field as well.
|
||||||
|
*/
|
||||||
|
private fun showCanField() {
|
||||||
|
if (viewModel.userCan.length == 6) {
|
||||||
|
binding!!.canSaved.text = getString(R.string.saved_can, viewModel.userCan)
|
||||||
|
binding!!.canMenuAction.text = getString(R.string.can_delete)
|
||||||
|
} else {
|
||||||
|
binding!!.canSaved.text = getString(R.string.saved_can, getString(R.string.missing))
|
||||||
|
binding!!.canMenuAction.text = getString(R.string.can_add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that allows the user to delete saved CAN from the device and also to save new a CAN if
|
||||||
|
* currently there is no CAN saved.
|
||||||
|
*/
|
||||||
|
private fun canAction() {
|
||||||
|
if (viewModel.userCan.length == 6) {
|
||||||
|
viewModel.deleteCan(requireContext())
|
||||||
|
showCanField()
|
||||||
|
} else {
|
||||||
|
val action = SettingsFragmentDirections.actionSettingsFragmentToCanFragment(saving = true)
|
||||||
|
findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for showing the PIN 1 field to the user and can be used to refresh the field as well.
|
||||||
|
* The PIN 1 is hidden by default and when it is hidden it is always shown as **** despite the
|
||||||
|
* length of the PIN 1. Can be made visible with toggle button.
|
||||||
|
*/
|
||||||
|
private fun showPinField() {
|
||||||
|
if (viewModel.userPin.length in 4..12) {
|
||||||
|
binding!!.pinMenuShow.visibility = Button.VISIBLE
|
||||||
|
if (showPin)
|
||||||
|
binding!!.pinSaved.text = getString(R.string.saved_pin, viewModel.userPin)
|
||||||
|
else
|
||||||
|
binding!!.pinSaved.text = getString(R.string.saved_pin, getString(R.string.hidden_pin))
|
||||||
|
binding!!.pinMenuAction.text = getString(R.string.pin1_delete)
|
||||||
|
} else {
|
||||||
|
binding!!.pinMenuShow.visibility = Button.GONE
|
||||||
|
binding!!.pinSaved.text = getString(R.string.saved_pin, getString(R.string.missing))
|
||||||
|
binding!!.pinMenuAction.text = getString(R.string.pin1_add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that allows the user to delete saved PIN 1 from the device and also to save a new PIN 1 if
|
||||||
|
* currently there is no PIN 1 saved.
|
||||||
|
*/
|
||||||
|
private fun pinAction() {
|
||||||
|
if (viewModel.userPin.length in 4..12) {
|
||||||
|
viewModel.deletePin(requireContext())
|
||||||
|
showPinField()
|
||||||
|
} else {
|
||||||
|
val action = SettingsFragmentDirections.actionSettingsFragmentToPinFragment(saving = true)
|
||||||
|
findNavController().navigate(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the PIN 1 or makes it visible.
|
||||||
|
*/
|
||||||
|
private fun togglePin() {
|
||||||
|
showPin = !showPin
|
||||||
|
togglePinButton()
|
||||||
|
showPinField()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the text on the button that controls the visiblity of the PIN 1.
|
||||||
|
*/
|
||||||
|
private fun togglePinButton() {
|
||||||
|
if (showPin) {
|
||||||
|
binding!!.pinMenuShow.text = getString(R.string.hide)
|
||||||
|
} else {
|
||||||
|
binding!!.pinMenuShow.text = getString(R.string.show)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates back to home fragment.
|
||||||
|
*/
|
||||||
|
private fun backToHome() {
|
||||||
|
findNavController().navigate(R.id.action_settingsFragment_to_homeFragment)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
binding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
package com.tarkvaraprojekt.mobileauthapp.model
|
package com.tarkvaraprojekt.mobileauthapp.model
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.security.crypto.EncryptedSharedPreferences
|
||||||
|
import androidx.security.crypto.MasterKeys
|
||||||
|
|
||||||
class SmartCardViewModel: ViewModel() {
|
class SmartCardViewModel: ViewModel() {
|
||||||
|
|
||||||
@ -19,12 +23,24 @@ class SmartCardViewModel: ViewModel() {
|
|||||||
private var _userIdentificationNumber: String = ""
|
private var _userIdentificationNumber: String = ""
|
||||||
val userIdentificationNumber get() = _userIdentificationNumber
|
val userIdentificationNumber get() = _userIdentificationNumber
|
||||||
|
|
||||||
|
private var _gender: String = ""
|
||||||
|
val gender get() = _gender
|
||||||
|
|
||||||
|
private var _expiration: String = ""
|
||||||
|
val expiration get() = _expiration
|
||||||
|
|
||||||
|
private var _citizenship: String = ""
|
||||||
|
val citizenship get() = _citizenship
|
||||||
|
|
||||||
fun clearUserInfo() {
|
fun clearUserInfo() {
|
||||||
_userPin = ""
|
_userPin = ""
|
||||||
_userCan = ""
|
_userCan = ""
|
||||||
_userFirstName = ""
|
_userFirstName = ""
|
||||||
_userLastName = ""
|
_userLastName = ""
|
||||||
_userIdentificationNumber = ""
|
_userIdentificationNumber = ""
|
||||||
|
_expiration = ""
|
||||||
|
_citizenship = ""
|
||||||
|
_gender = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setUserPin(newUserPin: String) {
|
fun setUserPin(newUserPin: String) {
|
||||||
@ -47,4 +63,67 @@ class SmartCardViewModel: ViewModel() {
|
|||||||
_userIdentificationNumber = newUserIdentificationNumber
|
_userIdentificationNumber = newUserIdentificationNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setExpiration(newExpiration: String) {
|
||||||
|
_expiration = newExpiration
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setCitizenship(newCitizenship: String) {
|
||||||
|
_citizenship = newCitizenship
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setGender(newGender: String) {
|
||||||
|
_gender = newGender
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getSharedPreferences(context: Context): SharedPreferences {
|
||||||
|
val masterKeyAlias: String = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
|
||||||
|
return EncryptedSharedPreferences.create(
|
||||||
|
"user_creds",
|
||||||
|
masterKeyAlias,
|
||||||
|
context,
|
||||||
|
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||||
|
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun storeCan(context: Context) {
|
||||||
|
val sharedPreferences: SharedPreferences = getSharedPreferences(context)
|
||||||
|
sharedPreferences.edit().putString("CAN", userCan).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkCan(context: Context) {
|
||||||
|
val sharedPreferences: SharedPreferences = getSharedPreferences(context)
|
||||||
|
val foundCan = sharedPreferences.getString("CAN", null)
|
||||||
|
foundCan?.let {
|
||||||
|
_userCan = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be called from AuthFragment as well, when CAN is wrong.
|
||||||
|
fun deleteCan(context: Context) {
|
||||||
|
val sharedPreferences: SharedPreferences = getSharedPreferences(context)
|
||||||
|
sharedPreferences.edit().remove("CAN").apply()
|
||||||
|
_userCan = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fun storePin(context: Context) {
|
||||||
|
val sharedPreferences: SharedPreferences = getSharedPreferences(context)
|
||||||
|
sharedPreferences.edit().putString("PIN1", userPin).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkPin(context: Context) {
|
||||||
|
val sharedPreferences: SharedPreferences = getSharedPreferences(context)
|
||||||
|
val foundPin = sharedPreferences.getString("PIN1", null)
|
||||||
|
foundPin?.let {
|
||||||
|
_userPin = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deletePin(context: Context) {
|
||||||
|
val sharedPreferences: SharedPreferences = getSharedPreferences(context)
|
||||||
|
sharedPreferences.edit().remove("PIN1").apply()
|
||||||
|
_userPin = ""
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
6
MobileAuthApp/app/src/main/res/color/stroke_color.xml
Normal file
6
MobileAuthApp/app/src/main/res/color/stroke_color.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- For material card views as recommended in the material.io website -->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?attr/colorPrimary" android:state_checked="true"/>
|
||||||
|
<item android:alpha="0.12" android:color="?attr/colorOnSurface" android:state_checked="false"/>
|
||||||
|
</selector>
|
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z"/>
|
||||||
|
</vector>
|
10
MobileAuthApp/app/src/main/res/drawable/ic_check_logo.xml
Normal file
10
MobileAuthApp/app/src/main/res/drawable/ic_check_logo.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
|
||||||
|
</vector>
|
10
MobileAuthApp/app/src/main/res/drawable/ic_info_logo.xml
Normal file
10
MobileAuthApp/app/src/main/res/drawable/ic_info_logo.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
|
||||||
|
</vector>
|
10
MobileAuthApp/app/src/main/res/drawable/ic_settings.xml
Normal file
10
MobileAuthApp/app/src/main/res/drawable/ic_settings.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
|
||||||
|
</vector>
|
@ -6,12 +6,28 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:background="?attr/colorPrimary"
|
||||||
|
android:elevation="4dp"
|
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/nav_host_fragment"
|
android:id="@+id/nav_host_fragment"
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="0dp"
|
||||||
app:defaultNavHost="true"
|
app:defaultNavHost="true"
|
||||||
app:navGraph="@navigation/nav_graph" />
|
app:navGraph="@navigation/nav_graph"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/toolbar"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -14,7 +14,10 @@
|
|||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
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"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:strokeColor="@color/stroke_color"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -59,7 +62,7 @@
|
|||||||
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/next_text"
|
||||||
android:textSize="18sp"
|
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"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
||||||
@ -70,7 +73,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
android:text="@string/cancel_text"
|
android:text="@string/cancel_text"
|
||||||
android:textSize="18sp"
|
android:textSize="15sp"
|
||||||
app:layout_constraintEnd_toStartOf="@id/next_button"
|
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" />
|
||||||
|
@ -14,7 +14,10 @@
|
|||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
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"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:strokeColor="@color/stroke_color"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -63,7 +66,7 @@
|
|||||||
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/next_text"
|
||||||
android:textSize="18sp"
|
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"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
||||||
@ -74,7 +77,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
android:text="@string/cancel_text"
|
android:text="@string/cancel_text"
|
||||||
android:textSize="18dp"
|
android:textSize="15sp"
|
||||||
app:layout_constraintEnd_toStartOf="@id/next_button"
|
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" />
|
||||||
|
@ -7,23 +7,87 @@
|
|||||||
android:padding="24dp"
|
android:padding="24dp"
|
||||||
tools:context=".HomeFragment">
|
tools:context=".HomeFragment">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/home_fragment_text"
|
android:id="@+id/saved_states"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/home_fragment"
|
android:orientation="vertical"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/can_status"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="12dp"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:strokeColor="@color/stroke_color"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/can_status_logo"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/can_status_text"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/pin_status"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="12dp"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:strokeColor="@color/stroke_color"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/pin_status_logo"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pin_status_text"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- Temporary button for testing purposes -->
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/begin_button"
|
android:id="@+id/begin_button"
|
||||||
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:text="@string/begin_text"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/home_fragment_text"
|
android:textSize="15sp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/saved_states"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintEnd_toEndOf="parent"/>
|
||||||
|
|
||||||
|
@ -14,7 +14,10 @@
|
|||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
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"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:strokeColor="@color/stroke_color"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -62,6 +65,7 @@
|
|||||||
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/next_text"
|
||||||
|
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"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
||||||
@ -72,6 +76,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
android:text="@string/cancel_text"
|
android:text="@string/cancel_text"
|
||||||
|
android:textSize="15sp"
|
||||||
app:layout_constraintEnd_toStartOf="@id/next_button"
|
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" />
|
||||||
|
77
MobileAuthApp/app/src/main/res/layout/fragment_settings.xml
Normal file
77
MobileAuthApp/app/src/main/res/layout/fragment_settings.xml
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="12dp"
|
||||||
|
tools:context=".menu.SettingsFragment">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/settings_card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:strokeColor="@color/stroke_color"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/can_settings"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="12dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/can_saved"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:text="@string/saved_can" />
|
||||||
|
<Button
|
||||||
|
android:id="@+id/can_menu_action"
|
||||||
|
android:layout_margin="12dp"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pin_saved"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:text="@string/saved_pin"/>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<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
|
||||||
|
android:id="@+id/pin_menu_show"
|
||||||
|
android:layout_margin="12dp"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/return_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/return_text"
|
||||||
|
android:layout_margin="24dp"
|
||||||
|
android:textSize="15sp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/settings_card"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -14,7 +14,10 @@
|
|||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
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"
|
||||||
|
app:strokeWidth="1dp"
|
||||||
|
app:strokeColor="@color/stroke_color"
|
||||||
|
app:cardElevation="0dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -54,6 +57,54 @@
|
|||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/gender_label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="@string/gender_label"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/gender"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/expiration_label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="@string/expiration_label"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/expiration"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/citizenship_label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:text="@string/citizenship_label"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/citizenship"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
11
MobileAuthApp/app/src/main/res/menu/menu.xml
Normal file
11
MobileAuthApp/app/src/main/res/menu/menu.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_settings_option"
|
||||||
|
android:title="@string/menu_settings_title"
|
||||||
|
android:icon="@drawable/ic_settings"
|
||||||
|
app:showAsAction="always"/>
|
||||||
|
|
||||||
|
</menu>
|
@ -9,51 +9,81 @@
|
|||||||
android:id="@+id/homeFragment"
|
android:id="@+id/homeFragment"
|
||||||
android:name="com.tarkvaraprojekt.mobileauthapp.HomeFragment"
|
android:name="com.tarkvaraprojekt.mobileauthapp.HomeFragment"
|
||||||
android:label="fragment_home"
|
android:label="fragment_home"
|
||||||
tools:layout="@layout/fragment_home" >
|
tools:layout="@layout/fragment_home">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_homeFragment_to_pinFragment"
|
android:id="@+id/action_homeFragment_to_settingsFragment"
|
||||||
app:destination="@id/pinFragment"
|
app:destination="@id/settingsFragment"
|
||||||
/>
|
app:popUpTo="@id/homeFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_homeFragment_to_canFragment"
|
||||||
|
app:destination="@id/canFragment"
|
||||||
|
app:popUpTo="@id/homeFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/pinFragment"
|
android:id="@+id/pinFragment"
|
||||||
android:name="com.tarkvaraprojekt.mobileauthapp.PinFragment"
|
android:name="com.tarkvaraprojekt.mobileauthapp.PinFragment"
|
||||||
android:label="fragment_pin"
|
android:label="fragment_pin"
|
||||||
tools:layout="@layout/fragment_pin" >
|
tools:layout="@layout/fragment_pin">
|
||||||
<action
|
|
||||||
android:id="@+id/action_pinFragment_to_canFragment"
|
|
||||||
app:destination="@id/canFragment"
|
|
||||||
app:popUpTo="@id/homeFragment" />
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_pinFragment_to_homeFragment"
|
android:id="@+id/action_pinFragment_to_homeFragment"
|
||||||
app:destination="@id/homeFragment"
|
app:destination="@id/homeFragment"
|
||||||
app:popUpTo="@id/homeFragment"
|
app:popUpTo="@id/homeFragment"
|
||||||
app:popUpToInclusive="true" />
|
app:popUpToInclusive="true" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_pinFragment_to_settingsFragment"
|
||||||
|
app:destination="@id/settingsFragment"
|
||||||
|
app:popUpTo="@id/settingsFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
<argument
|
||||||
|
android:name="saving"
|
||||||
|
android:defaultValue="false"
|
||||||
|
app:argType="boolean" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_pinFragment_to_authFragment"
|
||||||
|
app:destination="@id/authFragment"
|
||||||
|
app:popUpTo="@id/homeFragment" />
|
||||||
|
<argument
|
||||||
|
android:name="reading"
|
||||||
|
app:argType="boolean"
|
||||||
|
android:defaultValue="false" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/canFragment"
|
android:id="@+id/canFragment"
|
||||||
android:name="com.tarkvaraprojekt.mobileauthapp.CanFragment"
|
android:name="com.tarkvaraprojekt.mobileauthapp.CanFragment"
|
||||||
android:label="fragment_can"
|
android:label="fragment_can"
|
||||||
tools:layout="@layout/fragment_can" >
|
tools:layout="@layout/fragment_can">
|
||||||
<action
|
|
||||||
android:id="@+id/action_canFragment_to_authFragment"
|
|
||||||
app:destination="@id/authFragment"
|
|
||||||
app:popUpTo="@id/homeFragment"/>
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_canFragment_to_homeFragment"
|
android:id="@+id/action_canFragment_to_homeFragment"
|
||||||
app:destination="@id/homeFragment"
|
app:destination="@id/homeFragment"
|
||||||
app:popUpTo="@id/homeFragment"
|
app:popUpTo="@id/homeFragment"
|
||||||
app:popUpToInclusive="true" />
|
app:popUpToInclusive="true" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_canFragment_to_settingsFragment"
|
||||||
|
app:destination="@id/settingsFragment"
|
||||||
|
app:popUpTo="@id/settingsFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
|
<argument
|
||||||
|
android:name="saving"
|
||||||
|
android:defaultValue="false"
|
||||||
|
app:argType="boolean" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_canFragment_to_pinFragment"
|
||||||
|
app:destination="@id/pinFragment"
|
||||||
|
app:popUpTo="@id/homeFragment" />
|
||||||
|
<argument
|
||||||
|
android:name="reading"
|
||||||
|
app:argType="boolean"
|
||||||
|
android:defaultValue="false" />
|
||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/authFragment"
|
android:id="@+id/authFragment"
|
||||||
android:name="com.tarkvaraprojekt.mobileauthapp.AuthFragment"
|
android:name="com.tarkvaraprojekt.mobileauthapp.AuthFragment"
|
||||||
android:label="fragment_auth"
|
android:label="fragment_auth"
|
||||||
tools:layout="@layout/fragment_auth" >
|
tools:layout="@layout/fragment_auth">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_authFragment_to_userFragment"
|
android:id="@+id/action_authFragment_to_userFragment"
|
||||||
app:destination="@id/userFragment"
|
app:destination="@id/userFragment"
|
||||||
app:popUpTo="@id/homeFragment"/>
|
app:popUpTo="@id/homeFragment" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_authFragment_to_homeFragment"
|
android:id="@+id/action_authFragment_to_homeFragment"
|
||||||
app:destination="@id/homeFragment"
|
app:destination="@id/homeFragment"
|
||||||
@ -64,11 +94,28 @@
|
|||||||
android:id="@+id/userFragment"
|
android:id="@+id/userFragment"
|
||||||
android:name="com.tarkvaraprojekt.mobileauthapp.UserFragment"
|
android:name="com.tarkvaraprojekt.mobileauthapp.UserFragment"
|
||||||
android:label="fragment_user"
|
android:label="fragment_user"
|
||||||
tools:layout="@layout/fragment_user" >
|
tools:layout="@layout/fragment_user">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_userFragment_to_homeFragment"
|
android:id="@+id/action_userFragment_to_homeFragment"
|
||||||
app:destination="@id/homeFragment"
|
app:destination="@id/homeFragment"
|
||||||
app:popUpTo="@id/homeFragment"
|
app:popUpTo="@id/homeFragment"
|
||||||
app:popUpToInclusive="true"/>
|
app:popUpToInclusive="true" />
|
||||||
|
</fragment>
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/settingsFragment"
|
||||||
|
android:name="com.tarkvaraprojekt.mobileauthapp.menu.SettingsFragment"
|
||||||
|
android:label="fragment_settings"
|
||||||
|
tools:layout="@layout/fragment_settings">
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_settingsFragment_to_canFragment"
|
||||||
|
app:destination="@id/canFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_settingsFragment_to_pinFragment"
|
||||||
|
app:destination="@id/pinFragment" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_settingsFragment_to_homeFragment"
|
||||||
|
app:destination="@id/homeFragment"
|
||||||
|
app:popUpTo="@id/homeFragment"
|
||||||
|
app:popUpToInclusive="true" />
|
||||||
</fragment>
|
</fragment>
|
||||||
</navigation>
|
</navigation>
|
68
MobileAuthApp/app/src/main/res/values-en/strings.xml
Normal file
68
MobileAuthApp/app/src/main/res/values-en/strings.xml
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Must translate to English, but should work now -->
|
||||||
|
<string name="app_name">NFC authentication</string>
|
||||||
|
<string name="home_fragment">Work in progress</string>
|
||||||
|
|
||||||
|
<!-- string resources for HomeFragment -->
|
||||||
|
<string name="pin_status_saved">PIN 1 on 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_negative">CAN ei ole salvestatud</string>
|
||||||
|
|
||||||
|
<string name="begin_text">LOE ID KAARTI</string>
|
||||||
|
<string name="next_text">EDASI</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 resources for PinFragment -->
|
||||||
|
<string name="pin_fragment">Palun sisesta PIN 1</string>
|
||||||
|
<string name="enter_pin">PIN 1</string>
|
||||||
|
<string name="example_pin">Näide. 1234</string>
|
||||||
|
<string name="length_pin">PIN 1 lubatud pikkus on 4..12</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="save_pin_title">Salvesta PIN 1</string>
|
||||||
|
|
||||||
|
<!-- string resources for CanFragment -->
|
||||||
|
<string name="example_can">Näide. 123456</string>
|
||||||
|
<string name="text_can">CAN</string>
|
||||||
|
<string name="enter_can">Sisesta ID kaardi CAN (Card Access Number)</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 name="auth_instruction_text">ID kaardiga ühenduse loomiseks pane kaart vastu telefoni</string>
|
||||||
|
<string name="time_left">Aega on jäänud %d sek</string>
|
||||||
|
<string name="no_time">Aeg on otsas</string>
|
||||||
|
<string name="no_success">Vale CAN</string>
|
||||||
|
|
||||||
|
<!-- string resources for UserFragment layout -->
|
||||||
|
<string name="user_name_label">NIMI</string>
|
||||||
|
<string name="user_name">%1$s %2$s</string>
|
||||||
|
<string name="identification_number_label">ISIKUKOOD</string>
|
||||||
|
<string name="expiration_label">KEHTIV KUNI</string>
|
||||||
|
<string name="citizenship_label">KODAKONDSUS</string>
|
||||||
|
<string name="gender_label">SUGU</string>
|
||||||
|
<string name="clear_button">UNUSTA</string>
|
||||||
|
|
||||||
|
<!-- menu -->
|
||||||
|
<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="can_add">Lisa CAN</string>
|
||||||
|
<string name="can_delete">Kustuta CAN</string>
|
||||||
|
<string name="saved_pin">PIN1: %s</string>
|
||||||
|
<string name="pin1_add">Lisa PIN1</string>
|
||||||
|
<string name="pin1_delete">Kustuta PIN1</string>
|
||||||
|
<string name="missing">puudub</string>
|
||||||
|
<string name="show">NÄITA</string>
|
||||||
|
<string name="hide">PEIDA</string>
|
||||||
|
<string name="hidden_pin">****</string>
|
||||||
|
<string name="unavailable">Seaded pole hetkel saadaval</string>
|
||||||
|
</resources>
|
66
MobileAuthApp/app/src/main/res/values-et/strings.xml
Normal file
66
MobileAuthApp/app/src/main/res/values-et/strings.xml
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">NFC authentication</string>
|
||||||
|
<string name="home_fragment">Work in progress</string>
|
||||||
|
|
||||||
|
<string name="begin_text">LOE ID KAARTI</string>
|
||||||
|
<string name="next_text">EDASI</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 resources for HomeFragment -->
|
||||||
|
<string name="pin_status_saved">PIN 1 on 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_negative">CAN ei ole salvestatud</string>
|
||||||
|
|
||||||
|
<!-- string resources for PinFragment -->
|
||||||
|
<string name="pin_fragment">Palun sisesta PIN 1</string>
|
||||||
|
<string name="enter_pin">PIN 1</string>
|
||||||
|
<string name="example_pin">Näide. 1234</string>
|
||||||
|
<string name="length_pin">PIN 1 lubatud pikkus on 4..12</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="save_pin_title">Salvesta PIN 1</string>
|
||||||
|
|
||||||
|
<!-- string resources for CanFragment -->
|
||||||
|
<string name="example_can">Näide. 123456</string>
|
||||||
|
<string name="text_can">CAN</string>
|
||||||
|
<string name="enter_can">Sisesta ID kaardi CAN (Card Access Number)</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 name="auth_instruction_text">ID kaardiga ühenduse loomiseks pane kaart vastu telefoni</string>
|
||||||
|
<string name="time_left">Aega on jäänud %d sek</string>
|
||||||
|
<string name="no_time">Aeg on otsas</string>
|
||||||
|
<string name="no_success">Vale CAN</string>
|
||||||
|
|
||||||
|
<!-- string resources for UserFragment layout -->
|
||||||
|
<string name="user_name_label">NIMI</string>
|
||||||
|
<string name="user_name">%1$s %2$s</string>
|
||||||
|
<string name="identification_number_label">ISIKUKOOD</string>
|
||||||
|
<string name="clear_button">UNUSTA</string>
|
||||||
|
<string name="expiration_label">KEHTIV KUNI</string>
|
||||||
|
<string name="citizenship_label">KODAKONDSUS</string>
|
||||||
|
<string name="gender_label">SUGU</string>
|
||||||
|
|
||||||
|
<!-- menu -->
|
||||||
|
<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="can_add">Lisa CAN</string>
|
||||||
|
<string name="can_delete">Kustuta CAN</string>
|
||||||
|
<string name="saved_pin">PIN1: %s</string>
|
||||||
|
<string name="pin1_add">Lisa PIN1</string>
|
||||||
|
<string name="pin1_delete">Kustuta PIN1</string>
|
||||||
|
<string name="missing">puudub</string>
|
||||||
|
<string name="show">NÄITA</string>
|
||||||
|
<string name="hide">PEIDA</string>
|
||||||
|
<string name="hidden_pin">****</string>
|
||||||
|
<string name="unavailable">Seaded pole hetkel saadaval</string>
|
||||||
|
</resources>
|
@ -1,6 +1,6 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="Theme.MobileAuthApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
<style name="Theme.MobileAuthApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||||
<!-- Primary brand color. -->
|
<!-- Primary brand color. -->
|
||||||
<item name="colorPrimary">@color/blue_200</item>
|
<item name="colorPrimary">@color/blue_200</item>
|
||||||
<item name="colorPrimaryVariant">@color/blue_700</item>
|
<item name="colorPrimaryVariant">@color/blue_700</item>
|
||||||
|
@ -13,5 +13,4 @@
|
|||||||
<color name="blue_700">#1976d2</color>
|
<color name="blue_700">#1976d2</color>
|
||||||
<color name="orange_200">#ffcc80</color>
|
<color name="orange_200">#ffcc80</color>
|
||||||
<color name="orange_700">#f57c00</color>
|
<color name="orange_700">#f57c00</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -1,16 +1,27 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Mobile Authenticator</string>
|
<string name="app_name">NFC authentication</string>
|
||||||
<string name="home_fragment">Work in progress</string>
|
<string name="home_fragment">Work in progress</string>
|
||||||
|
|
||||||
<string name="begin_text">ALUSTA</string>
|
<string name="begin_text">LOE ID KAARTI</string>
|
||||||
<string name="next_text">EDASI</string>
|
<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 resources for HomeFragment -->
|
||||||
|
<string name="pin_status_saved">PIN 1 on 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_negative">CAN ei ole salvestatud</string>
|
||||||
|
|
||||||
<!-- string resources for PinFragment -->
|
<!-- string resources for PinFragment -->
|
||||||
<string name="pin_fragment">Palun sisesta PIN 1</string>
|
<string name="pin_fragment">Palun sisesta PIN 1</string>
|
||||||
<string name="enter_pin">PIN 1</string>
|
<string name="enter_pin">PIN 1</string>
|
||||||
<string name="example_pin">Näide. 1234</string>
|
<string name="example_pin">Näide. 1234</string>
|
||||||
<string name="length_pin">PIN 1 lubatud pikkus on 4..12</string>
|
<string name="length_pin">PIN 1 lubatud pikkus on 4..12</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="save_pin_title">Salvesta PIN 1</string>
|
||||||
|
|
||||||
<!-- string resources for CanFragment -->
|
<!-- string resources for CanFragment -->
|
||||||
<string name="example_can">Näide. 123456</string>
|
<string name="example_can">Näide. 123456</string>
|
||||||
@ -19,6 +30,8 @@
|
|||||||
<string name="length_can">CANi pikkus on vale</string>
|
<string name="length_can">CANi pikkus on vale</string>
|
||||||
<string name="card_detected">Kaart on tuvastatud. Hoia kaarti vastu telefoni.</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="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">ID kaardiga ühenduse loomiseks pane kaart vastu telefoni</string>
|
||||||
@ -30,5 +43,24 @@
|
|||||||
<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="expiration_label">KEHTIV KUNI</string>
|
||||||
|
<string name="citizenship_label">KODAKONDSUS</string>
|
||||||
|
<string name="gender_label">SUGU</string>
|
||||||
<string name="clear_button">UNUSTA</string>
|
<string name="clear_button">UNUSTA</string>
|
||||||
|
|
||||||
|
<!-- menu -->
|
||||||
|
<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="can_add">Lisa CAN</string>
|
||||||
|
<string name="can_delete">Kustuta CAN</string>
|
||||||
|
<string name="saved_pin">PIN1: %s</string>
|
||||||
|
<string name="pin1_add">Lisa PIN 1</string>
|
||||||
|
<string name="pin1_delete">Kustuta PIN 1</string>
|
||||||
|
<string name="missing">puudub</string>
|
||||||
|
<string name="show">NÄITA</string>
|
||||||
|
<string name="hide">PEIDA</string>
|
||||||
|
<string name="hidden_pin">****</string>
|
||||||
|
<string name="unavailable">Seaded pole hetkel saadaval</string>
|
||||||
</resources>
|
</resources>
|
@ -1,6 +1,6 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="Theme.MobileAuthApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
<style name="Theme.MobileAuthApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||||
<!-- Primary brand color. -->
|
<!-- Primary brand color. -->
|
||||||
<item name="colorPrimary">@color/blue_500</item>
|
<item name="colorPrimary">@color/blue_500</item>
|
||||||
<item name="colorPrimaryVariant">@color/blue_700</item>
|
<item name="colorPrimaryVariant">@color/blue_700</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user