diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fa6cc5fb6..937d51372 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,10 +8,15 @@
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
-
-
-
-
+
+
+
+
- Snackbar.make(coordinatorLayout!!,
- resultMessage,
- Snackbar.LENGTH_LONG).asError().show()
- }
- }
+ coordinatorLayout?.showActionError(result)
}
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt
index 3472f2a70..d4a255950 100644
--- a/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt
@@ -52,6 +52,7 @@ import com.kunzisoft.keepass.database.action.ProgressDialogThread
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.education.FileDatabaseSelectActivityEducation
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_TASK
+import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.*
import com.kunzisoft.keepass.view.asError
import kotlinx.android.synthetic.main.activity_file_selection.*
@@ -274,12 +275,28 @@ class FileDatabaseSelectActivity : StylishActivity(),
updateExternalStorageWarning()
// Construct adapter with listeners
- mFileDatabaseHistoryAction?.getAllFileDatabaseHistories { databaseFileHistoryList ->
- databaseFileHistoryList?.let {
- mAdapterDatabaseHistory?.addDatabaseFileHistoryList(it)
- updateFileListVisibility()
- mAdapterDatabaseHistory?.notifyDataSetChanged()
+ if (PreferencesUtil.showRecentFiles(this)) {
+ mFileDatabaseHistoryAction?.getAllFileDatabaseHistories { databaseFileHistoryList ->
+ databaseFileHistoryList?.let { historyList ->
+ val hideBrokenLocations = PreferencesUtil.hideBrokenLocations(this@FileDatabaseSelectActivity)
+ mAdapterDatabaseHistory?.addDatabaseFileHistoryList(
+ // Show only uri accessible
+ historyList.filter {
+ if (hideBrokenLocations) {
+ UriUtil.parse(it.databaseUri)?.let { historyUri ->
+ UriUtil.isUriAccessible(contentResolver, historyUri)
+ } ?: false
+ } else
+ true
+ })
+ mAdapterDatabaseHistory?.notifyDataSetChanged()
+ updateFileListVisibility()
+ }
}
+ } else {
+ mAdapterDatabaseHistory?.clearDatabaseFileHistoryList()
+ mAdapterDatabaseHistory?.notifyDataSetChanged()
+ updateFileListVisibility()
}
// Register progress task
diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt
index c60874e50..72c939bc0 100644
--- a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt
@@ -76,6 +76,7 @@ import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.view.AddNodeButtonView
import com.kunzisoft.keepass.view.ToolbarAction
import com.kunzisoft.keepass.view.asError
+import com.kunzisoft.keepass.view.showActionError
class GroupActivity : LockingActivity(),
GroupEditDialogFragment.EditGroupListener,
@@ -251,15 +252,7 @@ class GroupActivity : LockingActivity(),
}
}
- if (!result.isSuccess) {
- coordinatorLayout?.let { coordinatorLayout ->
- result.exception?.errorId?.let { errorId ->
- Snackbar.make(coordinatorLayout, errorId, Snackbar.LENGTH_LONG).asError().show()
- } ?: result.message?.let { message ->
- Snackbar.make(coordinatorLayout, message, Snackbar.LENGTH_LONG).asError().show()
- }
- }
- }
+ coordinatorLayout?.showActionError(result)
finishNodeAction()
diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt
index fd1e71f29..c75cba034 100644
--- a/app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt
@@ -24,7 +24,6 @@ import android.app.assist.AssistStructure
import android.app.backup.BackupManager
import android.content.Intent
import android.content.SharedPreferences
-import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
@@ -33,16 +32,15 @@ import android.preference.PreferenceManager
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
-import android.view.KeyEvent
-import android.view.Menu
-import android.view.MenuItem
-import android.view.View
+import android.view.*
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
-import android.widget.*
+import android.widget.Button
+import android.widget.CompoundButton
+import android.widget.EditText
+import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar
import androidx.biometric.BiometricManager
-import androidx.core.app.ActivityCompat
import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.DuplicateUuidDialog
@@ -74,11 +72,10 @@ import com.kunzisoft.keepass.view.asError
import kotlinx.android.synthetic.main.activity_password.*
import java.io.FileNotFoundException
-class PasswordActivity : StylishActivity() {
+open class PasswordActivity : StylishActivity() {
// Views
private var toolbar: Toolbar? = null
-
private var containerView: View? = null
private var filenameView: TextView? = null
private var passwordView: EditText? = null
@@ -88,18 +85,28 @@ class PasswordActivity : StylishActivity() {
private var checkboxKeyFileView: CompoundButton? = null
private var checkboxDefaultDatabaseView: CompoundButton? = null
private var advancedUnlockInfoView: AdvancedUnlockInfoView? = null
+ private var infoContainerView: ViewGroup? = null
private var enableButtonOnCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null
private var mDatabaseFileUri: Uri? = null
private var mDatabaseKeyFileUri: Uri? = null
- private var prefs: SharedPreferences? = null
+ private var mSharedPreferences: SharedPreferences? = null
private var mRememberKeyFile: Boolean = false
private var mOpenFileHelper: OpenFileHelper? = null
- private var mPermissionAsked = false
private var readOnly: Boolean = false
+ private var mForceReadOnly: Boolean = false
+ set(value) {
+ infoContainerView?.visibility = if (value) {
+ readOnly = true
+ View.VISIBLE
+ } else {
+ View.GONE
+ }
+ field = value
+ }
private var mProgressDialogThread: ProgressDialogThread? = null
@@ -108,9 +115,9 @@ class PasswordActivity : StylishActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- prefs = PreferenceManager.getDefaultSharedPreferences(this)
+ mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
- mRememberKeyFile = PreferencesUtil.rememberKeyFiles(this)
+ mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
setContentView(R.layout.activity_password)
@@ -121,7 +128,7 @@ class PasswordActivity : StylishActivity() {
supportActionBar?.setDisplayShowHomeEnabled(true)
containerView = findViewById(R.id.container)
- confirmButtonView = findViewById(R.id.pass_ok)
+ confirmButtonView = findViewById(R.id.activity_password_open_button)
filenameView = findViewById(R.id.filename)
passwordView = findViewById(R.id.password)
keyFileView = findViewById(R.id.pass_keyfile)
@@ -129,8 +136,8 @@ class PasswordActivity : StylishActivity() {
checkboxKeyFileView = findViewById(R.id.keyfile_checkox)
checkboxDefaultDatabaseView = findViewById(R.id.default_database)
advancedUnlockInfoView = findViewById(R.id.biometric_info)
+ infoContainerView = findViewById(R.id.activity_password_info_container)
- mPermissionAsked = savedInstanceState?.getBoolean(KEY_PERMISSION_ASKED) ?: mPermissionAsked
readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrPreference(this, savedInstanceState)
val browseView = findViewById(R.id.open_database_button)
@@ -180,6 +187,7 @@ class PasswordActivity : StylishActivity() {
removePassword()
if (result.isSuccess) {
+ setEmptyViews()
launchGroupActivity()
} else {
var resultError = ""
@@ -281,7 +289,6 @@ class PasswordActivity : StylishActivity() {
}
override fun onSaveInstanceState(outState: Bundle) {
- outState.putBoolean(KEY_PERMISSION_ASKED, mPermissionAsked)
ReadOnlyHelper.onSaveInstanceState(outState, readOnly)
super.onSaveInstanceState(outState)
}
@@ -302,6 +309,8 @@ class PasswordActivity : StylishActivity() {
keyFileUri = intent.getParcelableExtra(KEY_KEYFILE)
}
+ mForceReadOnly = UriUtil.isUriNotWritable(contentResolver, databaseUri)
+
// Post init uri with KeyFile if needed
if (mRememberKeyFile && (keyFileUri == null || keyFileUri.toString().isEmpty())) {
// Retrieve KeyFile in a thread
@@ -340,7 +349,7 @@ class PasswordActivity : StylishActivity() {
newDefaultFileName = databaseFileUri ?: newDefaultFileName
}
- prefs?.edit()?.apply {
+ mSharedPreferences?.edit()?.apply {
newDefaultFileName?.let {
putString(KEY_DEFAULT_DATABASE_PATH, newDefaultFileName.toString())
} ?: kotlin.run {
@@ -355,7 +364,7 @@ class PasswordActivity : StylishActivity() {
confirmButtonView?.setOnClickListener { verifyCheckboxesAndLoadDatabase() }
// Retrieve settings for default database
- val defaultFilename = prefs?.getString(KEY_DEFAULT_DATABASE_PATH, "")
+ val defaultFilename = mSharedPreferences?.getString(KEY_DEFAULT_DATABASE_PATH, "")
if (databaseFileUri != null
&& databaseFileUri.path != null && databaseFileUri.path!!.isNotEmpty()
&& databaseFileUri == UriUtil.parse(defaultFilename)) {
@@ -551,7 +560,12 @@ class PasswordActivity : StylishActivity() {
val inflater = menuInflater
// Read menu
inflater.inflate(R.menu.open_file, menu)
- changeOpenFileReadIcon(menu.findItem(R.id.menu_open_file_read_mode_key))
+
+ if (mForceReadOnly) {
+ menu.removeItem(R.id.menu_open_file_read_mode_key)
+ } else {
+ changeOpenFileReadIcon(menu.findItem(R.id.menu_open_file_read_mode_key))
+ }
MenuUtil.defaultMenuInflater(inflater, menu)
@@ -562,45 +576,14 @@ class PasswordActivity : StylishActivity() {
super.onCreateOptionsMenu(menu)
- launchEducation(menu) {
- launchCheckPermission()
- }
+ launchEducation(menu)
return true
}
- // Check permission
- private fun launchCheckPermission() {
- val writePermission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE
- val permissions = arrayOf(writePermission)
- if (Build.VERSION.SDK_INT >= 23
- && !readOnly
- && !mPermissionAsked) {
- mPermissionAsked = true
- // Check self permission to show or not the dialog
- if (toolbar != null
- && ActivityCompat.checkSelfPermission(this, writePermission) != PackageManager.PERMISSION_GRANTED) {
- ActivityCompat.requestPermissions(this, permissions, WRITE_EXTERNAL_STORAGE_REQUEST)
- }
- }
- }
-
- override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults)
-
- when (requestCode) {
- WRITE_EXTERNAL_STORAGE_REQUEST -> {
- if (grantResults.isEmpty() || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
- if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE))
- Toast.makeText(this, R.string.read_only_warning, Toast.LENGTH_LONG).show()
- }
- }
- }
- }
-
// To fix multiple view education
private var performedEductionInProgress = false
- private fun launchEducation(menu: Menu, onEducationFinished: ()-> Unit) {
+ private fun launchEducation(menu: Menu, onEducationFinished: (()-> Unit)? = null) {
if (!performedEductionInProgress) {
performedEductionInProgress = true
// Show education views
@@ -610,7 +593,7 @@ class PasswordActivity : StylishActivity() {
private fun performedNextEducation(passwordActivityEducation: PasswordActivityEducation,
menu: Menu,
- onEducationFinished: ()-> Unit) {
+ onEducationFinished: (()-> Unit)? = null) {
val educationToolbar = toolbar
val unlockEducationPerformed = educationToolbar != null
&& passwordActivityEducation.checkAndPerformedUnlockEducation(
@@ -650,7 +633,7 @@ class PasswordActivity : StylishActivity() {
})
if (!biometricEducationPerformed) {
- onEducationFinished.invoke()
+ onEducationFinished?.invoke()
}
}
}
@@ -727,10 +710,6 @@ class PasswordActivity : StylishActivity() {
private const val KEY_PASSWORD = "password"
private const val KEY_LAUNCH_IMMEDIATELY = "launchImmediately"
- private const val KEY_PERMISSION_ASKED = "KEY_PERMISSION_ASKED"
-
- private const val WRITE_EXTERNAL_STORAGE_REQUEST = 647
-
private fun buildAndLaunchIntent(activity: Activity, databaseFile: Uri, keyFile: Uri?,
intentBuildLauncher: (Intent) -> Unit) {
val intent = Intent(activity, PasswordActivity::class.java)
diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/FileDatabaseHistoryAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/FileDatabaseHistoryAdapter.kt
index 5907a6b15..3d01189b4 100644
--- a/app/src/main/java/com/kunzisoft/keepass/adapters/FileDatabaseHistoryAdapter.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/adapters/FileDatabaseHistoryAdapter.kt
@@ -20,6 +20,8 @@
package com.kunzisoft.keepass.adapters
import android.content.Context
+import android.graphics.Color
+import android.graphics.PorterDuff
import androidx.annotation.ColorInt
import androidx.recyclerview.widget.RecyclerView
import android.util.TypedValue
@@ -82,15 +84,26 @@ class FileDatabaseHistoryAdapter(private val context: Context)
// File path
holder.filePath.text = UriUtil.decode(fileDatabaseInfo.fileUri?.toString())
- holder.filePreciseInfoContainer.visibility = if (fileDatabaseInfo.found()) {
- // Modification
- holder.fileModification.text = fileDatabaseInfo.getModificationString()
- // Size
- holder.fileSize.text = fileDatabaseInfo.getSizeString()
+ if (fileDatabaseInfo.dataAccessible()) {
+ holder.fileInformation.clearColorFilter()
+ } else {
+ holder.fileInformation.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY)
+ }
- View.VISIBLE
- } else
- View.GONE
+ // Modification
+ if (fileDatabaseInfo.lastModificationAccessible()) {
+ holder.fileModification.text = fileDatabaseInfo.getModificationString()
+ holder.fileModification.visibility = View.VISIBLE
+ } else {
+ holder.fileModification.visibility = View.GONE
+ }
+ // Size
+ if (fileDatabaseInfo.sizeAccessible()) {
+ holder.fileSize.text = fileDatabaseInfo.getSizeString()
+ holder.fileSize.visibility = View.VISIBLE
+ } else {
+ holder.fileSize.visibility = View.GONE
+ }
// Click on information
val isExpanded = position == mExpandedPosition
@@ -142,6 +155,10 @@ class FileDatabaseHistoryAdapter(private val context: Context)
return listDatabaseFiles.size
}
+ fun clearDatabaseFileHistoryList() {
+ listDatabaseFiles.clear()
+ }
+
fun addDatabaseFileHistoryList(listFileDatabaseHistoryToAdd: List) {
listDatabaseFiles.clear()
listDatabaseFiles.addAll(listFileDatabaseHistoryToAdd)
@@ -178,7 +195,6 @@ class FileDatabaseHistoryAdapter(private val context: Context)
var fileModifyButton: ImageView = itemView.findViewById(R.id.file_modify_button)
var fileDeleteButton: ImageView = itemView.findViewById(R.id.file_delete_button)
var filePath: TextView = itemView.findViewById(R.id.file_path)
- var filePreciseInfoContainer: ViewGroup = itemView.findViewById(R.id.file_precise_info_container)
var fileModification: TextView = itemView.findViewById(R.id.file_modification)
var fileSize: TextView = itemView.findViewById(R.id.file_size)
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/action/CreateDatabaseRunnable.kt b/app/src/main/java/com/kunzisoft/keepass/database/action/CreateDatabaseRunnable.kt
index dc0285883..9ac60a887 100644
--- a/app/src/main/java/com/kunzisoft/keepass/database/action/CreateDatabaseRunnable.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/database/action/CreateDatabaseRunnable.kt
@@ -24,6 +24,7 @@ import android.net.Uri
import android.util.Log
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.database.element.Database
+import com.kunzisoft.keepass.settings.PreferencesUtil
class CreateDatabaseRunnable(context: Context,
private val mDatabase: Database,
@@ -57,8 +58,11 @@ class CreateDatabaseRunnable(context: Context,
if (result.isSuccess) {
// Add database to recent files
- FileDatabaseHistoryAction.getInstance(context.applicationContext)
- .addOrUpdateDatabaseUri(mDatabaseUri, mKeyFile)
+ if (PreferencesUtil.rememberDatabaseLocations(context)) {
+ FileDatabaseHistoryAction.getInstance(context.applicationContext)
+ .addOrUpdateDatabaseUri(mDatabaseUri,
+ if (PreferencesUtil.rememberKeyFileLocations(context)) mKeyFile else null)
+ }
} else {
Log.e("CreateDatabaseRunnable", "Unable to create the database")
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/action/LoadDatabaseRunnable.kt b/app/src/main/java/com/kunzisoft/keepass/database/action/LoadDatabaseRunnable.kt
index 00d5fff24..d584f1bbb 100644
--- a/app/src/main/java/com/kunzisoft/keepass/database/action/LoadDatabaseRunnable.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/database/action/LoadDatabaseRunnable.kt
@@ -74,14 +74,10 @@ class LoadDatabaseRunnable(private val context: Context,
override fun onFinishRun() {
if (result.isSuccess) {
// Save keyFile in app database
- val rememberKeyFile = PreferencesUtil.rememberKeyFiles(context)
- if (rememberKeyFile) {
- var keyUri = mKey
- if (!rememberKeyFile) {
- keyUri = null
- }
+ if (PreferencesUtil.rememberDatabaseLocations(context)) {
FileDatabaseHistoryAction.getInstance(context)
- .addOrUpdateDatabaseUri(mUri, keyUri)
+ .addOrUpdateDatabaseUri(mUri,
+ if (PreferencesUtil.rememberKeyFileLocations(context)) mKey else null)
}
// Register the biometric
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt b/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt
index 067b026c2..31facc9e1 100644
--- a/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt
@@ -75,16 +75,16 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
activity?.let { activity ->
allowCopyPassword()
- findPreference(getString(R.string.keyfile_key))?.setOnPreferenceChangeListener { _, newValue ->
+ findPreference(getString(R.string.remember_database_locations_key))?.setOnPreferenceChangeListener { _, newValue ->
if (!(newValue as Boolean)) {
- FileDatabaseHistoryAction.getInstance(activity.applicationContext).deleteAllKeyFiles()
+ FileDatabaseHistoryAction.getInstance(activity.applicationContext).deleteAll()
}
true
}
- findPreference(getString(R.string.recentfile_key))?.setOnPreferenceChangeListener { _, newValue ->
+ findPreference(getString(R.string.remember_keyfile_locations_key))?.setOnPreferenceChangeListener { _, newValue ->
if (!(newValue as Boolean)) {
- FileDatabaseHistoryAction.getInstance(activity.applicationContext).deleteAll()
+ FileDatabaseHistoryAction.getInstance(activity.applicationContext).deleteAllKeyFiles()
}
true
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt b/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt
index f8cb09b1f..c86b90c55 100644
--- a/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt
@@ -28,10 +28,28 @@ import java.util.*
object PreferencesUtil {
- fun rememberKeyFiles(context: Context): Boolean {
+ fun rememberDatabaseLocations(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
- return prefs.getBoolean(context.getString(R.string.keyfile_key),
- context.resources.getBoolean(R.bool.keyfile_default))
+ return prefs.getBoolean(context.getString(R.string.remember_database_locations_key),
+ context.resources.getBoolean(R.bool.remember_database_locations_default))
+ }
+
+ fun showRecentFiles(context: Context): Boolean {
+ val prefs = PreferenceManager.getDefaultSharedPreferences(context)
+ return prefs.getBoolean(context.getString(R.string.show_recent_files_key),
+ context.resources.getBoolean(R.bool.show_recent_files_default))
+ }
+
+ fun hideBrokenLocations(context: Context): Boolean {
+ val prefs = PreferenceManager.getDefaultSharedPreferences(context)
+ return prefs.getBoolean(context.getString(R.string.hide_broken_locations_key),
+ context.resources.getBoolean(R.bool.hide_broken_locations_default))
+ }
+
+ fun rememberKeyFileLocations(context: Context): Boolean {
+ val prefs = PreferenceManager.getDefaultSharedPreferences(context)
+ return prefs.getBoolean(context.getString(R.string.remember_keyfile_locations_key),
+ context.resources.getBoolean(R.bool.remember_keyfile_locations_default))
}
fun omitBackup(context: Context): Boolean {
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/SettingsActivity.kt b/app/src/main/java/com/kunzisoft/keepass/settings/SettingsActivity.kt
index 81e8ad6c7..f2099c35a 100644
--- a/app/src/main/java/com/kunzisoft/keepass/settings/SettingsActivity.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/SettingsActivity.kt
@@ -27,6 +27,7 @@ import android.net.Uri
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.widget.Toolbar
+import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.Fragment
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment
@@ -35,6 +36,7 @@ import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
import com.kunzisoft.keepass.activities.lock.LockingActivity
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.timeout.TimeoutHelper
+import com.kunzisoft.keepass.view.showActionError
open class SettingsActivity
: LockingActivity(),
@@ -43,6 +45,7 @@ open class SettingsActivity
private var backupManager: BackupManager? = null
+ private var coordinatorLayout: CoordinatorLayout? = null
private var toolbar: Toolbar? = null
companion object {
@@ -74,6 +77,8 @@ open class SettingsActivity
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_toolbar)
+
+ coordinatorLayout = findViewById(R.id.toolbar_coordinator)
toolbar = findViewById(R.id.toolbar)
toolbar?.setTitle(R.string.settings)
setSupportActionBar(toolbar)
@@ -92,6 +97,8 @@ open class SettingsActivity
(supportFragmentManager
.findFragmentByTag(TAG_NESTED) as NestedSettingsFragment?)
?.onProgressDialogThreadResult(actionTask, result)
+
+ coordinatorLayout?.showActionError(result)
}
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt b/app/src/main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt
index 83707f92c..a9b8ab7f2 100644
--- a/app/src/main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt
@@ -98,10 +98,14 @@ class ClipboardHelper(private val context: Context) {
@Throws(ClipboardException::class)
fun cleanClipboard(label: String = "") {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- getClipboardManager()?.clearPrimaryClip()
- } else {
- copyToClipboard(label, "")
+ try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ getClipboardManager()?.clearPrimaryClip()
+ } else {
+ copyToClipboard(label, "")
+ }
+ } catch (e: Exception) {
+ throw ClipboardException(e)
}
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/FileInfo.kt b/app/src/main/java/com/kunzisoft/keepass/utils/FileInfo.kt
index 4041f0422..d7a4a2b72 100644
--- a/app/src/main/java/com/kunzisoft/keepass/utils/FileInfo.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/utils/FileInfo.kt
@@ -22,8 +22,6 @@ package com.kunzisoft.keepass.utils
import android.content.Context
import android.net.Uri
import android.text.format.Formatter
-import androidx.documentfile.provider.DocumentFile
-import java.io.File
import java.io.Serializable
import java.text.DateFormat
import java.util.*
@@ -34,7 +32,7 @@ open class FileInfo : Serializable {
var fileUri: Uri?
var filePath: String? = null
var fileName: String? = ""
- var lastModification = Date()
+ var lastModification = Date(0L)
var size: Long = 0L
constructor(context: Context, fileUri: Uri) {
@@ -51,22 +49,11 @@ open class FileInfo : Serializable {
fun init() {
this.filePath = fileUri?.path
- if (EXTERNAL_STORAGE_AUTHORITY == fileUri?.authority) {
- fileUri?.let { fileUri ->
- DocumentFile.fromSingleUri(context, fileUri)?.let { file ->
- size = file.length()
- fileName = file.name
- lastModification = Date(file.lastModified())
- }
- }
- } else {
- filePath?.let {
- File(it).let { file ->
- size = file.length()
- fileName = file.name
- lastModification = Date(file.lastModified())
- }
- }
+
+ UriUtil.getFileData(context, fileUri)?.let { file ->
+ size = file.length()
+ fileName = file.name
+ lastModification = Date(file.lastModified())
}
if (fileName == null || fileName!!.isEmpty()) {
@@ -74,10 +61,18 @@ open class FileInfo : Serializable {
}
}
- fun found(): Boolean {
+ fun lastModificationAccessible(): Boolean {
+ return lastModification.after(Date(0L))
+ }
+
+ fun sizeAccessible(): Boolean {
return size != 0L
}
+ fun dataAccessible(): Boolean {
+ return UriUtil.isUriAccessible(context.contentResolver, fileUri)
+ }
+
fun getModificationString(): String {
return DateFormat.getDateTimeInstance()
.format(lastModification)
@@ -86,9 +81,4 @@ open class FileInfo : Serializable {
fun getSizeString(): String {
return Formatter.formatFileSize(context, size)
}
-
- companion object {
-
- private const val EXTERNAL_STORAGE_AUTHORITY = "com.android.externalstorage.documents"
- }
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/UriUtil.kt b/app/src/main/java/com/kunzisoft/keepass/utils/UriUtil.kt
index 3ded3cb6c..2e22e25e8 100644
--- a/app/src/main/java/com/kunzisoft/keepass/utils/UriUtil.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/utils/UriUtil.kt
@@ -24,29 +24,87 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
+import android.util.Log
import android.widget.Toast
+import androidx.documentfile.provider.DocumentFile
import com.kunzisoft.keepass.R
+import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.InputStream
+import java.util.*
object UriUtil {
- @Throws(FileNotFoundException::class)
- fun getUriInputStream(contentResolver: ContentResolver, uri: Uri?): InputStream? {
- if (uri == null)
- return null
- val scheme = uri.scheme
- return if (scheme == null || scheme.isEmpty() || scheme == "file") {
- FileInputStream(uri.path!!)
- } else if (scheme == "content") {
- contentResolver.openInputStream(uri)
- } else {
- null
+ fun isUriAccessible(contentResolver: ContentResolver, fileUri: Uri?): Boolean {
+ if (fileUri == null)
+ return false
+ return try {
+ //https://developer.android.com/reference/android/content/res/AssetFileDescriptor
+ contentResolver.openAssetFileDescriptor(fileUri, "r")?.close()
+ true
+ } catch (e: Exception) {
+ Log.e(UriUtil.javaClass.name, "Unable to access uri $fileUri : ${e.message}")
+ false
}
}
+ fun isUriNotWritable(contentResolver: ContentResolver, fileUri: Uri?): Boolean {
+ if (fileUri == null)
+ return true
+ return try {
+ contentResolver.openAssetFileDescriptor(fileUri, "wa")?.close()
+ false
+ } catch (e: Exception) {
+ Log.e(UriUtil.javaClass.name, "Unable to access uri $fileUri : ${e.message}")
+ true
+ }
+ }
+
+ fun getFileData(context: Context, fileUri: Uri?): DocumentFile? {
+ if (fileUri == null)
+ return null
+ return when {
+ isFileScheme(fileUri) -> {
+ fileUri.path?.let {
+ File(it).let { file ->
+ return DocumentFile.fromFile(file)
+ }
+ }
+ }
+ isContentScheme(fileUri) -> DocumentFile.fromSingleUri(context, fileUri)
+ else -> null
+ }
+ }
+
+ @Throws(FileNotFoundException::class)
+ fun getUriInputStream(contentResolver: ContentResolver, fileUri: Uri?): InputStream? {
+ if (fileUri == null)
+ return null
+ return when {
+ isFileScheme(fileUri) -> fileUri.path?.let { FileInputStream(it) }
+ isContentScheme(fileUri) -> contentResolver.openInputStream(fileUri)
+ else -> null
+ }
+ }
+
+ private fun isFileScheme(fileUri: Uri): Boolean {
+ val scheme = fileUri.scheme
+ if (scheme == null || scheme.isEmpty() || scheme.toLowerCase(Locale.ENGLISH) == "file") {
+ return true
+ }
+ return false
+ }
+
+ private fun isContentScheme(fileUri: Uri): Boolean {
+ val scheme = fileUri.scheme
+ if (scheme != null && scheme.toLowerCase(Locale.ENGLISH) == "content") {
+ return true
+ }
+ return false
+ }
+
fun parse(stringUri: String?): Uri? {
return if (stringUri?.isNotEmpty() == true) {
Uri.parse(stringUri)
diff --git a/app/src/main/java/com/kunzisoft/keepass/view/ViewUtil.kt b/app/src/main/java/com/kunzisoft/keepass/view/ViewUtil.kt
index 1daec2536..17fe14f4a 100644
--- a/app/src/main/java/com/kunzisoft/keepass/view/ViewUtil.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/view/ViewUtil.kt
@@ -29,8 +29,10 @@ import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
+import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.snackbar.Snackbar
import com.kunzisoft.keepass.R
+import com.kunzisoft.keepass.tasks.ActionRunnable
/**
* Replace font by monospace, must be called after seText()
@@ -99,4 +101,14 @@ fun Toolbar.expand(animate: Boolean = true) {
play(slideAnimator)
interpolator = AccelerateDecelerateInterpolator()
}.start()
+}
+
+fun CoordinatorLayout.showActionError(result: ActionRunnable.Result) {
+ if (!result.isSuccess) {
+ result.exception?.errorId?.let { errorId ->
+ Snackbar.make(this, errorId, Snackbar.LENGTH_LONG).asError().show()
+ } ?: result.message?.let { message ->
+ Snackbar.make(this, message, Snackbar.LENGTH_LONG).asError().show()
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_password.xml b/app/src/main/res/layout/activity_password.xml
index 622fe82e7..c45eef25a 100644
--- a/app/src/main/res/layout/activity_password.xml
+++ b/app/src/main/res/layout/activity_password.xml
@@ -32,7 +32,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/pass_ok">
+ app:layout_constraintBottom_toTopOf="@+id/activity_password_info_container">
+ android:scrollbarStyle="insideOverlay"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+
+
+
.
-->
-
-
-
-
-
+
+ android:layout_height="match_parent">
-
\ No newline at end of file
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_file_row.xml b/app/src/main/res/layout/item_file_row.xml
index 34c612734..d5ac85cc3 100644
--- a/app/src/main/res/layout/item_file_row.xml
+++ b/app/src/main/res/layout/item_file_row.xml
@@ -186,7 +186,7 @@
إنشاء قاعدة بيانات جديدة …
الحماية
للقراءة فقط
- تذكر أسماء الملفات المستخدمة مؤخرا
حذف
الجذر
استخدام الذاكرة
@@ -172,11 +171,8 @@
لا تبحثفي مدخلات النسخ الاحتياطي
قيد العمل…
KeePassDX يحتاج صلاحية الكتابة من اجل تعديل قاعدة البيانات.
- تذكر موقع ملف المفتاح قاعدة البيانات
- حفظ الملف المفتاحي
خوارزمية تشفير جميع البيانات.
قاعدة بيانات غير مدعومة.
- اسمح بالكتابة على بطاقة الذاكرة لحفظ التغيرات.
اربط بطاقة الذاكرة لإنشاء او تحميل قاعدة بيانات.
بناء %1$s
تم حفظ كلمة السر المشفرة
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 3b2ed4e38..f1f5ab346 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -113,8 +113,6 @@
Omet els grups \'Còpia de seguretat\' i paperera dels resultats de cerca
Creant nova base de dades…
Treballant…
- Recorda la localització d\'arxius clau
- Guarda arxiu clau
Elimina
Rijndael (AES)
Arrel
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index c3a11e3ab..98226e7e0 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -123,10 +123,6 @@
Zpracování…
Ochrana
Ke změně v databázi potřebuje KeePassDX oprávnění pro zápis.
- Historie nedávných souborů
- Pamatovat si nedávno otevřené soubory
- Pamatovat si umístění souborů s klíči
- Uložit soubor s klíčem
Odstranit
Rijndael (AES)
Kořen
@@ -144,7 +140,6 @@
Nepodporovaná verze databáze.
Velká písmena
Verze %1$s
- Povolte oprávnění k zápisu na SD kartu, aby bylo možné uložit změny v databázi.
Připojte SD kartu, aby bylo možné vytvořit a otevřít databázi.
Databázi odemknete zadáním hesla a/nebo souboru s klíčem.
\n
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index f4885f3a7..30e73d9dc 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -122,10 +122,6 @@
Arbejder…
Beskyttelse
KeePassDX behøver skrivetilladelse for at ændre i databasen.
- Seneste filhistorik
- Husk de seneste filnavne
- Husker placeringen af databasernøglefiler
- Gem nøglefil
Fjern
Rijndael (AES)
Rod
@@ -142,7 +138,6 @@
Understregning
Database-versionen er ikke understøttet.
Store bogstaver
- Giv SD-kort skrive adgang for at gemme databasen ændringer.
Monter SD-kortet for at oprette eller indlæse en database.
Version %1$s
Angiv en adgangskode og/eller en nøglefil til at låse databasen op.
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 02ea6227a..86c045960 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -127,10 +127,6 @@
Sicherheit
Schreibgeschützt
KeePassDX benötigt Schreibrechte, um etwas an der Datenbank zu ändern.
- Zuletzt verwendete Datenbanken
- Zuletzt verwendete Datenbanken merken
- Erinnert sich an den Speicherort der Schlüsseldateien der Datenbanken
- Schlüsselquelle merken
Löschen
Rijndael (AES)
Start
@@ -149,7 +145,6 @@
Großbuchstaben
Warnung
Passwortzeichen in der Datenbank vermeiden, die kein Text-Encoding-Format besitzen (nicht erkannte Zeichen werden in denselben Buchstaben umgewandelt).
- Schreibzugriff auf die SD-Karte gewähren, um Datenbankänderungen speichern zu können.
Die SD-Karte einbinden, um eine Datenbank erstellen oder laden zu können.
Version %1$s
Geben Sie das Passwort und/oder die Schlüsseldatei ein, um Ihre Datenbank zu entsperren.
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index c5a30e303..3b4f29368 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -122,10 +122,6 @@
Επεξεργασία…
Προστασία
Το KeePassDX χρειάζεται άδεια εγγραφής για να αλλάξει οτιδήποτε στη βάση δεδομένων σας.
- Πρόσφατο ιστορικό αρχείων
- Απομνημόνευση πρόσφατων ονομάτων αρχείων
- Απομνημόνευση της τοποθεσίας αρχείων-κλειδιών των βάσεων δεδομένων
- Αποθήκευση αρχείου-κλειδιού
Αφαίρεση
Rijndael (AES)
Ριζικός Κατάλογος
@@ -190,7 +186,6 @@
Προσπέλαση
Προειδοποίηση
Αποφύγετε τους χαρακτήρες κωδικού πρόσβασης έξω από τη μορφή κωδικοποίησης κειμένου στο αρχείο βάσης δεδομένων (οι μη αναγνωρισμένοι χαρακτήρες μετατρέπονται στο ίδιο γράμμα).
- Δώστε πρόσβαση εγγραφής στην κάρτα SD για να αποθηκεύσετε τις αλλαγές της βάσης δεδομένων.
Θέλετε πραγματικά να μην έχετε κανέναν κωδικό προστασίας ξεκλειδώματος;
Είστε βέβαιοι ότι δεν θέλετε να χρησιμοποιήσετε κάποιο κλειδί κρυπτογράφησης;
Ο Κρυπτογραφημένος κωδικός έχει αποθηκευτεί
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 4aeceeac4..aad777742 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -106,15 +106,11 @@
Nunca
Sin resultado de búsqueda
Instale un navegador web para abrir este URL.
- Historial de archivos recientes
- Recordar nombres de archivos recientes
Bases de datos recientes
No buscar en las entradas de respaldo
Omite los grupos «Respaldo» y «Papelera de reciclaje» de los resultados de búsqueda
Creando nueva base de datos…
Trabajando…
- Recuerda la ubicación de los archivos de clave de bases de datos
- Guardando archivo de clave
Quitar
Rijndael (AES)
Raíz
@@ -314,7 +310,6 @@
Modificable
Compilación %1$s
Si la supresión automática del portapapeles falla, borran el historial manualmente.
- Otorgue permiso de escritura a la tarjeta SD para guardar los cambios en la base de datos.
ATENCIÓN: todas las aplicaciones comparten el portapapeles. Si copia datos confidenciales, otros programas podrían recuperarlos.
No permitir claves maestras
Activar el botón «Abrir» si no se selecciona ninguna credencial
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 7aee88588..ec7b9a50c 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -122,10 +122,6 @@
Datubase berria sortzen…
Lanean…
Babesa
- Duela gutxiko fitxategien historia
- Gogoratu duela gutxi erabili diren fitxategien izenak
- Gogoratu gako fitxategien kokapenak
- Gako fitxategia gorde
Ezabatu
Rijndael (AES)
Root
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 15e8b4a76..0b95273cb 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -121,10 +121,6 @@
Luodaan uutta tietokantaa…
Työskennellään…
Suojaus
- Viimeisten tiedostojen lista
- Muista viimeksi käytettyjen tiedostojen nimet
- Muista avaintiedostojen sijainti
- Tallenna avaintiedosto
Poista
Rijndael (AES)
Juuri
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 9d7481d1e..f1c8e02ab 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -132,10 +132,6 @@
Protection
Protégé en écriture
Selon votre gestionnaire de fichiers, KeePassDX peut ne pas être autorisé à écrire dans votre stockage.
- Historique de fichiers récents
- Mémorise les noms des fichiers récents
- Mémorise l’emplacement des fichiers clé des bases de données
- Enregistrer le fichier clé
Supprimer
Racine
Algorithme de chiffrement de la base de données utilisé pour toutes les données.
@@ -167,7 +163,6 @@
Majuscules
Alerte
Éviter les caractères en dehors du format de codage de caractères du fichier de base de données (les caractères non reconnus sont convertis en une même lettre).
- Accorder l’accès en écriture à la mémoire pour enregistrer les modifications de la base de données.
Monter la carte mémoire pour créer ou charger une base de données.
Ne voulez-vous vraiment aucune protection de déverrouillage par mot de passe \?
Êtes-vous sûr de ne vouloir utiliser aucune clé de chiffrement \?
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 7b219b5da..afade3eb4 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -123,10 +123,6 @@
Védelem
Írásvédett
A KeePassDX-nek írási engedélyre van szüksége, hogy bármit is módosíthasson az adatbázisban.
- Előző fájlok előzményei
- Az előző fájlnevek megjegyzése
- Megjegyzi az adatbázis-kulcsfájlok helyét
- Kulcsfájl mentése
Eltávolítás
Rijndael (AES)
Gyökérkönyvár
@@ -212,7 +208,6 @@
Létrehozás
Módosítás
Hozzáférés
- SD kártya írási jogosultság megadása az adatbázis-változások mentéséhez.
Biztos, hogy nem akar jelszavas feloldási védelmet\?
Biztos, hogy nem akar semmilyen titkosítási kulcsot használni\?
Összeállítás: %1$s
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 6b04c912c..a3fd72d1c 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -123,10 +123,6 @@
Protezione
Sola lettura
KeePassDX richiede l\'autorizzazione di scrittura per poter modificare il tuo database.
- Cronologia file recenti
- Ricorda i file recenti
- Ricorda la posizione dei file chiave dei database
- Salva il file chiave
Elimina
Root
Livello cifratura
@@ -143,7 +139,6 @@
Maiuscole
Attenzione
Evita password con caratteri al di fuori del formato di codifica del testo nel file di database (i caratteri non riconosciuti vengono convertiti nella stessa lettera).
- Permetti l\'accesso in scrittura alla scheda SD per salvare le modifiche al database.
Monta la scheda SD per creare o caricare un database.
Versione %1$s
La scansione di impronte è supportata ma non impostata.
diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml
index 837f7e2a1..8cfc5413a 100644
--- a/app/src/main/res/values-iw/strings.xml
+++ b/app/src/main/res/values-iw/strings.xml
@@ -119,10 +119,6 @@
עובד…
הגנה
ל-KeePassDX אין הרשאות כתיבה למסד הנתונים הזה, ולכן הוא יפתח לקריאה בלבד.
- היסטוריית קובץ אחרונה
- שמור קבצים שהיו בשימוש לאחרונה
- זכור מיקום קבצי מפתח
- שמור קובץ מפתח
הסר
סיבובי הצפנה
מספר סיבובי הצפנה גבוה יותר מספר הגה טובה יותר נגד התקפות, אבל יכול להעלות בהרבה את זמן הטעינה והשמירה.
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 675ab7350..098064671 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -109,8 +109,6 @@
\"バックアップ\"と\"ごみ箱\"を検索対象から除外します
データベースファイルを作成中…
実行中…
- 前回使用したキーファイルを次回も表示します
- キーファイルを記憶
消去
Rijndael (AES)
Root
@@ -181,8 +179,6 @@
保護
書き込み保護
KeePassDX は、データベースを変更するために書き込みアクセス許可が必要です。
- 最近使用したファイルの履歴
- 最近使用したファイル名を記憶します
すべてのデータで使用するデータベース暗号化アルゴリズム。
並び順
昇順
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index f4cd4241b..cafb5257d 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -145,10 +145,6 @@
보호
쓰기 보호됨
KeePassDX는 데이터베이스를 수정하기 위해 쓰기 권한이 필요합니다.
- 최근 파일 기록
- 최근 파일 이름 기억하기
- 데이터베이스 키 파일 위치 기억하기
- 키 파일 저장
삭제
루트
데이터베이스 암호화 알고리즘이 모든 데이터에 적용됩니다.
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index a7bb667c7..aa1cb15d2 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -58,10 +58,6 @@
Įspėjimas
Įveskite duomenų bazės failą
Įveskite teigiamą skaičių ilgio lauke
- Naujausių failų istorija
- Atsiminti paskutinius naudotus failų pavadinimus
- Saugoti rakto failą
- Atsimena rakto failų vietą
Pašalinti
Šaknis
Tik skaitymui
diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml
index f40d6a106..7f01bbf3b 100644
--- a/app/src/main/res/values-lv/strings.xml
+++ b/app/src/main/res/values-lv/strings.xml
@@ -101,10 +101,6 @@
Izveido jaunu datu bāzi…
Darbojas…
Aizsardzība
- Nesen atvērtie
- Glabāt atvērto failu nosaukumus
- Atcerēties šo atslēgas faila vietu
- Saglabāt atslēgas failu
Noņemt
Rijndael (AES)
Root
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index 178ffc274..51d3e1e25 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -144,10 +144,6 @@
Beskyttelse
Skrivebeskyttet
KeePassDX har ikke skrivetilgang til din databaseplassering, så den vil bli åpnet skrivebeskyttet.
- Nylig filhistorikk
- Husk nylig brukte filnavn
- Husk nøkkelfilers plassering
- Lagre nøkkelfil
Fjern
Rot
Algoritme for å kryptere hele databasen. (Passord, brukernavn, merknader og all data i databasen er kryptert med valgt algoritme).
@@ -179,7 +175,6 @@
Store bokstaver
Advarsel
Unngå passordtegn utenfor tekstkodingsformat i databasefil (ukjente tegn blir konvertert til samme bokstav).
- SD-kortet ditt er i øyeblikket skrivebeskyttet. Det kan hende du ikke kan lagre endringer i databasen din.
SD-kortet ditt er ikke montert på enheten din. Du vil ikke kunne laste inne eller opprette din database.
Ønsker du virkelig å bruke en tom streng som ditt passord?
Er du sikker på at du ønsker å bruke en krypteringsnøkkel?
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 38bfaa7d7..4f91d3856 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -111,8 +111,6 @@
Hiermee worden groepen \"Back-up\" en \"Prullenbak\" uit de zoekresultaten weggelaten
Bezig met creëren van nieuwe databank…
Bezig met verwerken…
- Locatie van databank-sleutelbestanden onthouden
- Sleutelbestand opslaan
Verwijderen
Rijndael (AES)
Hoofdmap
@@ -128,7 +126,6 @@
Onderstrepen
Niet-ondersteunde databankversie.
Hoofdletters
- Machtig schrijftoegang om de databankwijzigingen op ge slaan.
Koppel de SD-kaart aan om een databank te creëren of laden.
Versie %1$s
Geef het wachtwoord en/of sleutelbestand op om je databank te ontgrendelen.
@@ -185,8 +182,8 @@
Beveiliging
Alleen-lezen
KeePassDX moet worden gemachtigd om je databank te kunnen aanpassen.
- Recente bestandgeschiedenis
- Recent gebruikte bestandsnamen onthouden
+ Recente bestandgeschiedenis
+ Recent gebruikte bestandsnamen onthouden
Het algoritme dat moet worden gebruikt om de gehele databank te versleutelen.
Om de sleutel voor het algoritme te kunnen genereren, wordt de hoofdsleutel getransformeerd middels een willekeurige afleidingsfunctie.
Geheugengebruik
diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml
index 9e0372953..5d01de553 100644
--- a/app/src/main/res/values-nn/strings.xml
+++ b/app/src/main/res/values-nn/strings.xml
@@ -110,8 +110,6 @@
Søkjeresultatet inneheld ikkje oppføringar frå \'Backup\' eller søppelbøtta
Lager ny database …
Arbeider …
- Hugsar staden til nøkkelfilene
- Lagra nøkkelfila
Ta vekk
Rijndael (AES)
Rot
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 01245c1e8..d770e20b6 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -108,10 +108,6 @@
Pomija grupy „Kopia zapasowa” i „Kosz” w wynikach wyszukiwania
Tworzenie nowej bazy danych…
Pracuję…
- Najnowsza historia plików
- Zapamiętaj najnowsze nazwy plików
- Zapamiętuje lokalizację plików kluczy baz danych
- Zapisz plik klucza
Usuń
Rijndael (AES)
Root
@@ -127,7 +123,6 @@
Podkreślenie
Nieobsługiwana wersja bazy danych.
Wielkie litery
- Przydziel dostęp do zapisu na karcie SD, aby zapisać zmiany w bazie danych.
Zamontuj kartę SD, aby utworzyć lub załadować bazę danych.
prowadź hasło i/lub plik klucza, aby odblokować bazę danych.
\n
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 63e7dc803..983dea3e1 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -109,8 +109,6 @@
Omite os grupos \"Backup\" e \"Lixeira\" dos resultados da busca
Criando novo banco de dados…
Trabalhando…
- Lembra o local dos arquivos-chave dos bancos de dados
- Salvar arquivo de chave
Remover
Rijndael (AES)
Raiz
@@ -177,8 +175,8 @@
Proteção
Apenas leitura
KeePassDX precisa de permissões de escrita para poder mudar qualquer coisa no seu banco.
- Histórico de arquivos recentes
- Lembrar nomes recentes de arquivos
+ Histórico de arquivos recentes
+ Lembrar nomes recentes de arquivos
Algoritmo de encriptação usado para todos os dados.
Para gerar uma chave para o algoritmo de encriptação, a chave mestre é transformada usando uma função de derivação de chave.
Uso de memória
@@ -321,7 +319,6 @@
Pacote de ícones
Pacote de ícones usado no aplicativo
Editar entrada
- Conceda acesso de escrita ao cartão SD para salvar alterações do banco.
Falha ao carregar o banco.
Não pôde carregar a chave. Tente diminuir o \"Uso de Memória\" do KDF.
Mostrar nomes de usuário
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index be8ebc0a5..0b3f9f044 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -124,10 +124,6 @@
Proteção
Apenas leitura
KeePassDX precisa de permissões de escrita para poder mudar qualquer coisa no seu banco.
- Histórico de ficheiros recentes
- Lembrar nomes recentes de ficheiros
- Lembra o local dos ficheiros-chave dos bancos de dados
- Guardar ficheiro chave
Remover
Rijndael (AES)
Raiz
@@ -221,7 +217,6 @@
Deslize para o lado para limpar agora a área de transferência
Não pôde ser habilitado o serviço de preenchimento automático.
Algoritmo de encriptação usado para todos os dados.
- Conceda acesso de escrita ao cartão SD para salvar alterações do banco.
Define o tamanho padrão para palavras-passe geradas
Caracteres da palavra-passe
Definir os caracteres padrão do gerador de palavra-passe
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 00c9f4c48..75b79355e 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -123,10 +123,6 @@
Защита
Только чтение
KeePassDX необходимо разрешение на запись, чтобы иметь возможность изменить что-либо в вашей базе.
- Базы паролей
- Хранить имена недавно открытых баз
- Хранить пути к файлам ключей
- Файлы ключей
Убрать из списка
Rijndael (AES)
База
@@ -145,7 +141,6 @@
ЗАГЛАВНЫЕ
Внимание
Избегайте использования в пароле символов вне кодировки текста в файле базы, так как эти символы будут преобразованы в одинаковый символ.
- Предоставьте доступ к хранилищу на запись для сохранения изменений в базе.
Подключите хранилище для создания или загрузки базы.
Версия %1$s
Биометрия поддерживается, но не настроена.
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 2098b18bc..c55817e06 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -109,8 +109,6 @@
Vynechať skupinu \'Backup\' a Recycle Bin z výsledkov hľadania
Vytváram novú databázu…
Pracujem…
- Zapamätať si umiestnenie keyfile
- Uložiť keyfile
Odstrániť
Rijndael (AES)
Root
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index d7d73bec9..b11fb95ad 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -121,8 +121,6 @@
Skapar ny databas…
Arbetar…
Skydd
- Kommer ihåg sökvägar till databasers nyckelfiler
- Spara nyckelfil
Ta bort
Rijndael (AES)
Root
@@ -192,8 +190,6 @@
Formulär-ifyllning
Skrivskyddad
KeePass DX behöver skrivbehörighet för att ändra något i din databas.
- Senaste filhistorik
- Kom ihåg senaste filnamn
Krypteringsalgoritm som används för all data i databasen.
För att generera nyckeln till krypteringsalgoritmen kommer huvudnyckeln transformeras med en slumpmässigt saltad nyckelderivatsfunktion.
Minnesanvändning
@@ -211,7 +207,6 @@
Åtkomst
Varning
Undvik lösenordstecken utöver textkodningsformatet i databasfilen (okända tecken konverteras till samma bokstav).
- Ge tillåtelse att skriva till SD-kortet för att spara ändringar i databasen.
Är du säker på att du verkligen inte vill skydda dina lösenord från att låsas upp\?
Är du säker på att du inte vill använda en krypteringsnyckel\?
Krypterat lösenord sparat
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 49d0d77ac..1e6dd0ebf 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -144,10 +144,6 @@
Koruma
Yazma korumalı
Veritabanınızdaki herhangi bir şeyi değiştirmek için KeePassDX\'in yazma iznine ihtiyacı var.
- Son dosya geçmişi
- Son dosya adlarını hatırla
- Veritabanı anahtar dosyaların yerini hatırlar
- Anahtar dosya kaydet
Kaldır
Kök
Tüm veriler için veritabanı şifreleme algoritması kullanılmıştır.
@@ -180,7 +176,6 @@
Büyük harf
Uyarı
Veritabanı dosyasındaki metin kodlama formatının dışındaki parola karakterlerinden kaçının (tanınmayan karakterler benzer harfe dönüştürülür).
- Veritabanı değişikliklerini kaydetmek için bellek yazma erişimi verin.
Bir veritabanı oluşturmak veya yüklemek için hafıza kartını takın.
Gerçekten parolasız açma koruması mı istiyorsunuz\?
Herhangi bir şifreleme anahtarı kullanmak istemediğinize emin misiniz\?
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 78ed3eae0..aee10cdbc 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -110,8 +110,6 @@
Пропустити групу \'Резервна копія\' та Кошик серед результатів пошуку
Створення нової бази даних…
Працює…
- Запам’ятати розташування файла ключа
- Збережіть файл ключа
Вилучити
Rijndael (AES)
Корінь
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index ba40e9286..efd63fc1e 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -106,8 +106,6 @@
最近使用过的数据库
正在创建新数据库…
正在处理…
- 记住密钥文件的位置
- 保存密钥文件
移除
Rijndael (AES)
Root
@@ -123,7 +121,6 @@
下划线
不支持的数据库版本。
大写
- 请授予 SD 卡写入权限以保存数据库。
请挂载SD卡以创建或加载数据库。
输入密码和/或一个密钥文件来解锁你的数据库。
\n
@@ -184,8 +181,8 @@
保护
只读
KeePassDX 需要写入权限以修改数据库。
- 最近文件历史
- 记住最近使用的文件名
+ 最近文件历史
+ 记住最近使用的文件名
加密所有数据时采用的算法。
将转换主密钥以生成加密数据库所需的密钥,转换方式为随机加盐算法。
内存使用量
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index d4e5287ce..0bbfaeb4a 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -106,8 +106,6 @@
最近打開的資料庫:
創建新資料庫中…
工作中…
- 記住密鑰檔的位置
- 保存密鑰檔
移除
Rijndael加密(AES)
Root
@@ -206,8 +204,6 @@
欄位值
找不到檔案。嘗試從檔案瀏覽器重新打開它。
從搜尋結果中省略\"備份\"和\"回收站\"組
- 最近的檔案歷史記錄
- 記住最近的檔案名
用於所有資料的資料庫加密演算法。
記憶體使用情況
密钥推導函數要使用的記憶體量(以二进制字节为单位)。
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index 9fef12e93..59c422441 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -83,10 +83,14 @@
true
allow_copy_password_key
false
- recentfile
- true
- keyfile
- true
+ remember_database_locations_key
+ true
+ show_recent_files_key
+ true
+ hide_broken_locations_key
+ true
+ remember_keyfile_locations_key
+ true
advanced_unlock_explanation_key
biometric_unlock_enable_key
false
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 715309950..fe7815e98 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -203,10 +203,14 @@
The database contains duplicate UUIDs.
By validating this dialog, KeePassDX will fix the problem (by generating new UUIDs for duplicates) and continue.
Selection mode
- Recent file history
- Remember recent filenames
- Remembers the location of databases keyfiles
- Save keyfile
+ Save location of databases
+ Remember the location of databases
+ Show recent files
+ Show locations of recent databases
+ Hide broken database links
+ Hide broken links in the list of recent databases
+ Save location of keyfiles
+ Remember the location of databases keyfiles
Root
Database encryption algorithm used for all data.
To generate the key for the encryption algorithm, the master key is transformed using a randomly salted key derivation function.
@@ -240,7 +244,7 @@
Upper-case
Warning
Avoid password characters outside of text encoding format in database file (unrecognized chars are converted to the same letter).
- Grant memory write access to save database changes.
+ Grant file write access to save database changes
Mount the memory card to create or load a database.
Do you really want no password unlocking protection?
Are you sure you do not want to use any encryption key?
diff --git a/app/src/main/res/xml/preferences_application.xml b/app/src/main/res/xml/preferences_application.xml
index 59c8ef1ec..1c779f2df 100644
--- a/app/src/main/res/xml/preferences_application.xml
+++ b/app/src/main/res/xml/preferences_application.xml
@@ -121,16 +121,28 @@
android:title="@string/database_history">
+ android:key="@string/remember_database_locations_key"
+ android:title="@string/remember_database_locations_title"
+ android:summary="@string/remember_database_locations_summary"
+ android:defaultValue="@bool/remember_database_locations_default"/>
+ android:key="@string/show_recent_files_key"
+ android:title="@string/show_recent_files_title"
+ android:summary="@string/show_recent_files_summary"
+ android:dependency="@string/remember_database_locations_key"
+ android:defaultValue="@bool/show_recent_files_default"/>
+
+