New state mode for biometric unlock

This commit is contained in:
J-Jamet
2019-09-02 12:01:36 +02:00
parent bff87d16b1
commit 5a08fa0088
33 changed files with 310 additions and 1108 deletions

View File

@@ -298,8 +298,16 @@ class PasswordActivity : StylishActivity() {
}
}
advancedUnlockedViewManager?.initBiometric()
// checks if fingerprint is available, will also start listening for fingerprints when available
advancedUnlockedViewManager?.checkBiometricAvailability()
// Add a check listener to change fingerprint mode
checkboxPasswordView?.setOnCheckedChangeListener { compoundButton, checked ->
advancedUnlockedViewManager?.checkBiometricAvailability()
// Add old listener to enable the button, only be call here because of onCheckedChange bug
enableButtonOnCheckedChangeListener?.onCheckedChanged(compoundButton, checked)
}
fingerPrintInit = true
} else {
advancedUnlockedViewManager?.destroy()
@@ -360,7 +368,7 @@ class PasswordActivity : StylishActivity() {
override fun onPause() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
advancedUnlockedViewManager?.stopListening()
advancedUnlockedViewManager?.pause()
}
super.onPause()
}
@@ -429,8 +437,8 @@ class PasswordActivity : StylishActivity() {
// Recheck fingerprint if error
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (PreferencesUtil.isBiometricPromptEnable(this@PasswordActivity)) {
// Stay with the same mode
advancedUnlockedViewManager?.reInitWithFingerprintMode()
// Stay with the same mode and init it
advancedUnlockedViewManager?.initBiometricMode()
}
}

View File

@@ -4,13 +4,11 @@ import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.widget.CompoundButton
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
@@ -30,11 +28,7 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
: BiometricHelper.BiometricUnlockCallback {
private var biometricHelper: BiometricHelper? = null
private var fingerprintMustBeConfigured = true
private var biometricMode: Mode = Mode.NOT_CONFIGURED_MODE
private var checkboxListenerHandler = Handler()
private var checkboxListenerRunnable: Runnable? = null
private var biometricMode: Mode = Mode.NOT_CONFIGURED
// makes it possible to store passwords per database
private val preferenceKeyValue: String
@@ -43,11 +37,7 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
private val preferenceKeyIvSpec: String
get() = PREF_KEY_IV_PREFIX + (databaseFileUri?.path ?: "")
private var prefsNoBackup: SharedPreferences? = null
init {
prefsNoBackup = getNoBackupSharedPreferences(context)
}
private var prefsNoBackup: SharedPreferences = getNoBackupSharedPreferences(context)
// fingerprint related code here
fun initBiometric() {
@@ -56,42 +46,55 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
// and the activity still active)
if (biometricHelper == null || !biometricHelper!!.isFingerprintInitialized) {
biometricMode = Mode.NOT_CONFIGURED_MODE
showFingerPrintViews(true)
// Start the animation
advancedUnlockInfoView?.startIconViewAnimation()
// Add a check listener to change fingerprint mode
checkboxPasswordView?.setOnCheckedChangeListener { compoundButton, checked ->
// New runnable to each change
checkboxListenerHandler.removeCallbacks(checkboxListenerRunnable)
checkboxListenerRunnable = Runnable {
if (!fingerprintMustBeConfigured) {
// encrypt or decrypt mode based on how much input or not
if (checked) {
toggleFingerprintMode(Mode.STORE_MODE)
} else {
if (prefsNoBackup?.contains(preferenceKeyValue) == true) {
toggleFingerprintMode(Mode.OPEN_MODE)
} else {
// This happens when no fingerprints are registered.
toggleFingerprintMode(Mode.WAITING_PASSWORD_MODE)
}
}
}
}
checkboxListenerHandler.post(checkboxListenerRunnable)
// Add old listener to enable the button, only be call here because of onCheckedChange bug
onCheckedPasswordChangeListener?.onCheckedChanged(compoundButton, checked)
}
biometricHelper = BiometricHelper(context, this)
// callback for fingerprint findings
biometricHelper?.setAuthenticationCallback(biometricCallback)
}
checkBiometricAvailability()
}
@Synchronized
fun checkBiometricAvailability() {
// fingerprint not supported (by API level or hardware) so keep option hidden
// or manually disable
val biometricCanAuthenticate = BiometricManager.from(context).canAuthenticate()
val newBiometricMode: Mode = if (!PreferencesUtil.isBiometricPromptEnable(context)
|| biometricCanAuthenticate == BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE
|| biometricCanAuthenticate == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE) {
Mode.UNAVAILABLE
} else {
// fingerprint is available but not configured, show icon but in disabled state with some information
if (biometricCanAuthenticate == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
Mode.NOT_CONFIGURED
} else {
// fingerprint available but no stored password found yet for this DB so show info don't listen
if (prefsNoBackup.contains(preferenceKeyValue)) {
// listen for decryption
Mode.OPEN
} else {
if (checkboxPasswordView?.isChecked == true) {
// listen for encryption
Mode.STORE
} else {
// wait for typing
Mode.WAIT_CREDENTIAL
}
}
}
}
// Toggle mode
if (newBiometricMode != biometricMode) {
biometricMode = newBiometricMode
initBiometricMode()
}
}
private val biometricCallback = object : BiometricPrompt.AuthenticationCallback () {
@@ -103,37 +106,64 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
5 -> Log.i(TAG, "Fingerprint authentication error. Code : $errorCode Error : $errString")
else -> {
Log.e(TAG, "Fingerprint authentication error. Code : $errorCode Error : $errString")
setAdvancedUnlockedView(errString.toString(), true)
setAdvancedUnlockedView(errString.toString())
}
}
}
override fun onAuthenticationFailed() {
Log.e(TAG, "Fingerprint authentication failed, fingerprint not recognized")
showError(R.string.fingerprint_not_recognized)
setAdvancedUnlockedView(R.string.fingerprint_not_recognized)
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
when (biometricMode) {
Mode.STORE_MODE -> {
Mode.UNAVAILABLE -> {}
Mode.NOT_CONFIGURED -> {}
Mode.WAIT_CREDENTIAL -> {}
Mode.STORE -> {
// newly store the entered password in encrypted way
biometricHelper?.encryptData(passwordView?.text.toString())
}
Mode.OPEN_MODE -> {
Mode.OPEN -> {
// retrieve the encrypted value from preferences
prefsNoBackup?.getString(preferenceKeyValue, null)?.let {
prefsNoBackup.getString(preferenceKeyValue, null)?.let {
biometricHelper?.decryptData(it)
}
}
Mode.NOT_CONFIGURED_MODE -> {}
Mode.WAITING_PASSWORD_MODE -> {}
}
}
}
private fun initNotAvailable() {
showFingerPrintViews(false)
advancedUnlockInfoView?.stopIconViewAnimation()
advancedUnlockInfoView?.setIconViewClickListener(null)
}
private fun initNotConfigured() {
showFingerPrintViews(true)
setAdvancedUnlockedView(R.string.configure_biometric)
advancedUnlockInfoView?.stopIconViewAnimation()
advancedUnlockInfoView?.setIconViewClickListener(null)
}
private fun initWaitData() {
showFingerPrintViews(true)
setAdvancedUnlockedView(R.string.no_password_stored)
advancedUnlockInfoView?.startIconViewAnimation()
advancedUnlockInfoView?.setIconViewClickListener(null)
}
private fun initEncryptData() {
setAdvancedUnlockedView(R.string.store_with_fingerprint)
biometricMode = Mode.STORE_MODE
showFingerPrintViews(true)
setAdvancedUnlockedView(R.string.open_biometric_prompt_store_credential)
advancedUnlockInfoView?.startIconViewAnimation()
biometricHelper?.initEncryptData { biometricPrompt, cryptoObject, promptInfo ->
// Set listener to open the biometric dialog and save credential
advancedUnlockInfoView?.setIconViewClickListener { _ ->
@@ -145,10 +175,12 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
}
private fun initDecryptData() {
setAdvancedUnlockedView(R.string.scanning_fingerprint)
biometricMode = Mode.OPEN_MODE
showFingerPrintViews(true)
setAdvancedUnlockedView(R.string.open_biometric_prompt_unlock_database)
advancedUnlockInfoView?.startIconViewAnimation()
if (biometricHelper != null) {
prefsNoBackup?.getString(preferenceKeyIvSpec, null)?.let {
prefsNoBackup.getString(preferenceKeyIvSpec, null)?.let {
biometricHelper?.initDecryptData(it) { biometricPrompt, cryptoObject, promptInfo ->
// Set listener to open the biometric dialog and check credential
advancedUnlockInfoView?.setIconViewClickListener { _ ->
@@ -161,120 +193,58 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
}
}
private fun initWaitData() {
setAdvancedUnlockedView(R.string.no_password_stored, true)
biometricMode = Mode.WAITING_PASSWORD_MODE
}
@Synchronized
private fun toggleFingerprintMode(newMode: Mode) {
when (newMode) {
Mode.WAITING_PASSWORD_MODE -> setAdvancedUnlockedView(R.string.no_password_stored, true)
Mode.STORE_MODE -> setAdvancedUnlockedView(R.string.store_with_fingerprint)
Mode.OPEN_MODE -> setAdvancedUnlockedView(R.string.scanning_fingerprint)
else -> {}
}
if (newMode != biometricMode) {
biometricMode = newMode
reInitWithFingerprintMode()
}
}
@Synchronized
fun reInitWithFingerprintMode() {
fun initBiometricMode() {
when (biometricMode) {
Mode.STORE_MODE -> initEncryptData()
Mode.WAITING_PASSWORD_MODE -> initWaitData()
Mode.OPEN_MODE -> initDecryptData()
else -> {}
Mode.UNAVAILABLE -> initNotAvailable()
Mode.NOT_CONFIGURED -> initNotConfigured()
Mode.WAIT_CREDENTIAL -> initWaitData()
Mode.STORE -> initEncryptData()
Mode.OPEN -> initDecryptData()
}
// Show fingerprint key deletion
context.invalidateOptionsMenu()
}
fun stopListening() {
// stop listening when we go in background
advancedUnlockInfoView?.stopIconViewAnimation()
biometricMode = Mode.NOT_CONFIGURED_MODE
fun pause() {
biometricMode = Mode.NOT_CONFIGURED
initBiometricMode()
}
fun destroy() {
// Restore the checked listener
checkboxPasswordView?.setOnCheckedChangeListener(onCheckedPasswordChangeListener)
stopListening()
biometricMode = Mode.UNAVAILABLE
initBiometricMode()
biometricHelper = null
showFingerPrintViews(false)
}
fun inflateOptionsMenu(menuInflater: MenuInflater, menu: Menu) {
if (!fingerprintMustBeConfigured && prefsNoBackup?.contains(preferenceKeyValue) == true)
menuInflater.inflate(R.menu.fingerprint, menu)
if (biometricMode != Mode.UNAVAILABLE
&& biometricMode != Mode.NOT_CONFIGURED
&& prefsNoBackup.contains(preferenceKeyValue))
menuInflater.inflate(R.menu.advanced_unlock, menu)
}
private fun showFingerPrintViews(show: Boolean) {
context.runOnUiThread { advancedUnlockInfoView?.hide = !show }
}
private fun setAdvancedUnlockedView(textId: Int, lock: Boolean = false) {
private fun setAdvancedUnlockedView(textId: Int) {
context.runOnUiThread {
advancedUnlockInfoView?.setText(textId, lock)
advancedUnlockInfoView?.setText(textId)
}
}
private fun setAdvancedUnlockedView(text: CharSequence, lock: Boolean = false) {
private fun setAdvancedUnlockedView(text: CharSequence) {
context.runOnUiThread {
advancedUnlockInfoView?.setText(text, lock)
advancedUnlockInfoView?.text = text
}
}
@Synchronized
fun checkBiometricAvailability() {
// fingerprint not supported (by API level or hardware) so keep option hidden
// or manually disable
val biometricCanAuthenticate = BiometricManager.from(context).canAuthenticate()
if (!PreferencesUtil.isBiometricPromptEnable(context)
|| biometricCanAuthenticate == BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE
|| biometricCanAuthenticate == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE) {
showFingerPrintViews(false)
} else {
// all is set here so we can confirm to user and start listening for fingerprints
// show explanations
advancedUnlockInfoView?.setOnClickListener { _ ->
FingerPrintExplanationDialog().show(context.supportFragmentManager, "fingerprintDialog")
}
showFingerPrintViews(true)
// fingerprint is available but not configured, show icon but in disabled state with some information
if (biometricCanAuthenticate == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
// This happens when no fingerprints are registered. Listening won't start
setAdvancedUnlockedView(R.string.configure_fingerprint, true)
} else {
fingerprintMustBeConfigured = false
// fingerprint available but no stored password found yet for this DB so show info don't listen
if (prefsNoBackup?.contains(preferenceKeyValue) != true) {
if (checkboxPasswordView?.isChecked == true) {
// listen for encryption
initEncryptData()
} else {
// wait for typing
initWaitData()
}
} else {
// listen for decryption
initDecryptData()
}
}// finally fingerprint available and configured so we can use it
}
// Show fingerprint key deletion
context.invalidateOptionsMenu()
}
private fun removePrefsNoBackupKey() {
prefsNoBackup?.edit()
prefsNoBackup.edit()
?.remove(preferenceKeyValue)
?.remove(preferenceKeyIvSpec)
?.apply()
@@ -283,7 +253,7 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
override fun handleEncryptedResult(
value: String,
ivSpec: String) {
prefsNoBackup?.edit()
prefsNoBackup.edit()
?.putString(preferenceKeyValue, value)
?.putString(preferenceKeyIvSpec, ivSpec)
?.apply()
@@ -297,7 +267,7 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
}
override fun onInvalidKeyException(e: Exception) {
showError(context.getString(R.string.fingerprint_invalid_key))
setAdvancedUnlockedView(R.string.biometric_invalid_key)
deleteEntryKey()
}
@@ -305,28 +275,20 @@ class AdvancedUnlockedViewManager(var context: FragmentActivity,
// Don't show error here;
// showError(getString(R.string.fingerprint_error, e.getMessage()));
// Can be uninit in Activity and init in fragment
setAdvancedUnlockedView(e.localizedMessage, true)
setAdvancedUnlockedView(e.localizedMessage)
}
fun deleteEntryKey() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
biometricHelper?.deleteEntryKey()
removePrefsNoBackupKey()
biometricMode = Mode.NOT_CONFIGURED_MODE
biometricMode = Mode.NOT_CONFIGURED
checkBiometricAvailability()
}
}
private fun showError(messageId: Int) {
showError(context.getString(messageId))
}
private fun showError(message: CharSequence) {
context.runOnUiThread { Toast.makeText(context, message, Toast.LENGTH_SHORT).show() } // TODO Error
}
enum class Mode {
NOT_CONFIGURED_MODE, WAITING_PASSWORD_MODE, STORE_MODE, OPEN_MODE
UNAVAILABLE, NOT_CONFIGURED, WAIT_CREDENTIAL, STORE, OPEN
}
companion object {

View File

@@ -32,13 +32,13 @@ import androidx.annotation.RequiresApi
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
import androidx.fragment.app.FragmentActivity
import com.kunzisoft.keepass.R
import java.io.IOException
import java.security.KeyStore
import java.security.KeyStoreException
import java.security.NoSuchAlgorithmException
import java.security.UnrecoverableKeyException
import java.security.cert.CertificateException
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import javax.crypto.BadPaddingException
import javax.crypto.Cipher
@@ -60,21 +60,16 @@ class BiometricHelper(private val context: FragmentActivity, private val biometr
private var isFingerprintInit = false
private var authenticationCallback: BiometricPrompt.AuthenticationCallback? = null
// TODO promptInfo
private val promptInfoStoreCredential = BiometricPrompt.PromptInfo.Builder()
.setTitle("Set the title to display.")
.setSubtitle("Set the subtitle to display.")
.setDescription("Set the description to display")
.setNegativeButtonText("Negative Button")
.setTitle(context.getString(R.string.biometric_prompt_store_credential_title))
//.setDeviceCredentialAllowed(true)
.setNegativeButtonText(context.getString(android.R.string.cancel))
.build()
private val promptInfoRetrieveCredential = BiometricPrompt.PromptInfo.Builder()
.setTitle("Set the title to display.")
.setSubtitle("Set the subtitle to display.")
.setDescription("Set the description to display")
.setNegativeButtonText("Negative Button")
private val promptInfoExtractCredential = BiometricPrompt.PromptInfo.Builder()
.setTitle(context.getString(R.string.biometric_prompt_extract_credential_title))
//.setDeviceCredentialAllowed(true)
.setNegativeButtonText(context.getString(android.R.string.cancel))
.build()
val isFingerprintInitialized: Boolean
@@ -129,7 +124,7 @@ class BiometricHelper(private val context: FragmentActivity, private val biometr
cipher?.init(Cipher.ENCRYPT_MODE, key)
initBiometricPrompt()
actionIfCypherInit.invoke(biometricPrompt, cryptoObject, promptInfoRetrieveCredential)
actionIfCypherInit.invoke(biometricPrompt, cryptoObject, promptInfoStoreCredential)
} catch (unrecoverableKeyException: UnrecoverableKeyException) {
Log.e(TAG, "Unable to initialize encrypt data", unrecoverableKeyException)
@@ -184,7 +179,7 @@ class BiometricHelper(private val context: FragmentActivity, private val biometr
cipher?.init(Cipher.DECRYPT_MODE, key, spec)
initBiometricPrompt()
actionIfCypherInit.invoke(biometricPrompt, cryptoObject, promptInfoRetrieveCredential)
actionIfCypherInit.invoke(biometricPrompt, cryptoObject, promptInfoExtractCredential)
} catch (unrecoverableKeyException: UnrecoverableKeyException) {
Log.e(TAG, "Unable to initialize decrypt data", unrecoverableKeyException)

View File

@@ -1,344 +0,0 @@
/*
* Copyright 2019 Jeremy Jamet / Kunzisoft.
*
* This file is part of KeePass DX.
*
* KeePass DX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* KeePass DX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.kunzisoft.keepass.fingerprint
import android.annotation.SuppressLint
import android.app.KeyguardManager
import android.content.Context
import android.hardware.fingerprint.FingerprintManager
import android.os.Build
import android.os.CancellationSignal
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyPermanentlyInvalidatedException
import android.security.keystore.KeyProperties
import androidx.annotation.RequiresApi
import android.util.Base64
import android.util.Log
import java.io.IOException
import java.security.KeyStore
import java.security.KeyStoreException
import java.security.NoSuchAlgorithmException
import java.security.UnrecoverableKeyException
import java.security.cert.CertificateException
import javax.crypto.BadPaddingException
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
@RequiresApi(api = Build.VERSION_CODES.M)
class FingerPrintHelper(context: Context, private val fingerPrintCallback: FingerPrintCallback?) {
private val fingerprintManager: FingerprintManager? =
context.getSystemService(FingerprintManager::class.java)
private var keyStore: KeyStore? = null
private var keyGenerator: KeyGenerator? = null
private var cipher: Cipher? = null
private var keyguardManager: KeyguardManager? = null
private var cryptoObject: FingerprintManager.CryptoObject? = null
private var initOk = false
private var cancellationSignal: CancellationSignal? = null
private var authenticationCallback: FingerprintManager.AuthenticationCallback? = null
val isFingerprintInitialized: Boolean
get() = isFingerprintInitialized(true)
fun setAuthenticationCallback(authenticationCallback: FingerprintManager.AuthenticationCallback) {
this.authenticationCallback = authenticationCallback
}
@Synchronized
fun startListening() {
// starts listening for fingerprints with the initialised crypto object
cancellationSignal = CancellationSignal()
fingerprintManager?.authenticate(
cryptoObject,
cancellationSignal,
0 /* flags */,
authenticationCallback!!, null)
}
@Synchronized
fun stopListening() {
if (!isFingerprintInitialized(false)) {
return
}
if (cancellationSignal != null) {
cancellationSignal?.cancel()
cancellationSignal = null
}
}
init {
if (!isFingerprintSupported(fingerprintManager)) {
// really not much to do when no fingerprint support found
initOk = false
} else {
this.keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
if (hasEnrolledFingerprints()) {
try {
this.keyStore = KeyStore.getInstance("AndroidKeyStore")
this.keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore")
this.cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7)
this.cryptoObject = FingerprintManager.CryptoObject(cipher!!)
initOk = true
} catch (e: Exception) {
Log.e(TAG, "Unable to initialize the keystore", e)
initOk = false
fingerPrintCallback?.onFingerPrintException(e)
}
}
}
}
private fun isFingerprintInitialized(throwException: Boolean): Boolean {
val isFingerprintInit = hasEnrolledFingerprints() && initOk
if (!isFingerprintInit && fingerPrintCallback != null) {
if (throwException)
fingerPrintCallback.onFingerPrintException(Exception("FingerPrint not initialized"))
}
return isFingerprintInit
}
fun initEncryptData() {
if (!isFingerprintInitialized) {
return
}
try {
stopListening()
createNewKeyIfNeeded(false) // no need to keep deleting existing keys
keyStore?.load(null)
val key = keyStore?.getKey(FINGERPRINT_KEYSTORE_KEY, null) as SecretKey
cipher?.init(Cipher.ENCRYPT_MODE, key)
startListening()
} catch (unrecoverableKeyException: UnrecoverableKeyException) {
Log.e(TAG, "Unable to initialize encrypt data", unrecoverableKeyException)
deleteEntryKey()
} catch (invalidKeyException: KeyPermanentlyInvalidatedException) {
Log.e(TAG, "Unable to initialize encrypt data", invalidKeyException)
fingerPrintCallback?.onInvalidKeyException(invalidKeyException)
} catch (e: Exception) {
Log.e(TAG, "Unable to initialize encrypt data", e)
fingerPrintCallback?.onFingerPrintException(e)
}
}
fun encryptData(value: String) {
if (!isFingerprintInitialized) {
return
}
try {
// actual do encryption here
val encrypted = cipher?.doFinal(value.toByteArray())
val encryptedValue = Base64.encodeToString(encrypted, Base64.NO_WRAP)
// passes updated iv spec on to callback so this can be stored for decryption
cipher?.parameters?.getParameterSpec(IvParameterSpec::class.java)?.let{ spec ->
val ivSpecValue = Base64.encodeToString(spec.iv, Base64.NO_WRAP)
fingerPrintCallback?.handleEncryptedResult(encryptedValue, ivSpecValue)
}
} catch (e: Exception) {
Log.e(TAG, "Unable to encrypt data", e)
fingerPrintCallback?.onFingerPrintException(e)
}
}
fun initDecryptData(ivSpecValue: String) {
if (!isFingerprintInitialized) {
return
}
try {
stopListening()
createNewKeyIfNeeded(false)
keyStore?.load(null)
val key = keyStore?.getKey(FINGERPRINT_KEYSTORE_KEY, null) as SecretKey
// important to restore spec here that was used for decryption
val iv = Base64.decode(ivSpecValue, Base64.NO_WRAP)
val spec = IvParameterSpec(iv)
cipher?.init(Cipher.DECRYPT_MODE, key, spec)
startListening()
} catch (unrecoverableKeyException: UnrecoverableKeyException) {
Log.e(TAG, "Unable to initialize decrypt data", unrecoverableKeyException)
deleteEntryKey()
} catch (invalidKeyException: KeyPermanentlyInvalidatedException) {
Log.e(TAG, "Unable to initialize decrypt data", invalidKeyException)
fingerPrintCallback?.onInvalidKeyException(invalidKeyException)
} catch (e: Exception) {
Log.e(TAG, "Unable to initialize decrypt data", e)
fingerPrintCallback?.onFingerPrintException(e)
}
}
fun decryptData(encryptedValue: String) {
if (!isFingerprintInitialized) {
return
}
try {
// actual decryption here
val encrypted = Base64.decode(encryptedValue, Base64.NO_WRAP)
cipher?.doFinal(encrypted)?.let { decrypted ->
//final String encryptedString = Base64.encodeToString(encrypted, 0 /* flags */);
fingerPrintCallback?.handleDecryptedResult(String(decrypted))
}
} catch (badPaddingException: BadPaddingException) {
Log.e(TAG, "Unable to decrypt data", badPaddingException)
fingerPrintCallback?.onInvalidKeyException(badPaddingException)
} catch (e: Exception) {
Log.e(TAG, "Unable to decrypt data", e)
fingerPrintCallback?.onFingerPrintException(e)
}
}
@SuppressLint("NewApi")
private fun createNewKeyIfNeeded(allowDeleteExisting: Boolean) {
if (!isFingerprintInitialized) {
return
}
try {
keyStore?.load(null)
if (allowDeleteExisting && keyStore != null && keyStore!!.containsAlias(FINGERPRINT_KEYSTORE_KEY)) {
keyStore?.deleteEntry(FINGERPRINT_KEYSTORE_KEY)
}
// Create new key if needed
if (keyStore != null && !keyStore!!.containsAlias(FINGERPRINT_KEYSTORE_KEY)) {
// Set the alias of the entry in Android KeyStore where the key will appear
// and the constrains (purposes) in the constructor of the Builder
keyGenerator?.init(
KeyGenParameterSpec.Builder(
FINGERPRINT_KEYSTORE_KEY,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
// Require the user to authenticate with a fingerprint to authorize every use
// of the key
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build())
keyGenerator?.generateKey()
}
} catch (e: Exception) {
Log.e(TAG, "Unable to create a key in keystore", e)
fingerPrintCallback?.onFingerPrintException(e)
}
}
fun deleteEntryKey() {
try {
keyStore?.load(null)
keyStore?.deleteEntry(FINGERPRINT_KEYSTORE_KEY)
} catch (e: KeyStoreException) {
Log.e(TAG, "Unable to delete entry key in keystore", e)
fingerPrintCallback?.onFingerPrintException(e)
} catch (e: CertificateException) {
Log.e(TAG, "Unable to delete entry key in keystore", e)
fingerPrintCallback?.onFingerPrintException(e)
} catch (e: NoSuchAlgorithmException) {
Log.e(TAG, "Unable to delete entry key in keystore", e)
fingerPrintCallback?.onFingerPrintException(e)
} catch (e: IOException) {
Log.e(TAG, "Unable to delete entry key in keystore", e)
fingerPrintCallback?.onFingerPrintException(e)
} catch (e: NullPointerException) {
Log.e(TAG, "Unable to delete entry key in keystore", e)
fingerPrintCallback?.onFingerPrintException(e)
}
}
@SuppressLint("NewApi")
fun hasEnrolledFingerprints(): Boolean {
// fingerprint hardware supported and api level OK
return (isFingerprintSupported(fingerprintManager)
// fingerprints enrolled
&& fingerprintManager != null && fingerprintManager.hasEnrolledFingerprints()
// and lockscreen configured
&& keyguardManager != null && keyguardManager!!.isKeyguardSecure)
}
interface FingerPrintErrorCallback {
fun onInvalidKeyException(e: Exception)
fun onFingerPrintException(e: Exception)
}
interface FingerPrintCallback : FingerPrintErrorCallback {
fun handleEncryptedResult(value: String, ivSpec: String)
fun handleDecryptedResult(value: String)
}
enum class Mode {
NOT_CONFIGURED_MODE, WAITING_PASSWORD_MODE, STORE_MODE, OPEN_MODE
}
companion object {
private val TAG = FingerPrintHelper::class.java.name
private const val FINGERPRINT_KEYSTORE_KEY = "com.kunzisoft.keepass.fingerprint.key"
fun isFingerprintSupported(fingerprintManager: FingerprintManager?): Boolean {
return fingerprintManager != null && fingerprintManager.isHardwareDetected
}
/**
* Remove entry key in keystore
*/
fun deleteEntryKeyInKeystoreForFingerprints(context: Context,
fingerPrintCallback: FingerPrintErrorCallback) {
val fingerPrintHelper = FingerPrintHelper( context, object : FingerPrintCallback {
override fun handleEncryptedResult(value: String, ivSpec: String) {}
override fun handleDecryptedResult(value: String) {}
override fun onInvalidKeyException(e: Exception) {
fingerPrintCallback.onInvalidKeyException(e)
}
override fun onFingerPrintException(e: Exception) {
fingerPrintCallback.onFingerPrintException(e)
}
})
fingerPrintHelper.deleteEntryKey()
}
}
}

View File

@@ -1,343 +0,0 @@
package com.kunzisoft.keepass.fingerprint
import android.content.Context
import android.content.SharedPreferences
import android.hardware.fingerprint.FingerprintManager
import android.net.Uri
import android.os.Build
import android.os.Handler
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.widget.CompoundButton
import android.widget.TextView
import android.widget.Toast
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.view.FingerPrintInfoView
@RequiresApi(api = Build.VERSION_CODES.M)
class FingerPrintViewsManager(var context: AppCompatActivity,
var databaseFileUri: Uri?,
var fingerPrintInfoView: FingerPrintInfoView?,
var checkboxPasswordView: CompoundButton?,
var onCheckedPasswordChangeListener: CompoundButton.OnCheckedChangeListener? = null,
var passwordView: TextView?,
var loadDatabase: (password: String?) -> Unit)
: FingerPrintHelper.FingerPrintCallback {
private var fingerPrintHelper: FingerPrintHelper? = null
private var fingerprintMustBeConfigured = true
private var fingerPrintMode: FingerPrintHelper.Mode = FingerPrintHelper.Mode.NOT_CONFIGURED_MODE
private var checkboxListenerHandler = Handler()
private var checkboxListenerRunnable: Runnable? = null
// makes it possible to store passwords per database
private val preferenceKeyValue: String
get() = PREF_KEY_VALUE_PREFIX + (databaseFileUri?.path ?: "")
private val preferenceKeyIvSpec: String
get() = PREF_KEY_IV_PREFIX + (databaseFileUri?.path ?: "")
private var prefsNoBackup: SharedPreferences? = null
init {
prefsNoBackup = getNoBackupSharedPreferences(context)
}
// fingerprint related code here
fun initFingerprint() {
// Check if fingerprint well init (be called the first time the fingerprint is configured
// and the activity still active)
if (fingerPrintHelper == null || !fingerPrintHelper!!.isFingerprintInitialized) {
fingerPrintMode = FingerPrintHelper.Mode.NOT_CONFIGURED_MODE
showFingerPrintViews(true)
// Start the animation
fingerPrintInfoView?.startFingerPrintAnimation()
// Add a check listener to change fingerprint mode
checkboxPasswordView?.setOnCheckedChangeListener { compoundButton, checked ->
// New runnable to each change
checkboxListenerHandler.removeCallbacks(checkboxListenerRunnable)
checkboxListenerRunnable = Runnable {
if (!fingerprintMustBeConfigured) {
// encrypt or decrypt mode based on how much input or not
if (checked) {
toggleFingerprintMode(FingerPrintHelper.Mode.STORE_MODE)
} else {
if (prefsNoBackup?.contains(preferenceKeyValue) == true) {
toggleFingerprintMode(FingerPrintHelper.Mode.OPEN_MODE)
} else {
// This happens when no fingerprints are registered.
toggleFingerprintMode(FingerPrintHelper.Mode.WAITING_PASSWORD_MODE)
}
}
}
}
checkboxListenerHandler.post(checkboxListenerRunnable)
// Add old listener to enable the button, only be call here because of onCheckedChange bug
onCheckedPasswordChangeListener?.onCheckedChanged(compoundButton, checked)
}
fingerPrintHelper = FingerPrintHelper(context, this)
// callback for fingerprint findings
fingerPrintHelper?.setAuthenticationCallback(authenticationCallback)
}
}
private val authenticationCallback = object : FingerprintManager.AuthenticationCallback() {
override fun onAuthenticationError(
errorCode: Int,
errString: CharSequence) {
when (errorCode) {
5 -> Log.i(TAG, "Fingerprint authentication error. Code : $errorCode Error : $errString")
else -> {
Log.e(TAG, "Fingerprint authentication error. Code : $errorCode Error : $errString")
setFingerPrintView(errString.toString(), true)
}
}
}
override fun onAuthenticationHelp(
helpCode: Int,
helpString: CharSequence) {
Log.w(TAG, "Fingerprint authentication help. Code : $helpCode Help : $helpString")
showError(helpString)
setFingerPrintView(helpString.toString(), true)
fingerPrintInfoView?.text = helpString.toString()
}
override fun onAuthenticationFailed() {
Log.e(TAG, "Fingerprint authentication failed, fingerprint not recognized")
showError(R.string.fingerprint_not_recognized)
}
override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult) {
when (fingerPrintMode) {
FingerPrintHelper.Mode.STORE_MODE -> {
// newly store the entered password in encrypted way
fingerPrintHelper?.encryptData(passwordView?.text.toString())
}
FingerPrintHelper.Mode.OPEN_MODE -> {
// retrieve the encrypted value from preferences
prefsNoBackup?.getString(preferenceKeyValue, null)?.let {
fingerPrintHelper?.decryptData(it)
}
}
FingerPrintHelper.Mode.NOT_CONFIGURED_MODE -> {}
FingerPrintHelper.Mode.WAITING_PASSWORD_MODE -> {}
}
}
}
private fun initEncryptData() {
setFingerPrintView(R.string.store_with_fingerprint)
fingerPrintMode = FingerPrintHelper.Mode.STORE_MODE
fingerPrintHelper?.initEncryptData()
}
private fun initDecryptData() {
setFingerPrintView(R.string.scanning_fingerprint)
fingerPrintMode = FingerPrintHelper.Mode.OPEN_MODE
if (fingerPrintHelper != null) {
prefsNoBackup?.getString(preferenceKeyIvSpec, null)?.let {
fingerPrintHelper?.initDecryptData(it)
}
}
}
private fun initWaitData() {
setFingerPrintView(R.string.no_password_stored, true)
fingerPrintMode = FingerPrintHelper.Mode.WAITING_PASSWORD_MODE
}
@Synchronized
private fun toggleFingerprintMode(newMode: FingerPrintHelper.Mode) {
when (newMode) {
FingerPrintHelper.Mode.WAITING_PASSWORD_MODE -> setFingerPrintView(R.string.no_password_stored, true)
FingerPrintHelper.Mode.STORE_MODE -> setFingerPrintView(R.string.store_with_fingerprint)
FingerPrintHelper.Mode.OPEN_MODE -> setFingerPrintView(R.string.scanning_fingerprint)
else -> {}
}
if (newMode != fingerPrintMode) {
fingerPrintMode = newMode
reInitWithFingerprintMode()
}
}
@Synchronized
fun reInitWithFingerprintMode() {
when (fingerPrintMode) {
FingerPrintHelper.Mode.STORE_MODE -> initEncryptData()
FingerPrintHelper.Mode.WAITING_PASSWORD_MODE -> initWaitData()
FingerPrintHelper.Mode.OPEN_MODE -> initDecryptData()
else -> {}
}
// Show fingerprint key deletion
context.invalidateOptionsMenu()
}
fun stopListening() {
// stop listening when we go in background
fingerPrintInfoView?.stopFingerPrintAnimation()
fingerPrintMode = FingerPrintHelper.Mode.NOT_CONFIGURED_MODE
fingerPrintHelper?.stopListening()
}
fun destroy() {
// Restore the checked listener
checkboxPasswordView?.setOnCheckedChangeListener(onCheckedPasswordChangeListener)
stopListening()
fingerPrintHelper = null
showFingerPrintViews(false)
}
fun inflateOptionsMenu(menuInflater: MenuInflater, menu: Menu) {
if (!fingerprintMustBeConfigured && prefsNoBackup?.contains(preferenceKeyValue) == true)
menuInflater.inflate(R.menu.fingerprint, menu)
}
private fun showFingerPrintViews(show: Boolean) {
context.runOnUiThread { fingerPrintInfoView?.hide = !show }
}
private fun setFingerPrintView(textId: Int, lock: Boolean = false) {
context.runOnUiThread {
fingerPrintInfoView?.setText(textId, lock)
}
}
private fun setFingerPrintView(text: CharSequence, lock: Boolean = false) {
context.runOnUiThread {
fingerPrintInfoView?.setText(text, lock)
}
}
@Synchronized
fun checkFingerprintAvailability() {
// fingerprint not supported (by API level or hardware) so keep option hidden
// or manually disable
if (!PreferencesUtil.isFingerprintEnable(context)
|| !FingerPrintHelper.isFingerprintSupported(context.getSystemService(FingerprintManager::class.java))) {
showFingerPrintViews(false)
} else {
// all is set here so we can confirm to user and start listening for fingerprints
// show explanations
fingerPrintInfoView?.setOnClickListener { _ ->
FingerPrintExplanationDialog().show(context.supportFragmentManager, "fingerprintDialog")
}
showFingerPrintViews(true)
// fingerprint is available but not configured, show icon but in disabled state with some information
if (fingerPrintHelper?.hasEnrolledFingerprints() != true) {
// This happens when no fingerprints are registered. Listening won't start
setFingerPrintView(R.string.configure_fingerprint, true)
} else {
fingerprintMustBeConfigured = false
// fingerprint available but no stored password found yet for this DB so show info don't listen
if (prefsNoBackup?.contains(preferenceKeyValue) != true) {
if (checkboxPasswordView?.isChecked == true) {
// listen for encryption
initEncryptData()
} else {
// wait for typing
initWaitData()
}
} else {
// listen for decryption
initDecryptData()
}
}// finally fingerprint available and configured so we can use it
}
// Show fingerprint key deletion
context.invalidateOptionsMenu()
}
private fun removePrefsNoBackupKey() {
prefsNoBackup?.edit()
?.remove(preferenceKeyValue)
?.remove(preferenceKeyIvSpec)
?.apply()
}
override fun handleEncryptedResult(
value: String,
ivSpec: String) {
prefsNoBackup?.edit()
?.putString(preferenceKeyValue, value)
?.putString(preferenceKeyIvSpec, ivSpec)
?.apply()
loadDatabase.invoke(null)
setFingerPrintView(R.string.encrypted_value_stored)
}
override fun handleDecryptedResult(value: String) {
// Load database directly with password retrieve
loadDatabase.invoke(value)
}
override fun onInvalidKeyException(e: Exception) {
showError(context.getString(R.string.fingerprint_invalid_key))
deleteEntryKey()
}
override fun onFingerPrintException(e: Exception) {
// Don't show error here;
// showError(getString(R.string.fingerprint_error, e.getMessage()));
// Can be uninit in Activity and init in fragment
setFingerPrintView(e.localizedMessage, true)
}
fun deleteEntryKey() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
fingerPrintHelper?.deleteEntryKey()
removePrefsNoBackupKey()
fingerPrintMode = FingerPrintHelper.Mode.NOT_CONFIGURED_MODE
checkFingerprintAvailability()
}
}
private fun showError(messageId: Int) {
showError(context.getString(messageId))
}
private fun showError(message: CharSequence) {
context.runOnUiThread { Toast.makeText(context, message, Toast.LENGTH_SHORT).show() } // TODO Error
}
companion object {
private val TAG = FingerPrintViewsManager::class.java.name
private const val PREF_KEY_VALUE_PREFIX = "valueFor_" // key is a combination of db file name and this prefix
private const val PREF_KEY_IV_PREFIX = "ivFor_" // key is a combination of db file name and this prefix
private const val NO_BACKUP_PREFERENCE_FILE_NAME = "nobackup"
fun getNoBackupSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences(
NO_BACKUP_PREFERENCE_FILE_NAME,
Context.MODE_PRIVATE)
}
fun deleteAllValuesFromNoBackupPreferences(context: Context) {
val prefsNoBackup = getNoBackupSharedPreferences(context)
val sharedPreferencesEditor = prefsNoBackup.edit()
sharedPreferencesEditor.clear()
sharedPreferencesEditor.apply()
}
}
}

View File

@@ -152,14 +152,14 @@ class NestedSettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferen
}
}
val deleteKeysFingerprints = findPreference(getString(R.string.fingerprint_delete_all_key))
val deleteKeysFingerprints = findPreference(getString(R.string.biometric_delete_all_key_key))
if (!biometricUnlockSupported) {
deleteKeysFingerprints.isEnabled = false
} else {
deleteKeysFingerprints.setOnPreferenceClickListener {
context?.let { context ->
AlertDialog.Builder(context)
.setMessage(resources.getString(R.string.fingerprint_delete_all_warning))
.setMessage(resources.getString(R.string.biometric_delete_all_key_warning))
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(resources.getString(android.R.string.yes)
) { _, _ ->
@@ -171,7 +171,7 @@ class NestedSettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferen
override fun onBiometricException(e: Exception) {
Toast.makeText(context,
getString(R.string.fingerprint_error, e.localizedMessage),
getString(R.string.biometric_scanning_error, e.localizedMessage),
Toast.LENGTH_SHORT).show()
}
})

View File

@@ -8,6 +8,7 @@ import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.StringRes
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.fingerprint.FingerPrintAnimatedVector
@@ -48,8 +49,9 @@ class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context,
}
}
fun setIconViewClickListener(listener: (view: View)->Unit) {
fun setIconViewClickListener(listener: ((view: View)->Unit)?) {
unlockIconImageView?.setOnClickListener(listener)
unlockContainerView.alpha = if (listener == null) 0.8f else 1f
}
var text: CharSequence
@@ -60,13 +62,8 @@ class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context,
unlockTextView?.text = value
}
fun setText(textId: Int, lock: Boolean = false) {
setText(context.getString(textId), lock)
}
fun setText(text: CharSequence, lock: Boolean = false) {
unlockContainerView.alpha = if (lock) 0.8f else 1f
unlockTextView?.text = text
fun setText(@StringRes textId: Int) {
text = context.getString(textId)
}
var hide: Boolean

View File

@@ -1,76 +0,0 @@
package com.kunzisoft.keepass.view
import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.fingerprint.FingerPrintAnimatedVector
class FingerPrintInfoView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0)
: LinearLayout(context, attrs, defStyle) {
private val fingerPrintContainerView: View
private var fingerPrintAnimatedVector: FingerPrintAnimatedVector? = null
private var fingerPrintTextView: TextView? = null
var fingerPrintImageView: ImageView? = null
init {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
inflater.inflate(R.layout.fingerprint_show, this)
fingerPrintContainerView = findViewById(R.id.fingerprint_container)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
fingerPrintTextView = findViewById(R.id.fingerprint_label)
fingerPrintImageView = findViewById(R.id.fingerprint_image)
// Init the fingerprint animation
fingerPrintAnimatedVector = FingerPrintAnimatedVector(context, fingerPrintImageView!!)
}
}
fun startFingerPrintAnimation() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
fingerPrintAnimatedVector?.startScan()
}
}
fun stopFingerPrintAnimation() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
fingerPrintAnimatedVector?.stopScan()
}
}
var text: CharSequence
get() {
return fingerPrintTextView?.text?.toString() ?: ""
}
set(value) {
fingerPrintTextView?.text = value
}
fun setText(textId: Int, lock: Boolean = false) {
setText(context.getString(textId), lock)
}
fun setText(text: CharSequence, lock: Boolean = false) {
fingerPrintContainerView.alpha = if (lock) 0.8f else 1f
fingerPrintTextView?.text = text
}
var hide: Boolean
get() {
return visibility != VISIBLE
}
set(value) {
visibility = if (value) View.GONE else View.VISIBLE
}
}

View File

@@ -10,6 +10,17 @@
android:layout_height="1dp"
android:background="?attr/colorPrimaryDark"/>
<TextView
android:id="@+id/fingerprint_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:layout_marginEnd="18dp"
android:layout_toStartOf="@+id/fingerprint_image"
style="@style/KeepassDXStyle.TextAppearance.Default.TextOnPrimary"
android:gravity="center_vertical|start" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/fingerprint_image"
android:layout_width="48dp"
@@ -23,15 +34,4 @@
android:src="@drawable/fingerprint"
android:background="@drawable/circle"
android:backgroundTint="?attr/colorAccent" />
<TextView
android:id="@+id/fingerprint_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="24dp"
android:layout_marginEnd="18dp"
android:layout_toStartOf="@+id/fingerprint_image"
style="@style/KeepassDXStyle.TextAppearance.Default.TextOnPrimary"
android:gravity="center_vertical|start" />
</RelativeLayout>

View File

@@ -58,6 +58,7 @@
android:layout_height="wrap_content"
android:minHeight="48dp"
android:layout_gravity="end"
android:gravity="center_vertical|end"
style="@style/KeepassDXStyle.TextAppearance.Small"
android:textColor="?android:attr/textColorHintInverse"
android:paddingHorizontal="8dp"

View File

@@ -21,7 +21,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_fingerprint_remove_key"
android:icon="@drawable/ic_remove_circle_white_24dp"
android:title="@string/menu_fingerprint_remove_key"
android:title="@string/menu_biometric_remove_key"
android:orderInCategory="93"
app:showAsAction="ifRoom" />
</menu>

View File

@@ -80,7 +80,7 @@
<string name="menu_lock">قفل قاعدة البيانات</string>
<string name="menu_open">فتح</string>
<string name="menu_search">البحث</string>
<string name="menu_fingerprint_remove_key">إزالة بصمة المفتاح</string>
<string name="menu_biometric_remove_key">إزالة بصمة المفتاح</string>
<string name="minus">ناقص</string>
<string name="never">أبداً</string>
<string name="no_results">لا توجد نتائج للبحث</string>
@@ -201,7 +201,7 @@
<string name="lock_database_screen_off_summary">اقفل قاعدة البيانات عند انغلاق الشاشة</string>
<string name="fingerprint_type_password_text">ادخل كلمة سر قاعدة البيانات</string>
<string name="usage">استخدام</string>
<string name="fingerprint_delete_all_title">حذف مفاتيح التشفير</string>
<string name="biometric_delete_all_key_title">حذف مفاتيح التشفير</string>
<string name="unavailable_feature_text">لا يمكن بدأ هذه الميزة .</string>
<string name="unavailable_feature_version">نسخة الاندرويد %1$s لا تحقق ادنى متطلبات السنخة %2$s.</string>
<string name="file_name">اسم الملف</string>
@@ -209,12 +209,12 @@
<string name="bytes">بايت</string>
<string name="full_file_path_enable_title">مسار الملف</string>
<string name="full_file_path_enable_summary">عرض المسار الكامل للملف</string>
<string name="configure_fingerprint">فحص البصمة مدعوم لكنه ليس معد.</string>
<string name="scanning_fingerprint">فحص البصمة</string>
<string name="fingerprint_invalid_key">لا يمكن قراءة مفتاح البصمة.
<string name="configure_biometric">فحص البصمة مدعوم لكنه ليس معد.</string>
<string name="open_biometric_prompt_unlock_database">فحص البصمة</string>
<string name="biometric_invalid_key">لا يمكن قراءة مفتاح البصمة.
\nاستعد كلمة السر.</string>
<string name="fingerprint_not_recognized">لم يتعرّف على البصمة</string>
<string name="store_with_fingerprint">استخدم البصمة لحفظ كلمة السر</string>
<string name="open_biometric_prompt_store_credential">استخدم البصمة لحفظ كلمة السر</string>
<string name="history">تأريخ</string>
<string name="clipboard_notifications_summary">مكن اشعارات الحافظة لنسخ الحقول</string>
<string name="fingerprint_quick_unlock_title">كيف أعد فحص البصمة للفتح السريع \?</string>

View File

@@ -193,7 +193,7 @@
<string name="menu_move">Přesunout</string>
<string name="menu_paste">Vložit</string>
<string name="menu_cancel">Storno</string>
<string name="menu_fingerprint_remove_key">Odebrat otisk prstu</string>
<string name="menu_biometric_remove_key">Odebrat otisk prstu</string>
<string name="menu_file_selection_read_only">Pouze pro čtení</string>
<string name="menu_open_file_read_and_write">Čtení a zápis</string>
<string name="read_only">Pouze pro čtení</string>
@@ -216,13 +216,13 @@
<string name="warning_password_encoding">Nepoužívejte v hesle pro .kdb soubory znaky nepodporované znakovou sadou Latin-1 (nepoužívejte znaky s diakritikou).</string>
<string name="warning_empty_password">Opravdu chcete ponechat databázi nechráněnou (bez hesla)?</string>
<string name="warning_no_encryption_key">Opravdu nechcete používat šifrovací klíč?</string>
<string name="configure_fingerprint">Otisk prstu je zařízením podporován, ale není nastavený.</string>
<string name="scanning_fingerprint">Snímání otisku prstu</string>
<string name="configure_biometric">Otisk prstu je zařízením podporován, ale není nastavený.</string>
<string name="open_biometric_prompt_unlock_database">Snímání otisku prstu</string>
<string name="encrypted_value_stored">Šifrované heslo uloženo</string>
<string name="fingerprint_invalid_key">Problém s neplatným otiskem prstu. Obnovte své heslo.</string>
<string name="biometric_invalid_key">Problém s neplatným otiskem prstu. Obnovte své heslo.</string>
<string name="fingerprint_not_recognized">Otisk prstu není rozpoznán</string>
<string name="fingerprint_error">Problém s otiskem prstu: %1$s</string>
<string name="store_with_fingerprint">Použít pro uložení tohoto hesla otisk prstu</string>
<string name="biometric_scanning_error">Problém s otiskem prstu: %1$s</string>
<string name="open_biometric_prompt_store_credential">Použít pro uložení tohoto hesla otisk prstu</string>
<string name="no_password_stored">Tato databáze zatím není chráněna heslem.</string>
<string name="history">Historie</string>
<string name="appearance">Vzhled</string>
@@ -253,9 +253,9 @@
<string name="fingerprint">Otisk</string>
<string name="biometric_unlock_enable_title">Snímání otisku prstu</string>
<string name="biometric_unlock_enable_summary">Otevírat databázi otiskem prstu</string>
<string name="fingerprint_delete_all_title">Smazat šifrovací klíče</string>
<string name="fingerprint_delete_all_summary">Smazat všechny šifrovací klíče související s rozpoznáváním otisku prstu</string>
<string name="fingerprint_delete_all_warning">Opravdu chcete smazat všechny klíče přiřazené k otiskům prstů\?</string>
<string name="biometric_delete_all_key_title">Smazat šifrovací klíče</string>
<string name="biometric_delete_all_key_summary">Smazat všechny šifrovací klíče související s rozpoznáváním otisku prstu</string>
<string name="biometric_delete_all_key_warning">Opravdu chcete smazat všechny klíče přiřazené k otiskům prstů\?</string>
<string name="unavailable_feature_text">Toto funkci se nedaří spustit.</string>
<string name="unavailable_feature_version">Verze %1$s vámi používaného systému Android je starší, než minimální požadovaná %2$s.</string>
<string name="unavailable_feature_hardware">Hardware nebyl rozpoznán.</string>

View File

@@ -189,7 +189,7 @@
<string name="menu_move">Flyt</string>
<string name="menu_paste">Indsæt</string>
<string name="menu_cancel">Annuller</string>
<string name="menu_fingerprint_remove_key">Slet gemt fingeraftryk</string>
<string name="menu_biometric_remove_key">Slet gemt fingeraftryk</string>
<string name="menu_file_selection_read_only">Skrivebeskyttet</string>
<string name="menu_open_file_read_and_write">Modificerbar</string>
<string name="read_only">Skrivebeskyttet</string>
@@ -212,13 +212,13 @@
<string name="warning_password_encoding">Undgå adgangskodetegn uden for tekstkodningsformatet i databasefilen (ukendte tegn konverteres til samme bogstav).</string>
<string name="warning_empty_password">Bekræft brug af ingen adgangskode til beskyttelse mod oplåsning\?</string>
<string name="warning_no_encryption_key">Bekræft ingen brug af en krypteringsnøgle?</string>
<string name="configure_fingerprint">Fingeraftryksscanning understøttes, men er ikke sat op.</string>
<string name="scanning_fingerprint">Fingeraftryks-scanning</string>
<string name="configure_biometric">Fingeraftryksscanning understøttes, men er ikke sat op.</string>
<string name="open_biometric_prompt_unlock_database">Fingeraftryks-scanning</string>
<string name="encrypted_value_stored">Krypteret adgangskode er gemt</string>
<string name="fingerprint_invalid_key">Kunne ikke læse fingeraftryksnøgle. Gendan adgangskode.</string>
<string name="biometric_invalid_key">Kunne ikke læse fingeraftryksnøgle. Gendan adgangskode.</string>
<string name="fingerprint_not_recognized">Kunne ikke genkende fingeraftryk</string>
<string name="fingerprint_error">Problem med fingeraftryk: %1$s</string>
<string name="store_with_fingerprint">Brug fingeraftryk til at gemme adgangskoden</string>
<string name="biometric_scanning_error">Problem med fingeraftryk: %1$s</string>
<string name="open_biometric_prompt_store_credential">Brug fingeraftryk til at gemme adgangskoden</string>
<string name="no_password_stored">Databasen har endnu ikke en adgangskode.</string>
<string name="history">Historik</string>
<string name="appearance">Udseende</string>
@@ -249,9 +249,9 @@
<string name="fingerprint">Fingeraftryk</string>
<string name="biometric_unlock_enable_title">Fingeraftryksscanning</string>
<string name="biometric_unlock_enable_summary">Scan fingeraftryk for at åbne databasen</string>
<string name="fingerprint_delete_all_title">Slet krypteringsnøgler</string>
<string name="fingerprint_delete_all_summary">Slet alle krypteringsnøgler, der er relateret til fingeraftryk</string>
<string name="fingerprint_delete_all_warning">Bekræft sletning af alle nøgler, der er relateret til fingeraftryksgenkendelse\?</string>
<string name="biometric_delete_all_key_title">Slet krypteringsnøgler</string>
<string name="biometric_delete_all_key_summary">Slet alle krypteringsnøgler, der er relateret til fingeraftryk</string>
<string name="biometric_delete_all_key_warning">Bekræft sletning af alle nøgler, der er relateret til fingeraftryksgenkendelse\?</string>
<string name="unavailable_feature_text">Funktionen kunne ikke startes.</string>
<string name="unavailable_feature_version">Android-version %1$s opfylder ikke minimum versionskrav %2$s.</string>
<string name="unavailable_feature_hardware">Kunne ikke finde den tilsvarende hardware.</string>

View File

@@ -201,18 +201,18 @@
<string name="lock">Sperre</string>
<string name="list_password_generator_options_summary">Erlaubte Zeichen für Passwortgenerator festlegen</string>
<string name="list_password_generator_options_title">Passwortzeichen</string>
<string name="configure_fingerprint">Fingerabdruck-Scannen wird unterstützt, ist jedoch nicht konfiguriert.</string>
<string name="scanning_fingerprint">Fingerabdruck wird gescannt</string>
<string name="configure_biometric">Fingerabdruck-Scannen wird unterstützt, ist jedoch nicht konfiguriert.</string>
<string name="open_biometric_prompt_unlock_database">Fingerabdruck wird gescannt</string>
<string name="encrypted_value_stored">Verschlüsseltes Passwort wurde gespeichert</string>
<string name="fingerprint_invalid_key">Fingerabdruckschlüssel nicht lesbar. Bitte das Passwort wiederherstellen.</string>
<string name="fingerprint_error">Problem mit dem Fingerabdruck: %1$s</string>
<string name="biometric_invalid_key">Fingerabdruckschlüssel nicht lesbar. Bitte das Passwort wiederherstellen.</string>
<string name="biometric_scanning_error">Problem mit dem Fingerabdruck: %1$s</string>
<string name="history">Verlauf</string>
<string name="fingerprint_quick_unlock_title">Wie richte ich den Fingerabdruckscanner für schnelles Entsperren ein?</string>
<string name="fingerprint_setting_text">Eingelesenen Fingerabdruck für das Gerät speichern in</string>
<string name="fingerprint_setting_way_text">„Einstellungen“ → „Sicherheit“ → „Fingerabdruck“</string>
<string name="usage">Verwendung</string>
<string name="general">Allgemein</string>
<string name="store_with_fingerprint">Fingerabdruck verwenden, um dieses Passwort zu speichern</string>
<string name="open_biometric_prompt_store_credential">Fingerabdruck verwenden, um dieses Passwort zu speichern</string>
<string name="no_password_stored">Diese Datenbank hat noch kein Passwort.</string>
<string name="style_choose_summary">App-Design, das in der App genutzt wird</string>
<string name="encryption">Verschlüsselung</string>
@@ -223,7 +223,7 @@
<string name="error_autofill_enable_service">Autofill-Dienst kann nicht aktiviert werden.</string>
<string name="copy_field">Kopie von %1$s</string>
<string name="menu_form_filling_settings">Formularausfüllung</string>
<string name="menu_fingerprint_remove_key">Gespeicherten Fingerabdruck löschen</string>
<string name="menu_biometric_remove_key">Gespeicherten Fingerabdruck löschen</string>
<string name="encryption_explanation">Verschlüsselungsalgorithmus der Datenbank wird für sämtliche Daten verwendet.</string>
<string name="kdf_explanation">Um den Schlüssel für den Verschlüsselungsalgorithmus zu generieren, wird der Hauptschlüssel umgewandelt, wobei ein zufälliger Salt in der Schlüsselberechnung verwendet wird.</string>
<string name="memory_usage">Speichernutzung</string>
@@ -246,9 +246,9 @@
<string name="set_autofill_service_title">Standard Autofill-Dienst auswählen</string>
<string name="set_autofill_service_summary">Autofill aktivieren, um automatisch Eingabefelder in anderen Apps auszufüllen</string>
<string name="clipboard">Zwischenablage</string>
<string name="fingerprint_delete_all_title">Verschlüsselungsschlüssel löschen</string>
<string name="fingerprint_delete_all_summary">Alle Verschlüsselungsschlüssel für Fingerabdruckerkennung löschen</string>
<string name="fingerprint_delete_all_warning">Sollen wirklich alle mit der Fingerabdruckerkennung verknüpften Schlüssel gelöscht werden\?</string>
<string name="biometric_delete_all_key_title">Verschlüsselungsschlüssel löschen</string>
<string name="biometric_delete_all_key_summary">Alle Verschlüsselungsschlüssel für Fingerabdruckerkennung löschen</string>
<string name="biometric_delete_all_key_warning">Sollen wirklich alle mit der Fingerabdruckerkennung verknüpften Schlüssel gelöscht werden\?</string>
<string name="unavailable_feature_version">Die Android-Version, %1$s, erfüllt nicht die Mindestanforderung für Version %2$s.</string>
<string name="unavailable_feature_hardware">Keine entsprechende Hardware.</string>
<string name="bytes">Bytes</string>

View File

@@ -172,7 +172,7 @@ Spanish translation by José I. Paños. Updated by David García-Abad (23-09-201
<string name="keyfile_is_empty">El archivo clave está vacío.</string>
<string name="copy_field">Copia de %1$s</string>
<string name="menu_form_filling_settings">Llenado de formulario</string>
<string name="menu_fingerprint_remove_key">Quite la clave de huella dactilar</string>
<string name="menu_biometric_remove_key">Quite la clave de huella dactilar</string>
<string name="protection">Protección</string>
<string name="read_only">Solo lectura</string>
<string name="read_only_warning">KeePass DX no tiene permiso de escritura en la ubicación de la base de datos, la base de datos se abrirá como solo lectura.</string>
@@ -198,13 +198,13 @@ Spanish translation by José I. Paños. Updated by David García-Abad (23-09-201
<string name="warning_password_encoding">El formato .kdb solo admite el juego de caracteres Latin1. Su contraseña puede contener caracteres fuera de este juego de caracteres. Todos los caracteres no-Latin1 se convierten al mismo carácter, lo que reduce la seguridad de su contraseña. Se recomienda cambiar su contraseña.</string>
<string name="warning_empty_password">¿De verdad quieres usar una cadena vacía como contraseña?</string>
<string name="warning_no_encryption_key">¿Estás seguro que no quieres usar clave de cifrado?</string>
<string name="configure_fingerprint">Huella digital compatible pero no configurada para el dispositivo</string>
<string name="scanning_fingerprint">Monitoreando huellas digitales</string>
<string name="configure_biometric">Huella digital compatible pero no configurada para el dispositivo</string>
<string name="open_biometric_prompt_unlock_database">Monitoreando huellas digitales</string>
<string name="encrypted_value_stored">Contraseña encriptada almacenada</string>
<string name="fingerprint_invalid_key">Problema clave de huella digital no válida. Restaure su contraseña.</string>
<string name="biometric_invalid_key">Problema clave de huella digital no válida. Restaure su contraseña.</string>
<string name="fingerprint_not_recognized">Huella digital no reconocida</string>
<string name="fingerprint_error">Problema de huella digital: %1$s</string>
<string name="store_with_fingerprint">Usa la huella digital para almacenar esta contraseña</string>
<string name="biometric_scanning_error">Problema de huella digital: %1$s</string>
<string name="open_biometric_prompt_store_credential">Usa la huella digital para almacenar esta contraseña</string>
<string name="no_password_stored">Aún sin contraseña almacenada para esta base de datos</string>
<string name="history">Historial</string>
<string name="appearance">Apariencia</string>
@@ -234,9 +234,9 @@ Spanish translation by José I. Paños. Updated by David García-Abad (23-09-201
<string name="fingerprint">Huella digital</string>
<string name="biometric_unlock_enable_title">Monitoreando Huella digital</string>
<string name="biometric_unlock_enable_summary">Habilitar la apertura de base de datos por huella digital</string>
<string name="fingerprint_delete_all_title">Eliminar claves de cifrado</string>
<string name="fingerprint_delete_all_summary">Eliminar todas las claves de cifrado relacionadas con el reconocimiento de huellas digitales</string>
<string name="fingerprint_delete_all_warning">¿Está seguro de que desea borrar todas las claves relacionadas con las huellas digitales?</string>
<string name="biometric_delete_all_key_title">Eliminar claves de cifrado</string>
<string name="biometric_delete_all_key_summary">Eliminar todas las claves de cifrado relacionadas con el reconocimiento de huellas digitales</string>
<string name="biometric_delete_all_key_warning">¿Está seguro de que desea borrar todas las claves relacionadas con las huellas digitales?</string>
<string name="unavailable_feature_text">No se puede iniciar esta característica.</string>
<string name="unavailable_feature_version">Su versión de Android %1$s no es la versión mínima, se requiere %2$s.</string>
<string name="unavailable_feature_hardware">El hardware no es detectado.</string>

View File

@@ -121,7 +121,7 @@
<string name="menu_open">Ouvrir</string>
<string name="menu_search">Rechercher</string>
<string name="menu_showpass">Afficher le mot de passe</string>
<string name="menu_fingerprint_remove_key">Supprimer lempreinte digitale enregistrée</string>
<string name="menu_biometric_remove_key">Supprimer lempreinte digitale enregistrée</string>
<string name="menu_url">Ouvrir lURL</string>
<string name="minus">Moins</string>
<string name="never">Jamais</string>
@@ -178,13 +178,13 @@
<string name="warning_empty_password">Ne voulez-vous vraiment aucune protection de déverrouillage par mot de passe\?</string>
<string name="warning_no_encryption_key">Êtes-vous sûr de ne vouloir utiliser aucune clé de chiffrement\?</string>
<string name="version_label">Version %1$s</string>
<string name="configure_fingerprint">La reconnaissance dempreinte digitale est prise en charge mais pas configurée.</string>
<string name="scanning_fingerprint">Reconnaissance dempreinte digitale</string>
<string name="configure_biometric">La reconnaissance dempreinte digitale est prise en charge mais pas configurée.</string>
<string name="open_biometric_prompt_unlock_database">Reconnaissance dempreinte digitale</string>
<string name="encrypted_value_stored">Mot de passe chiffré stocké</string>
<string name="fingerprint_invalid_key">Impossible de lire la clé de lempreinte digitale. Restaurer votre mot de passe.</string>
<string name="biometric_invalid_key">Impossible de lire la clé de lempreinte digitale. Restaurer votre mot de passe.</string>
<string name="fingerprint_not_recognized">Impossible de reconnaître lempreinte digitale</string>
<string name="fingerprint_error">Problème dempreinte digitale : %1$s</string>
<string name="store_with_fingerprint">Utiliser lempreinte digitale pour stocker ce mot de passe</string>
<string name="biometric_scanning_error">Problème dempreinte digitale : %1$s</string>
<string name="open_biometric_prompt_store_credential">Utiliser lempreinte digitale pour stocker ce mot de passe</string>
<string name="no_password_stored">Cette base de données na pas encore de mot de passe.</string>
<string name="history">Historique</string>
<string name="appearance">Apparence</string>
@@ -215,9 +215,9 @@
<string name="fingerprint">Empreinte digitale</string>
<string name="biometric_unlock_enable_title">Reconnaissance dempreinte digitale</string>
<string name="biometric_unlock_enable_summary">Vous permet de numériser votre empreinte digitale pour ouvrir la base de données</string>
<string name="fingerprint_delete_all_title">Supprimer les clés de chiffrement</string>
<string name="fingerprint_delete_all_summary">Supprimer toutes les clés de chiffrement liées à la reconnaissance dempreinte digitale</string>
<string name="fingerprint_delete_all_warning">Êtes-vous sûr de vouloir supprimer toutes les clés liées à la reconnaissance dempreinte digitale\?</string>
<string name="biometric_delete_all_key_title">Supprimer les clés de chiffrement</string>
<string name="biometric_delete_all_key_summary">Supprimer toutes les clés de chiffrement liées à la reconnaissance dempreinte digitale</string>
<string name="biometric_delete_all_key_warning">Êtes-vous sûr de vouloir supprimer toutes les clés liées à la reconnaissance dempreinte digitale\?</string>
<string name="unavailable_feature_text">Impossible de démarrer cette fonctionnalité.</string>
<string name="unavailable_feature_version">Votre version Android %1$s est inférieure à la version minimale %2$s requise.</string>
<string name="unavailable_feature_hardware">Impossible de trouver le matériel correspondant.</string>

View File

@@ -149,12 +149,12 @@
<string name="warning_password_encoding">Kerülje a Latin-1 karakterkészlettől eltérő jelszókaraktereket a .kbd fájlokban, mert ugyanarra a betűre lesznek átalakítva.</string>
<string name="warning_unmounted">Csatolja az SD kártyát, hogy adatbázist hozzon létre vagy töltsön be.</string>
<string name="version_label">Verzió: %1$s</string>
<string name="configure_fingerprint">Az ujjlenyomat-leolvasás támogatott, de nincs beállítva.</string>
<string name="scanning_fingerprint">Ujjlenyomat-leolvasás</string>
<string name="configure_biometric">Az ujjlenyomat-leolvasás támogatott, de nincs beállítva.</string>
<string name="open_biometric_prompt_unlock_database">Ujjlenyomat-leolvasás</string>
<string name="encrypted_value_stored">Titkosított jelszó tárolva</string>
<string name="fingerprint_invalid_key">Az ujjlenyomat kulcs nem olvasható. Állítsa vissza a jelszavát.</string>
<string name="fingerprint_error">Ujjlenyomat probléma: %1$s</string>
<string name="store_with_fingerprint">Használjon ujjlenyomatot a jelszó tárolásához</string>
<string name="biometric_invalid_key">Az ujjlenyomat kulcs nem olvasható. Állítsa vissza a jelszavát.</string>
<string name="biometric_scanning_error">Ujjlenyomat probléma: %1$s</string>
<string name="open_biometric_prompt_store_credential">Használjon ujjlenyomatot a jelszó tárolásához</string>
<string name="no_password_stored">Az adatbázisnak még nincs jelszava.</string>
<string name="education_unlock_summary">Adja meg a jelszót és/vagy a kulcsfájlt, hogy kinyithassa az adatbázist.
@@ -195,7 +195,7 @@
<string name="menu_move">Áthelyezés</string>
<string name="menu_paste">Beillesztés</string>
<string name="menu_cancel">Mégse</string>
<string name="menu_fingerprint_remove_key">Mentett ujjlenyomat törlése</string>
<string name="menu_biometric_remove_key">Mentett ujjlenyomat törlése</string>
<string name="menu_file_selection_read_only">Írásvédett</string>
<string name="menu_open_file_read_and_write">Módosítható</string>
<string name="create_keepass_file">Új adatbázis létrehozása</string>
@@ -248,9 +248,9 @@
<string name="fingerprint">Ujjlenyomat</string>
<string name="biometric_unlock_enable_title">Ujjlenyomat-leolvasás</string>
<string name="biometric_unlock_enable_summary">Lehetővé teszi, hogy leolvassa az ujjlenyomatát az adatbázis feloldásához</string>
<string name="fingerprint_delete_all_title">Titkosítási kulcsok törlése</string>
<string name="fingerprint_delete_all_summary">Az összes ujjlenyomat-felismeréssel kapcsolatos titkosítási kulcs törlése</string>
<string name="fingerprint_delete_all_warning">Biztos, hogy törli az összes ujjlenyomat-felismeréssel kapcsolatos titkosítási kulcsot\?</string>
<string name="biometric_delete_all_key_title">Titkosítási kulcsok törlése</string>
<string name="biometric_delete_all_key_summary">Az összes ujjlenyomat-felismeréssel kapcsolatos titkosítási kulcs törlése</string>
<string name="biometric_delete_all_key_warning">Biztos, hogy törli az összes ujjlenyomat-felismeréssel kapcsolatos titkosítási kulcsot\?</string>
<string name="unavailable_feature_text">A funkciót nem sikerült elindítani.</string>
<string name="unavailable_feature_version">Az Android verziója (%1$s) nem éri el a minimálisan szükséges verziót (%2$s).</string>
<string name="unavailable_feature_hardware">Nem található a megfelelő hardver.</string>

View File

@@ -153,12 +153,12 @@
<string name="warning_read_only">Permetti l\'accesso in scrittura alla scheda SD per salvare le modifiche al database.</string>
<string name="warning_unmounted">Monta la scheda SD per creare o caricare un database.</string>
<string name="version_label">Versione %1$s</string>
<string name="configure_fingerprint">La scansione di impronte è supportata ma non impostata.</string>
<string name="scanning_fingerprint">Scansione impronte</string>
<string name="configure_biometric">La scansione di impronte è supportata ma non impostata.</string>
<string name="open_biometric_prompt_unlock_database">Scansione impronte</string>
<string name="encrypted_value_stored">Password criptata salvata</string>
<string name="fingerprint_invalid_key">Lettura dell\'impronta fallita. Ripristina la tua password.</string>
<string name="fingerprint_error">Problema impronta: %1$s</string>
<string name="store_with_fingerprint">Usa l\'impronta per salvare questa password</string>
<string name="biometric_invalid_key">Lettura dell\'impronta fallita. Ripristina la tua password.</string>
<string name="biometric_scanning_error">Problema impronta: %1$s</string>
<string name="open_biometric_prompt_store_credential">Usa l\'impronta per salvare questa password</string>
<string name="no_password_stored">Questo database non ha ancora alcuna password.</string>
<string name="education_unlock_summary">Inserisci una password e/o file chiave per sbloccare il database.
\n
@@ -194,7 +194,7 @@
<string name="menu_move">Sposta</string>
<string name="menu_paste">Incolla</string>
<string name="menu_cancel">Annulla</string>
<string name="menu_fingerprint_remove_key">Elimina l\'impronta digitale salvata</string>
<string name="menu_biometric_remove_key">Elimina l\'impronta digitale salvata</string>
<string name="menu_file_selection_read_only">Sola lettura</string>
<string name="menu_open_file_read_and_write">Modificabile</string>
<string name="encryption_explanation">Algoritmo di cifratura del database usato per tutti i dati.</string>
@@ -243,9 +243,9 @@
<string name="fingerprint">Impronta</string>
<string name="biometric_unlock_enable_title">Scansione di impronte</string>
<string name="biometric_unlock_enable_summary">Consente la scansione di impronte per aprire il database</string>
<string name="fingerprint_delete_all_title">Elimina chiavi di cifratura</string>
<string name="fingerprint_delete_all_summary">Elimina tutte le chiavi di cifratura relative al riconoscimento dell\'impronta</string>
<string name="fingerprint_delete_all_warning">Sei sicuro di volere eliminare tutte le chiavi relative alle impronte?</string>
<string name="biometric_delete_all_key_title">Elimina chiavi di cifratura</string>
<string name="biometric_delete_all_key_summary">Elimina tutte le chiavi di cifratura relative al riconoscimento dell\'impronta</string>
<string name="biometric_delete_all_key_warning">Sei sicuro di volere eliminare tutte le chiavi relative alle impronte?</string>
<string name="unavailable_feature_text">Impossibile avviare questa funzione.</string>
<string name="unavailable_feature_version">La tua versione di Android %1$s non è la minima %2$s richiesta.</string>
<string name="unavailable_feature_hardware">L\'hardware relativo non è stato trovato.</string>

View File

@@ -179,7 +179,7 @@
<string name="menu_move">移動</string>
<string name="menu_paste">貼り付け</string>
<string name="menu_cancel">キャンセル</string>
<string name="menu_fingerprint_remove_key">保存された指紋を削除</string>
<string name="menu_biometric_remove_key">保存された指紋を削除</string>
<string name="menu_file_selection_read_only">書き込み保護</string>
<string name="menu_open_file_read_and_write">変更可能</string>
<string name="create_keepass_file">新しいデータベースを作成</string>

View File

@@ -114,7 +114,7 @@
<string name="menu_open">열기</string>
<string name="menu_search">검색</string>
<string name="menu_showpass">비밀번호 보이기</string>
<string name="menu_fingerprint_remove_key">저장된 지문 삭제됨</string>
<string name="menu_biometric_remove_key">저장된 지문 삭제됨</string>
<string name="menu_url">링크로 가기</string>
<string name="menu_file_selection_read_only">쓰기 보호됨</string>
<string name="menu_open_file_read_and_write">수정 가능</string>

View File

@@ -114,7 +114,7 @@
<string name="menu_open">Åpne</string>
<string name="menu_search">Søk</string>
<string name="menu_showpass">Vis passord</string>
<string name="menu_fingerprint_remove_key">Fjern fingeravtrykksnøkkelen</string>
<string name="menu_biometric_remove_key">Fjern fingeravtrykksnøkkelen</string>
<string name="menu_url">Gå til nettadresse</string>
<string name="menu_file_selection_read_only">Skrivebeskyttet</string>
<string name="menu_open_file_read_and_write">Les og skriv</string>
@@ -173,13 +173,13 @@
<string name="warning_empty_password">Ønsker du virkelig å bruke en tom streng som ditt passord?</string>
<string name="warning_no_encryption_key">Er du sikker på at du ønsker å bruke en krypteringsnøkkel?</string>
<string name="version_label">Versjon %1$s</string>
<string name="configure_fingerprint">Fingeravtrykket er satt støttet, men ikke satt opp på denne enheten.</string>
<string name="scanning_fingerprint">Venter på fingeravtrykk</string>
<string name="configure_biometric">Fingeravtrykket er satt støttet, men ikke satt opp på denne enheten.</string>
<string name="open_biometric_prompt_unlock_database">Venter på fingeravtrykk</string>
<string name="encrypted_value_stored">Kryptert passord lagret</string>
<string name="fingerprint_invalid_key">Ugyldig fingeravtrykksnøkkelproblem. Gjenopprett passordet ditt.</string>
<string name="biometric_invalid_key">Ugyldig fingeravtrykksnøkkelproblem. Gjenopprett passordet ditt.</string>
<string name="fingerprint_not_recognized">Fremmed fingeravtrykk</string>
<string name="fingerprint_error">Fingeravtrykksproblem: %1$s</string>
<string name="store_with_fingerprint">Bruk fingeravtrykk til å lagre dette passordet</string>
<string name="biometric_scanning_error">Fingeravtrykksproblem: %1$s</string>
<string name="open_biometric_prompt_store_credential">Bruk fingeravtrykk til å lagre dette passordet</string>
<string name="no_password_stored">Denne databasen har ikke et passord enda.</string>
<string name="history">Historikk</string>
<string name="appearance">Utseende</string>
@@ -210,9 +210,9 @@
<string name="fingerprint">Fingeravtrykk</string>
<string name="biometric_unlock_enable_title">Skanner etter fingeravtrykk</string>
<string name="biometric_unlock_enable_summary">Skru på fingeravtrykksåpning av database</string>
<string name="fingerprint_delete_all_title">Slett krypteringsnøkler</string>
<string name="fingerprint_delete_all_summary">Slett alle fingeravtrykksnøkler som har med fingeravtrykksgjenkjennelse å gjøre</string>
<string name="fingerprint_delete_all_warning">Er du sikker på at du vil slette alle nøklene som har med fingeravtrykk å gjøre?</string>
<string name="biometric_delete_all_key_title">Slett krypteringsnøkler</string>
<string name="biometric_delete_all_key_summary">Slett alle fingeravtrykksnøkler som har med fingeravtrykksgjenkjennelse å gjøre</string>
<string name="biometric_delete_all_key_warning">Er du sikker på at du vil slette alle nøklene som har med fingeravtrykk å gjøre?</string>
<string name="unavailable_feature_text">Kunne ikke starte denne funksjonen.</string>
<string name="unavailable_feature_version">Din Androidversjon %1$s oppfyller ikke minimumskravet, %2$s kreves.</string>
<string name="unavailable_feature_hardware">Fant ikke maskinvaren.</string>

View File

@@ -186,7 +186,7 @@
<string name="menu_move">Verplaatsen</string>
<string name="menu_paste">Plakken</string>
<string name="menu_cancel">Annuleren</string>
<string name="menu_fingerprint_remove_key">Opgeslagen vingerafdruk verwijderen</string>
<string name="menu_biometric_remove_key">Opgeslagen vingerafdruk verwijderen</string>
<string name="menu_file_selection_read_only">Alleen-lezen</string>
<string name="menu_open_file_read_and_write">Lezen en schrijven</string>
<string name="protection">Beveiliging</string>
@@ -215,13 +215,13 @@
<string name="warning_password_encoding">Vermijd letters bevatten die niet ondersteund worden door de Latin-1-tekenset van .kdb-bestanden; ze worden allemaal omgezet naar dezelfde letter.</string>
<string name="warning_empty_password">Weet je zeker dat je geen wachtwoordontgrendelbescherming wilt\?</string>
<string name="warning_no_encryption_key">Weet je zeker dat je geen sleutel wilt koppelen aan je versleuteling?</string>
<string name="configure_fingerprint">Vingerafdruk wordt ondersteund, maar is niet ingesteld.</string>
<string name="scanning_fingerprint">Vingerafdrukscanning</string>
<string name="configure_biometric">Vingerafdruk wordt ondersteund, maar is niet ingesteld.</string>
<string name="open_biometric_prompt_unlock_database">Vingerafdrukscanning</string>
<string name="encrypted_value_stored">Versleuteld wachtwoord is opgeslagen</string>
<string name="fingerprint_invalid_key">Kan vingerafdruksleutel niet lezen; herstel je wachtwoord.</string>
<string name="biometric_invalid_key">Kan vingerafdruksleutel niet lezen; herstel je wachtwoord.</string>
<string name="fingerprint_not_recognized">Vingerafdruk niet herkend</string>
<string name="fingerprint_error">Vingerafdrukprobleem: %1$s</string>
<string name="store_with_fingerprint">Vingerafdruk gebruiken om dit wachtwoord op te slaan</string>
<string name="biometric_scanning_error">Vingerafdrukprobleem: %1$s</string>
<string name="open_biometric_prompt_store_credential">Vingerafdruk gebruiken om dit wachtwoord op te slaan</string>
<string name="no_password_stored">Deze databank heeft nog geen wachtwoord.</string>
<string name="history">Geschiedenis</string>
<string name="appearance">Uiterlijk</string>
@@ -252,9 +252,9 @@
<string name="fingerprint">Vingerafdruk</string>
<string name="biometric_unlock_enable_title">Bezig met vingerafdrukherkenning</string>
<string name="biometric_unlock_enable_summary">Databank openen met vingerafdruk</string>
<string name="fingerprint_delete_all_title">Sleutels voor versleuteling verwijderen</string>
<string name="fingerprint_delete_all_summary">Alle aan vingerafdrukherkenning gerelateerde sleutels wilt verwijderen</string>
<string name="fingerprint_delete_all_warning">Weet je zeker dat je alle aan vingerafdrukherkenning gerelateerde sleutels wilt verwijderen?</string>
<string name="biometric_delete_all_key_title">Sleutels voor versleuteling verwijderen</string>
<string name="biometric_delete_all_key_summary">Alle aan vingerafdrukherkenning gerelateerde sleutels wilt verwijderen</string>
<string name="biometric_delete_all_key_warning">Weet je zeker dat je alle aan vingerafdrukherkenning gerelateerde sleutels wilt verwijderen?</string>
<string name="unavailable_feature_text">Kan deze functie niet starten.</string>
<string name="unavailable_feature_version">Je Android-versie, %1$s, voldoet niet aan de minimumvereiste %2$s.</string>
<string name="unavailable_feature_hardware">De hardware wordt niet herkend.</string>

View File

@@ -182,7 +182,7 @@ along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
<string name="menu_move">Przenieś</string>
<string name="menu_paste">Wklej</string>
<string name="menu_cancel">Anuluj</string>
<string name="menu_fingerprint_remove_key">Usuń zapisany klucz linii papilarnych</string>
<string name="menu_biometric_remove_key">Usuń zapisany klucz linii papilarnych</string>
<string name="menu_file_selection_read_only">Chroniony przed zapisem</string>
<string name="menu_open_file_read_and_write">Modyfikowalne</string>
<string name="protection">Ochrona</string>
@@ -209,14 +209,14 @@ along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
<string name="warning_empty_password">Czy naprawdę nie chcesz ochrony przed odblokowaniem hasła\?</string>
<string name="warning_no_encryption_key">Czy na pewno nie chcesz używać żadnego klucza szyfrowania?</string>
<string name="version_label">Wersja %1$s</string>
<string name="configure_fingerprint">Skanowanie odcisków palców jest obsługiwane, ale nie skonfigurowane.</string>
<string name="configure_biometric">Skanowanie odcisków palców jest obsługiwane, ale nie skonfigurowane.</string>
<string name="encrypted_value_stored">"Przechowywane hasło zaszyfrowane "</string>
<string name="sort_groups_before">Grupy poprzednie</string>
<string name="scanning_fingerprint">Skanowanie odcisków palców</string>
<string name="fingerprint_invalid_key">Nie można odczytać klucza linii papilarnych. Przywróć swoje hasło.</string>
<string name="open_biometric_prompt_unlock_database">Skanowanie odcisków palców</string>
<string name="biometric_invalid_key">Nie można odczytać klucza linii papilarnych. Przywróć swoje hasło.</string>
<string name="fingerprint_not_recognized">Nie można rozpoznać odcisku palca</string>
<string name="fingerprint_error">Problem z odciskiem palca: %1$s</string>
<string name="store_with_fingerprint">Użyj odcisku palca, aby zapisać to hasło</string>
<string name="biometric_scanning_error">Problem z odciskiem palca: %1$s</string>
<string name="open_biometric_prompt_store_credential">Użyj odcisku palca, aby zapisać to hasło</string>
<string name="no_password_stored">Baza danych nie ma jeszcze hasła.</string>
<string name="history">Historia</string>
<string name="appearance">Wygląd</string>
@@ -247,9 +247,9 @@ along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
<string name="fingerprint">Odcisk palca</string>
<string name="biometric_unlock_enable_title">Skanowanie odcisków palców</string>
<string name="biometric_unlock_enable_summary">Umożliwia skanowanie odcisku palca w celu otwarcia bazy danych</string>
<string name="fingerprint_delete_all_title">Usuń klucze szyfrowania</string>
<string name="fingerprint_delete_all_summary">Usuń wszystkie klucze szyfrowania związane z rozpoznawaniem linii papilarnych</string>
<string name="fingerprint_delete_all_warning">Czy na pewno chcesz usunąć wszystkie klucze związane z rozpoznawaniem linii papilarnych\?</string>
<string name="biometric_delete_all_key_title">Usuń klucze szyfrowania</string>
<string name="biometric_delete_all_key_summary">Usuń wszystkie klucze szyfrowania związane z rozpoznawaniem linii papilarnych</string>
<string name="biometric_delete_all_key_warning">Czy na pewno chcesz usunąć wszystkie klucze związane z rozpoznawaniem linii papilarnych\?</string>
<string name="unavailable_feature_text">Nie można uruchomić tej funkcji.</string>
<string name="unavailable_feature_version">Twoja wersja Androida %1$s nie spełnia wymaganej minimalnej wersji %2$s.</string>
<string name="unavailable_feature_hardware">Nie można znaleźć odpowiedniego sprzętu.</string>

View File

@@ -179,7 +179,7 @@
<string name="menu_move">Mover</string>
<string name="menu_paste">Colar</string>
<string name="menu_cancel">Cancelar</string>
<string name="menu_fingerprint_remove_key">Deletar impressão digital salva</string>
<string name="menu_biometric_remove_key">Deletar impressão digital salva</string>
<string name="menu_file_selection_read_only">Apenas leitura</string>
<string name="menu_open_file_read_and_write">Leitura e escrita</string>
<string name="protection">Proteção</string>
@@ -208,13 +208,13 @@
<string name="warning_password_encoding">Evite caracteres fora do formato de codificação do arquivo do banco (todos os caracteres não reconhecidos são convertidos para a mesma letra).</string>
<string name="warning_empty_password">Você realmente não quer proteção por senha\?</string>
<string name="warning_no_encryption_key">Você tem certeza de que não quer usar uma chave de encriptação\?</string>
<string name="configure_fingerprint">Impressão digital é suportada, mas não está configurada.</string>
<string name="scanning_fingerprint">Escaneamento de impressão digital</string>
<string name="configure_biometric">Impressão digital é suportada, mas não está configurada.</string>
<string name="open_biometric_prompt_unlock_database">Escaneamento de impressão digital</string>
<string name="encrypted_value_stored">Senha encriptada armazenada</string>
<string name="fingerprint_invalid_key">Não pôde ler chave de impressão digital. Recupere sua senha.</string>
<string name="biometric_invalid_key">Não pôde ler chave de impressão digital. Recupere sua senha.</string>
<string name="fingerprint_not_recognized">Não pôde reconhecer impressão digital</string>
<string name="fingerprint_error">Problema de Impressão digital: %1$s</string>
<string name="store_with_fingerprint">Use Impressão digital para armazenar esta senha</string>
<string name="biometric_scanning_error">Problema de Impressão digital: %1$s</string>
<string name="open_biometric_prompt_store_credential">Use Impressão digital para armazenar esta senha</string>
<string name="no_password_stored">Ainda não há nenhuma senha armazenada nesse banco de dados.</string>
<string name="history">Histórico</string>
<string name="appearance">Aparência</string>
@@ -244,9 +244,9 @@
<string name="fingerprint">Impressão Digital</string>
<string name="biometric_unlock_enable_title">Escaneamento de impressão digital</string>
<string name="biometric_unlock_enable_summary">Permite que você escaneie sua impressão digital para a abertura do banco de dados</string>
<string name="fingerprint_delete_all_title">Apague chaves de encriptação</string>
<string name="fingerprint_delete_all_summary">Apague todas as chaves de encriptação relacionadas ao reconhecimento de Impressões digitais</string>
<string name="fingerprint_delete_all_warning">Tem certeza que você quer apagar todas as chaves relacionadas ao reconhecimento de Impressões digitais\?</string>
<string name="biometric_delete_all_key_title">Apague chaves de encriptação</string>
<string name="biometric_delete_all_key_summary">Apague todas as chaves de encriptação relacionadas ao reconhecimento de Impressões digitais</string>
<string name="biometric_delete_all_key_warning">Tem certeza que você quer apagar todas as chaves relacionadas ao reconhecimento de Impressões digitais\?</string>
<string name="unavailable_feature_text">Não foi possível iniciar esse recurso.</string>
<string name="unavailable_feature_version">Sua versão do Android %1$s não corresponde a versão mínima %2$s necessária.</string>
<string name="unavailable_feature_hardware">Não foi possível encontrar o hardware correspondente.</string>

View File

@@ -182,7 +182,7 @@
<string name="menu_move">Mover</string>
<string name="menu_paste">Colar</string>
<string name="menu_cancel">Cancelar</string>
<string name="menu_fingerprint_remove_key">Apagar de impressão digital gravada</string>
<string name="menu_biometric_remove_key">Apagar de impressão digital gravada</string>
<string name="menu_file_selection_read_only">Protegido contra escrita</string>
<string name="menu_open_file_read_and_write">Pode ser modificado</string>
<string name="create_keepass_file">Criar nova base de dados</string>
@@ -203,11 +203,11 @@
<string name="warning_empty_password">Quer realmente usar uma palavra-chave vazia\?</string>
<string name="warning_no_encryption_key">Tem a certeza que não quer usar uma chave de encriptação\?</string>
<string name="build_label">Construir %1$s</string>
<string name="configure_fingerprint">Impressão digital suportada, mas não configurada para dispositivo.</string>
<string name="configure_biometric">Impressão digital suportada, mas não configurada para dispositivo.</string>
<string name="encrypted_value_stored">Palavra-chave encriptada armazenada</string>
<string name="fingerprint_not_recognized">Impressão digital não reconhecida</string>
<string name="fingerprint_error">Problema da Impressão digital: %1$s</string>
<string name="store_with_fingerprint">Use a impressão digital para armazenar esta palavra-chave</string>
<string name="biometric_scanning_error">Problema da Impressão digital: %1$s</string>
<string name="open_biometric_prompt_store_credential">Use a impressão digital para armazenar esta palavra-chave</string>
<string name="no_password_stored">Ainda não há nenhuma palavra-chave armazenada nesta base de dados.</string>
<string name="history">Histórico</string>
<string name="appearance">Aparência</string>

View File

@@ -154,12 +154,12 @@
<string name="warning_read_only">Карта помять в режиме только для чтения. Изменения не будут сохранены.</string>
<string name="warning_unmounted">Карта памяти не подключена. Работа с базой невозможна.</string>
<string name="version_label">Версия %1$s</string>
<string name="configure_fingerprint">Отпечатки пальцев поддерживаются, но не настроены.</string>
<string name="scanning_fingerprint">Ожидание отпечатка пальца</string>
<string name="configure_biometric">Отпечатки пальцев поддерживаются, но не настроены.</string>
<string name="open_biometric_prompt_unlock_database">Ожидание отпечатка пальца</string>
<string name="encrypted_value_stored">Зашифрованный пароль сохранён</string>
<string name="fingerprint_invalid_key">Неверный ключ отпечатка пальца. Восстановите пароль.</string>
<string name="fingerprint_error">Проблема с отпечатком пальца : %1$s</string>
<string name="store_with_fingerprint">Используйте отпечаток пальца, чтобы сохранить пароль</string>
<string name="biometric_invalid_key">Неверный ключ отпечатка пальца. Восстановите пароль.</string>
<string name="biometric_scanning_error">Проблема с отпечатком пальца : %1$s</string>
<string name="open_biometric_prompt_store_credential">Используйте отпечаток пальца, чтобы сохранить пароль</string>
<string name="no_password_stored">Для этой базы пароль ещё не сохранён</string>
<string name="education_unlock_summary">Введите пароль и/или файл ключа, чтобы разблокировать базу.
\n
@@ -210,7 +210,7 @@
<string name="menu_move">Переместить</string>
<string name="menu_paste">Вставить</string>
<string name="menu_cancel">Отмена</string>
<string name="menu_fingerprint_remove_key">Удалить отпечаток</string>
<string name="menu_biometric_remove_key">Удалить отпечаток</string>
<string name="menu_file_selection_read_only">Только чтение</string>
<string name="menu_open_file_read_and_write">Чтение и запись</string>
<string name="sort_groups_before">Сначала группы</string>
@@ -248,9 +248,9 @@
<string name="fingerprint">Отпечаток пальца</string>
<string name="biometric_unlock_enable_title">Сканирование отпечатка пальца</string>
<string name="biometric_unlock_enable_summary">Включить разблокировку базы с помощью отпечатка пальца</string>
<string name="fingerprint_delete_all_title">Удалить ключи шифрования</string>
<string name="fingerprint_delete_all_summary">Удалить все ключи шифрования, связанные с распознаванием отпечатка пальца</string>
<string name="fingerprint_delete_all_warning">Вы уверены, что хотите удалить все ключи, связанные с отпечатком пальца?</string>
<string name="biometric_delete_all_key_title">Удалить ключи шифрования</string>
<string name="biometric_delete_all_key_summary">Удалить все ключи шифрования, связанные с распознаванием отпечатка пальца</string>
<string name="biometric_delete_all_key_warning">Вы уверены, что хотите удалить все ключи, связанные с отпечатком пальца?</string>
<string name="unavailable_feature_text">Невозможно запустить эту функцию.</string>
<string name="unavailable_feature_version">Ваша версия Android %1$s ниже минимально необходимой %2$s.</string>
<string name="unavailable_feature_hardware">Оборудование не найдено.</string>

View File

@@ -114,7 +114,7 @@
<string name="menu_open"></string>
<string name="menu_search">Ara</string>
<string name="menu_showpass">Parolayı göster</string>
<string name="menu_fingerprint_remove_key">Kaydedilen parmak izini silin</string>
<string name="menu_biometric_remove_key">Kaydedilen parmak izini silin</string>
<string name="menu_url">URL\'a git</string>
<string name="menu_file_selection_read_only">Yazma korumalı</string>
<string name="menu_open_file_read_and_write">Değiştirilebilir</string>
@@ -176,13 +176,13 @@
<string name="warning_no_encryption_key">Herhangi bir şifreleme anahtarı kullanmak istemediğinize emin misiniz\?</string>
<string name="version_label">Sürüm %1$s</string>
<string name="build_label">Yapı %1$s</string>
<string name="configure_fingerprint">Parmak izi taraması desteklenir, ancak kurulmaz.</string>
<string name="scanning_fingerprint">Parmak izi tarama</string>
<string name="configure_biometric">Parmak izi taraması desteklenir, ancak kurulmaz.</string>
<string name="open_biometric_prompt_unlock_database">Parmak izi tarama</string>
<string name="encrypted_value_stored">Şifreli parola saklandı</string>
<string name="fingerprint_invalid_key">Parmak izi anahtarı okunamadı. Şifreni geri yükle.</string>
<string name="biometric_invalid_key">Parmak izi anahtarı okunamadı. Şifreni geri yükle.</string>
<string name="fingerprint_not_recognized">Parmak izi tanınamadı</string>
<string name="fingerprint_error">Parmak izi sorunu: %1$s</string>
<string name="store_with_fingerprint">Bu şifreyi saklamak için parmak izini kullanın</string>
<string name="biometric_scanning_error">Parmak izi sorunu: %1$s</string>
<string name="open_biometric_prompt_store_credential">Bu şifreyi saklamak için parmak izini kullanın</string>
<string name="no_password_stored">Bu veritabanının henüz bir parolası yok.</string>
<string name="history">Geçmiş</string>
<string name="appearance">Görünüm</string>
@@ -213,9 +213,9 @@
<string name="fingerprint">Parmakizi</string>
<string name="biometric_unlock_enable_title">Parmak izi tarama</string>
<string name="biometric_unlock_enable_summary">Veritabanını açmak için parmak izinizi taramanızı sağlar</string>
<string name="fingerprint_delete_all_title">Şifreleme anahtarlarını silin</string>
<string name="fingerprint_delete_all_summary">Parmak izi tanıma ile ilgili tüm şifreleme anahtarlarını silin</string>
<string name="fingerprint_delete_all_warning">Parmak izi tanıma ile ilgili tüm tuşları silmek istediğinizden emin misiniz\?</string>
<string name="biometric_delete_all_key_title">Şifreleme anahtarlarını silin</string>
<string name="biometric_delete_all_key_summary">Parmak izi tanıma ile ilgili tüm şifreleme anahtarlarını silin</string>
<string name="biometric_delete_all_key_warning">Parmak izi tanıma ile ilgili tüm tuşları silmek istediğinizden emin misiniz\?</string>
<string name="unavailable_feature_text">Bu özellik başlatılamadı.</string>
<string name="unavailable_feature_version">Android sürümünüz %1$s, gerekli minimum %2$s sürümünü karşılamıyor.</string>
<string name="unavailable_feature_hardware">İlgili donanım bulunamadı.</string>

View File

@@ -181,7 +181,7 @@
<string name="menu_paste">粘贴</string>
<string name="menu_cancel">取消</string>
<string name="menu_showpass">显示密码</string>
<string name="menu_fingerprint_remove_key">删除保存的指纹</string>
<string name="menu_biometric_remove_key">删除保存的指纹</string>
<string name="menu_file_selection_read_only">只读</string>
<string name="menu_open_file_read_and_write">可修改</string>
<string name="omitbackup_title">搜索时忽略备份条目</string>
@@ -207,7 +207,7 @@
<string name="search_results">搜索结果</string>
<string name="warning">警告</string>
<string name="version_label">版本 %1$s</string>
<string name="store_with_fingerprint">使用指纹保存此密码</string>
<string name="open_biometric_prompt_store_credential">使用指纹保存此密码</string>
<string name="history">历史</string>
<string name="appearance">外观</string>
<string name="general">通用</string>
@@ -249,12 +249,12 @@
<string name="warning_empty_password">你真的不需要密码解锁的保护吗?</string>
<string name="warning_no_encryption_key">你确认不使用任何的密钥吗?</string>
<string name="build_label">版本 %1$s</string>
<string name="configure_fingerprint">指纹解锁功能支持,但没有配置使用。</string>
<string name="scanning_fingerprint">指纹扫描</string>
<string name="configure_biometric">指纹解锁功能支持,但没有配置使用。</string>
<string name="open_biometric_prompt_unlock_database">指纹扫描</string>
<string name="encrypted_value_stored">加密密码存储</string>
<string name="fingerprint_invalid_key">不能读取指纹密钥,请重置你的密码。</string>
<string name="biometric_invalid_key">不能读取指纹密钥,请重置你的密码。</string>
<string name="fingerprint_not_recognized">未能识别的指纹</string>
<string name="fingerprint_error">指纹识别问题:%1$s</string>
<string name="biometric_scanning_error">指纹识别问题:%1$s</string>
<string name="no_password_stored">当前数据库没有任何密码。</string>
<string name="set_autofill_service_title">配置自动填充服务</string>
<string name="set_autofill_service_summary">打开自动填充功能,以便快速的在其他应用中填写信息</string>
@@ -275,9 +275,9 @@
<string name="usage">使用指纹解锁</string>
<string name="biometric_unlock_enable_title">指纹扫描</string>
<string name="biometric_unlock_enable_summary">通过指纹扫描解锁数据库</string>
<string name="fingerprint_delete_all_title">删除加密密钥</string>
<string name="fingerprint_delete_all_summary">删除所有与指纹解锁相关的加密密钥</string>
<string name="fingerprint_delete_all_warning">确认要删除所有与指纹识别相关的密钥吗?</string>
<string name="biometric_delete_all_key_title">删除加密密钥</string>
<string name="biometric_delete_all_key_summary">删除所有与指纹解锁相关的加密密钥</string>
<string name="biometric_delete_all_key_warning">确认要删除所有与指纹识别相关的密钥吗?</string>
<string name="unavailable_feature_text">无法启动此功能。</string>
<string name="unavailable_feature_version">你的安卓版本 %1$s 不能满足软件对最低系统版本 %2$s 的要求。</string>
<string name="unavailable_feature_hardware">找不到所需的硬件。</string>

View File

@@ -163,7 +163,7 @@
<string name="menu_paste">貼上</string>
<string name="menu_cancel">取消</string>
<string name="menu_showpass">顯示密碼</string>
<string name="menu_fingerprint_remove_key">移除指紋密鑰</string>
<string name="menu_biometric_remove_key">移除指紋密鑰</string>
<string name="menu_file_selection_read_only">唯讀</string>
<string name="menu_open_file_read_and_write">讀寫</string>
<string name="omitbackup_title">不要搜尋備份的項目</string>

View File

@@ -94,7 +94,7 @@
<bool name="auto_open_file_uri_default" translatable="false">true</bool>
<string name="biometric_unlock_enable_key" translatable="false">biometric_unlock_enable_key</string>
<bool name="biometric_unlock_enable_default" translatable="false">false</bool>
<string name="fingerprint_delete_all_key" translatable="false">fingerprint_delete_all_key</string>
<string name="biometric_delete_all_key_key" translatable="false">biometric_delete_all_key_key</string>
<!-- Form Filling Settings -->
<string name="settings_form_filling_key" translatable="false">settings_form_filling_key</string>

View File

@@ -162,7 +162,7 @@
<string name="menu_open">Open</string>
<string name="menu_search">Search</string>
<string name="menu_showpass">Show password</string>
<string name="menu_fingerprint_remove_key">Delete saved fingerprint</string>
<string name="menu_biometric_remove_key">Delete saved biometric key</string>
<string name="menu_url">Go to URL</string>
<string name="menu_file_selection_read_only">Write-protected</string>
<string name="menu_open_file_read_and_write">Modifiable</string>
@@ -225,15 +225,17 @@
<string name="warning_no_encryption_key">Are you sure you do not want to use any encryption key?</string>
<string name="version_label">Version %1$s</string>
<string name="build_label">Build %1$s</string>
<string name="configure_fingerprint">Fingerprint scanning is supported but not set up.</string>
<string name="scanning_fingerprint">Fingerprint Scanning</string>
<string name="configure_biometric">Biometric prompt is supported but not set up.</string>
<string name="open_biometric_prompt_unlock_database">Open the biometric prompt to unlock the database</string>
<string name="open_biometric_prompt_store_credential">Open the biometric prompt to store credentials</string>
<string name="biometric_prompt_store_credential_title">Store database credentials with biometric data</string>
<string name="biometric_prompt_extract_credential_title">Extract database credential with biometric data</string>
<string name="encrypted_value_stored">Encrypted password stored</string>
<string name="fingerprint_invalid_key">Could not read fingerprint key. Restore your password.</string>
<string name="biometric_invalid_key">Could not read biometric key. Restore your credential.</string>
<string name="fingerprint_not_recognized">Could not recognize fingerprint</string>
<!--This problem could be with scanning, or something else.-->
<string name="fingerprint_error">Fingerprinting problem: %1$s</string>
<string name="store_with_fingerprint">Use fingerprint to store this password</string>
<string name="no_password_stored">This database does not have a password yet.</string>
<string name="biometric_scanning_error">Biometric error: %1$s</string>
<string name="no_password_stored">This database does not have stored credential yet.</string>
<string name="history">History</string>
<string name="appearance">Appearance</string>
<string name="general">General</string>
@@ -266,9 +268,9 @@
<string name="fingerprint">Fingerprint</string>
<string name="biometric_unlock_enable_title">Biometric unlocking</string>
<string name="biometric_unlock_enable_summary">Lets you scan your fingerprint or other biometric prompt to open the database</string>
<string name="fingerprint_delete_all_title">Delete encryption keys</string>
<string name="fingerprint_delete_all_summary">Delete all encryption keys related to fingerprint recognition</string>
<string name="fingerprint_delete_all_warning">Are you sure you want to delete all keys related to fingerprint recognition?</string>
<string name="biometric_delete_all_key_title">Delete encryption keys</string>
<string name="biometric_delete_all_key_summary">Delete all encryption keys related to biometric recognition</string>
<string name="biometric_delete_all_key_warning">Are you sure you want to delete all keys related to biometric recognition?</string>
<string name="unavailable_feature_text">Could not start this feature.</string>
<string name="unavailable_feature_version">Your Android version %1$s does not meet the minimum version %2$s required.</string>
<string name="unavailable_feature_hardware">Could not find the corresponding hardware.</string>

View File

@@ -143,9 +143,9 @@
android:summary="@string/biometric_unlock_enable_summary"
android:defaultValue="@bool/biometric_unlock_enable_default"/>
<Preference
android:key="@string/fingerprint_delete_all_key"
android:title="@string/fingerprint_delete_all_title"
android:summary="@string/fingerprint_delete_all_summary" />
android:key="@string/biometric_delete_all_key_key"
android:title="@string/biometric_delete_all_key_title"
android:summary="@string/biometric_delete_all_key_summary" />
</PreferenceCategory>