mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
New state mode for biometric unlock
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 l’empreinte digitale enregistrée</string>
|
||||
<string name="menu_biometric_remove_key">Supprimer l’empreinte digitale enregistrée</string>
|
||||
<string name="menu_url">Ouvrir l’URL</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 d’empreinte digitale est prise en charge mais pas configurée.</string>
|
||||
<string name="scanning_fingerprint">Reconnaissance d’empreinte digitale</string>
|
||||
<string name="configure_biometric">La reconnaissance d’empreinte digitale est prise en charge mais pas configurée.</string>
|
||||
<string name="open_biometric_prompt_unlock_database">Reconnaissance d’empreinte digitale</string>
|
||||
<string name="encrypted_value_stored">Mot de passe chiffré stocké</string>
|
||||
<string name="fingerprint_invalid_key">Impossible de lire la clé de l’empreinte digitale. Restaurer votre mot de passe.</string>
|
||||
<string name="biometric_invalid_key">Impossible de lire la clé de l’empreinte digitale. Restaurer votre mot de passe.</string>
|
||||
<string name="fingerprint_not_recognized">Impossible de reconnaître l’empreinte digitale</string>
|
||||
<string name="fingerprint_error">Problème d’empreinte digitale : %1$s</string>
|
||||
<string name="store_with_fingerprint">Utiliser l’empreinte digitale pour stocker ce mot de passe</string>
|
||||
<string name="biometric_scanning_error">Problème d’empreinte digitale : %1$s</string>
|
||||
<string name="open_biometric_prompt_store_credential">Utiliser l’empreinte digitale pour stocker ce mot de passe</string>
|
||||
<string name="no_password_stored">Cette base de données n’a 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 d’empreinte 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 d’empreinte digitale</string>
|
||||
<string name="fingerprint_delete_all_warning">Êtes-vous sûr de vouloir supprimer toutes les clés liées à la reconnaissance d’empreinte 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 d’empreinte digitale</string>
|
||||
<string name="biometric_delete_all_key_warning">Êtes-vous sûr de vouloir supprimer toutes les clés liées à la reconnaissance d’empreinte 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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<string name="menu_open">Aç</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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user