Merge pull request #9 from TanelOrumaa/iter3UI

Iter3 UI
This commit is contained in:
Henrik Lepson 2021-10-21 20:31:26 +03:00 committed by GitHub
commit 71db5cc9e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 1051 additions and 88 deletions

View File

@ -59,4 +59,7 @@ dependencies {
//For cryptography
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69'
//SecureDataStoring
implementation("androidx.security:security-crypto:1.0.0")
}

View File

@ -78,10 +78,13 @@ class AuthFragment : Fragment() {
card.use {
try {
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.setUserLastName(response[0])
viewModel.setUserIdentificationNumber(response[2])
viewModel.setGender(response[3])
viewModel.setCitizenship(response[4])
viewModel.setExpiration(response[5])
requireActivity().runOnUiThread{
binding!!.timeCounter.text = getString(R.string.data_read)
}
@ -89,6 +92,8 @@ class AuthFragment : Fragment() {
requireActivity().runOnUiThread {
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
Thread.sleep(1000)
goToTheStart()

View File

@ -1,5 +1,6 @@
package com.tarkvaraprojekt.mobileauthapp
import android.app.AlertDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -8,11 +9,14 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentCanBinding
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() {
@ -20,6 +24,12 @@ class CanFragment : Fragment() {
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(
inflater: LayoutInflater,
container: ViewGroup?,
@ -31,28 +41,93 @@ class CanFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding!!.nextButton.setOnClickListener { goToNextFragment() }
checkIfSkip()
// 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() }
}
private fun goToNextFragment() {
val enteredCan = binding!!.canEditText.editText?.text.toString()
if (enteredCan.length != 6) {
Toast.makeText(requireContext(), getString(R.string.length_can), Toast.LENGTH_SHORT)
.show()
} else {
viewModel.setUserCan(
binding!!.canEditText.editText?.text.toString()
)
findNavController().navigate(R.id.action_canFragment_to_authFragment)
/**
* Checks if the current fragment can be skipped or not.
* If the user has CAN saved on the device there is no need to ask it again.
*/
private fun checkIfSkip() {
if (viewModel.userCan.length == 6) {
goToTheNextFragment()
}
}
/**
* 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() {
viewModel.clearUserInfo()
if (args.saving) {
findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
} else {
findNavController().navigate(R.id.action_canFragment_to_homeFragment)
}
}
override fun onDestroy() {
super.onDestroy()

View File

@ -10,6 +10,13 @@ import androidx.navigation.fragment.findNavController
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentHomeBinding
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() {
private val viewModel: SmartCardViewModel by activityViewModels()
@ -22,17 +29,72 @@ class HomeFragment : Fragment() {
savedInstanceState: Bundle?
): View? {
binding = FragmentHomeBinding.inflate(inflater, container, false)
// Making settings menu active again
(activity as MainActivity).menuAvailable = true
return binding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding!!.beginButton.setOnClickListener { goToNextFragment() }
initialChecks()
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() {

View File

@ -1,24 +1,51 @@
package com.tarkvaraprojekt.mobileauthapp
import android.nfc.NfcAdapter
import androidx.appcompat.app.AppCompatActivity
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.fragment.NavHostFragment
import com.tarkvaraprojekt.mobileauthapp.databinding.ActivityMainBinding
/**
* The only activity of the application (single activity design).
*/
class MainActivity : AppCompatActivity() {
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?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
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)
}
}

View File

@ -1,5 +1,6 @@
package com.tarkvaraprojekt.mobileauthapp
import android.app.AlertDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -8,11 +9,14 @@ import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentPinBinding
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() {
@ -20,6 +24,12 @@ class PinFragment : Fragment() {
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(
inflater: LayoutInflater,
container: ViewGroup?,
@ -31,34 +41,95 @@ class PinFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding!!.nextButton.setOnClickListener { goToNextFragment() }
checkIfSkip()
// 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() }
// 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()
if (enteredPin1.length in 4..12) {
viewModel.setUserPin(
binding!!.pinEditText.editText?.text.toString()
)
findNavController().navigate(R.id.action_pinFragment_to_canFragment)
/**
* 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()
}
}
/**
* 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 {
// Currently it is not important to enter PIN1 so we will allow the user to leave this field empty
//Toast.makeText(requireContext(), getString(R.string.length_pin), Toast.LENGTH_SHORT)
// .show()
viewModel.setUserPin("1234")
findNavController().navigate(R.id.action_pinFragment_to_canFragment)
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() {
if (args.saving) {
findNavController().navigate(R.id.action_pinFragment_to_settingsFragment)
} else {
viewModel.clearUserInfo()
findNavController().navigate(R.id.action_pinFragment_to_homeFragment)
}
}
override fun onDestroy() {
super.onDestroy()

View File

@ -33,13 +33,25 @@ class UserFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding!!.userName.text =
getString(R.string.user_name, viewModel.userFirstName, viewModel.userLastName)
binding!!.identificationNumber.text = viewModel.userIdentificationNumber
displayInformation()
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() {
viewModel.clearUserInfo()
findNavController().navigate(R.id.action_userFragment_to_homeFragment)

View File

@ -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
}
}

View File

@ -1,6 +1,10 @@
package com.tarkvaraprojekt.mobileauthapp.model
import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.ViewModel
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
class SmartCardViewModel: ViewModel() {
@ -19,12 +23,24 @@ class SmartCardViewModel: ViewModel() {
private var _userIdentificationNumber: String = ""
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() {
_userPin = ""
_userCan = ""
_userFirstName = ""
_userLastName = ""
_userIdentificationNumber = ""
_expiration = ""
_citizenship = ""
_gender = ""
}
fun setUserPin(newUserPin: String) {
@ -47,4 +63,67 @@ class SmartCardViewModel: ViewModel() {
_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 = ""
}
}

View 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>

View 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="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>

View 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>

View 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>

View 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>

View File

@ -6,12 +6,28 @@
android:layout_height="match_parent"
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
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="0dp"
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>

View File

@ -14,7 +14,10 @@
android:layout_margin="8dp"
app:layout_constraintEnd_toEndOf="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
android:layout_width="match_parent"
@ -59,7 +62,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/next_text"
android:textSize="18sp"
android:textSize="15sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/cancel_button"
app:layout_constraintTop_toBottomOf="@id/card_view" />
@ -70,7 +73,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/cancel_text"
android:textSize="18sp"
android:textSize="15sp"
app:layout_constraintEnd_toStartOf="@id/next_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/card_view" />

View File

@ -14,7 +14,10 @@
android:layout_margin="8dp"
app:layout_constraintEnd_toEndOf="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
android:layout_width="match_parent"
@ -63,7 +66,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/next_text"
android:textSize="18sp"
android:textSize="15sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/cancel_button"
app:layout_constraintTop_toBottomOf="@id/card_view" />
@ -74,7 +77,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/cancel_text"
android:textSize="18dp"
android:textSize="15sp"
app:layout_constraintEnd_toStartOf="@id/next_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/card_view" />

View File

@ -7,23 +7,87 @@
android:padding="24dp"
tools:context=".HomeFragment">
<TextView
android:id="@+id/home_fragment_text"
android:layout_width="wrap_content"
<LinearLayout
android:id="@+id/saved_states"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/home_fragment"
app:layout_constraintTop_toTopOf="parent"
android:orientation="vertical"
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
android:id="@+id/begin_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/begin_text"
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_constraintEnd_toEndOf="parent"/>

View File

@ -14,7 +14,10 @@
android:layout_margin="8dp"
app:layout_constraintEnd_toEndOf="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
android:layout_width="match_parent"
@ -62,6 +65,7 @@
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" />
@ -72,6 +76,7 @@
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_constraintTop_toBottomOf="@id/card_view" />

View 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>

View File

@ -14,7 +14,10 @@
android:layout_margin="8dp"
app:layout_constraintEnd_toEndOf="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
android:layout_width="match_parent"
@ -54,6 +57,54 @@
android:textSize="20sp"
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>
</com.google.android.material.card.MaterialCardView>

View 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>

View File

@ -11,39 +11,69 @@
android:label="fragment_home"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/action_homeFragment_to_pinFragment"
app:destination="@id/pinFragment"
/>
android:id="@+id/action_homeFragment_to_settingsFragment"
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
android:id="@+id/pinFragment"
android:name="com.tarkvaraprojekt.mobileauthapp.PinFragment"
android:label="fragment_pin"
tools:layout="@layout/fragment_pin">
<action
android:id="@+id/action_pinFragment_to_canFragment"
app:destination="@id/canFragment"
app:popUpTo="@id/homeFragment" />
<action
android:id="@+id/action_pinFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:popUpTo="@id/homeFragment"
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
android:id="@+id/canFragment"
android:name="com.tarkvaraprojekt.mobileauthapp.CanFragment"
android:label="fragment_can"
tools:layout="@layout/fragment_can">
<action
android:id="@+id/action_canFragment_to_authFragment"
app:destination="@id/authFragment"
app:popUpTo="@id/homeFragment"/>
<action
android:id="@+id/action_canFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:popUpTo="@id/homeFragment"
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
android:id="@+id/authFragment"
@ -71,4 +101,21 @@
app:popUpTo="@id/homeFragment"
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>
</navigation>

View 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>

View 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>

View File

@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.MobileAuthApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<style name="Theme.MobileAuthApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/blue_200</item>
<item name="colorPrimaryVariant">@color/blue_700</item>

View File

@ -13,5 +13,4 @@
<color name="blue_700">#1976d2</color>
<color name="orange_200">#ffcc80</color>
<color name="orange_700">#f57c00</color>
</resources>

View File

@ -1,16 +1,27 @@
<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="begin_text">ALUSTA</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>
@ -19,6 +30,8 @@
<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>
@ -30,5 +43,24 @@
<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 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>

View File

@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.MobileAuthApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<style name="Theme.MobileAuthApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/blue_500</item>
<item name="colorPrimaryVariant">@color/blue_700</item>