Compare commits

..

39 Commits

Author SHA1 Message Date
J-Jamet
a846ec29ca Merge branch 'release/2.5beta28' 2020-03-10 18:59:59 +01:00
J-Jamet
4533e96bff Upgrade CHANGELOG 2020-03-10 18:48:57 +01:00
J-Jamet
0a401c3ac9 Fix strings 2020-03-10 18:41:35 +01:00
J-Jamet
468abaf077 Fix strings 2020-03-10 18:29:19 +01:00
J-Jamet
4ccf2f641c Merge branch 'master' of https://hosted.weblate.org/projects/keepass-dx/strings into develop 2020-03-10 18:14:14 +01:00
Dominik Baláž
34eb2785cf Translated using Weblate (Slovak)
Currently translated at 21.5% (92 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sk/
2020-03-10 17:21:26 +01:00
anonymous
09dbfe323e Translated using Weblate (Slovak)
Currently translated at 21.5% (92 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/sk/
2020-03-10 17:21:26 +01:00
Destiny Li
1f06c5b425 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-03-10 11:33:21 +01:00
Destiny Li
b98e089f7a Translated using Weblate (Chinese (Traditional))
Currently translated at 48.3% (206 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hant/
2020-03-10 11:33:20 +01:00
Aurel F
a0ad06ed0a Translated using Weblate (Romanian)
Currently translated at 40.8% (174 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2020-03-10 11:33:18 +01:00
solokot
ec63365429 Translated using Weblate (Russian)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-10 11:33:10 +01:00
J-Jamet
2cb85e4346 Update items after appearance change #452 2020-03-10 08:58:22 +01:00
J-Jamet
0d7c479c51 Merge branch 'feature/Migration_SDK_29' into develop 2020-03-10 08:40:53 +01:00
J-Jamet
5a6c21e662 Try to fix read only bug #480 2020-03-10 08:38:49 +01:00
J-Jamet
d6cadac98f Fix small warning 2020-03-08 13:22:11 +01:00
J-Jamet
dac2fc2c37 Use PreferenceManager from AndroidX 2020-03-08 13:10:16 +01:00
J-Jamet
0fb45cef0d Encapsulate preferences 2020-03-08 13:04:25 +01:00
anonymous
5ebdbd4003 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-03-08 12:08:21 +01:00
Destiny Li
b30f1023cb Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/zh_Hans/
2020-03-08 12:08:21 +01:00
J-Jamet
e5f65a4d1e Fix % issue in string 2020-03-08 11:48:47 +01:00
J-Jamet
ab42a65aa4 Fix null issues 2020-03-08 11:41:13 +01:00
J-Jamet
e351456bfe First pass migration SDK 29 2020-03-08 11:03:21 +01:00
J-Jamet
452e68b08f Fix C cast warning 2020-03-08 10:52:29 +01:00
J-Jamet
d65beed7a1 Fix small warnings 2020-03-08 10:49:06 +01:00
J-Jamet
f5a5a0e8cb Add generated JSON for database 2020-03-08 10:41:52 +01:00
solokot
98380a0906 Translated using Weblate (Russian)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-08 10:20:37 +01:00
J-Jamet
22fe7508f3 Fix doForEachChild warning 2020-03-08 10:16:31 +01:00
J-Jamet
c8e241fc76 Fix Room incremental warning 2020-03-08 09:50:32 +01:00
J-Jamet
2c943e00d0 Fix writeEnum warning 2020-03-08 09:50:07 +01:00
J-Jamet
7ddb83b72d Fix DateFormatter warning 2020-03-08 09:36:45 +01:00
Kunzisoft
50bac01699 Translated using Weblate (French)
Currently translated at 99.7% (425 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/fr/
2020-03-08 09:33:23 +01:00
Aurel F
e0a92dfadd Translated using Weblate (Romanian)
Currently translated at 12.2% (52 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ro/
2020-03-08 09:33:22 +01:00
solokot
b50c951091 Translated using Weblate (Russian)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/ru/
2020-03-08 09:33:17 +01:00
Kunzisoft
2f589a95a9 Translated using Weblate (English)
Currently translated at 100.0% (426 of 426 strings)

Translation: KeePass DX/Strings
Translate-URL: https://hosted.weblate.org/projects/keepass-dx/strings/en/
2020-03-08 09:33:15 +01:00
J-Jamet
53eac86a95 Update AndroidX dependencies and fix small warning 2020-03-08 09:17:18 +01:00
J-Jamet
9412f8955e Update kotlin to 1.3.61 2020-03-08 09:07:14 +01:00
J-Jamet
71c98d82b1 Update gradle to 5.6.4 2020-03-08 09:00:56 +01:00
J-Jamet
42c1a925b4 Upgrade app to 2.54beta28 2020-03-08 08:59:41 +01:00
J-Jamet
1e84534ffd Merge tag '2.5beta27' into develop
2.5beta27
2020-03-07 14:41:37 +01:00
55 changed files with 689 additions and 267 deletions

View File

@@ -1,4 +1,8 @@
KeepassDX (2.5beta27)
KeePassDX(2.5beta28)
* Fix read only database
* Upgrade to Android SDK 29
KeePassDX (2.5beta27)
* New setting to hide broken links
* Show URL when title is empty
* Setting to open search field at database opening
@@ -7,7 +11,7 @@ KeepassDX (2.5beta27)
* Fix appearance refresh settings
* Sort optimization
KeepassDX (2.5.0.0beta26)
KeePassDX (2.5.0.0beta26)
* Download attachments
* Change file size string format
* Prevent screenshot for all screen
@@ -20,7 +24,7 @@ KeepassDX (2.5.0.0beta26)
* Fix dates
* Fix UUID message for Database v1
KeepassDX (2.5.0.0beta25)
KeePassDX (2.5.0.0beta25)
* Setting for Recycle Bin
* Fix Recycle bin issues
* Fix TOTP
@@ -28,7 +32,7 @@ KeepassDX (2.5.0.0beta25)
* Fix update group
* Fix OOM
KeepassDX (2.5.0.0beta24)
KeePassDX (2.5.0.0beta24)
* Add OTP (HOTP / TOTP)
* Add settings (Color, Security, Master Key)
* Show history of each entry
@@ -38,7 +42,7 @@ KeepassDX (2.5.0.0beta24)
* Open/Save database as service / Add persistent notification
* Fix settings / edit group / small bugs
KeepassDX (2.5.0.0beta23)
KeePassDX (2.5.0.0beta23)
* New, more secure database creation workflow
* Recognize more database files
* Add alias for history files (WARNING: history is erased)
@@ -47,14 +51,14 @@ KeepassDX (2.5.0.0beta23)
* Fix OOM with KeyFile
* Fix small issues
KeepassDX (2.5.0.0beta22)
KeePassDX (2.5.0.0beta22)
* Rebuild code for actions
* Add UUID as entry view
* Fix bug with natural order
* Fix number of entries in databaseV1
* New entry views
KeepassDX (2.5.0.0beta21)
KeePassDX (2.5.0.0beta21)
* Fix nested groups no longer visible in V1 databases
* Improved data import algorithm for V1 databases
* Add natural database sort
@@ -62,10 +66,10 @@ KeepassDX (2.5.0.0beta21)
* Fix button disabled with only KeyFile
* Show the number of entries in a group
KeepassDX (2.5.0.0beta20)
KeePassDX (2.5.0.0beta20)
* Fix a major bug that displays an entry history
KeepassDX (2.5.0.0beta19)
KeePassDX (2.5.0.0beta19)
* Add lock button always visible
* New connection workflow
* Code refactored in Kotlin
@@ -76,7 +80,7 @@ KeepassDX (2.5.0.0beta19)
* Fix memory when load database
* Fix small bugs
KeepassDX (2.5.0.0beta18)
KeePassDX (2.5.0.0beta18)
* New recent databases views
* New information dialog
* Custom fields for the Magikeyboard
@@ -85,10 +89,10 @@ KeepassDX (2.5.0.0beta18)
* Fix memory when opening the database
* Memory management for attachments
KeepassDX (2.5.0.0beta17)
KeePassDX (2.5.0.0beta17)
* Fix font and search
KeepassDX (2.5.0.0beta16)
KeePassDX (2.5.0.0beta16)
* New search in a single fragment
* Search suggestions
* Added the display of usernames
@@ -96,20 +100,20 @@ KeepassDX (2.5.0.0beta16)
* Fix read-only mode
* Fix parcelable / toolbar / back
KeepassDX (2.5.0.0beta15)
KeePassDX (2.5.0.0beta15)
* Read only mode
* Best group recovery for the navigation fragment
* Fix copies in notifications
* Fix orientation
* Added translations
KeepassDX (2.5.0.0beta14)
KeePassDX (2.5.0.0beta14)
* Optimize all the memory with parcelables / fix search
KeepassDX (2.5.0.0beta13)
KeePassDX (2.5.0.0beta13)
* Fix memory issue with parcelable (crash in beta12 version)
KeepassDX (2.5.0.0beta12)
KeePassDX (2.5.0.0beta12)
* Added the Magikeyboard to fill the forms (settings still in development)
* Added move and copy for groups and entries
* New navigation in a single screen / new animations between activities
@@ -122,10 +126,10 @@ KeepassDX (2.5.0.0beta12)
* Fix the fingerprint recognition (WARNING : The keystore is reinit, you must delete the old keys)
* Fix small bugs
KeepassDX (2.5.0.0beta11)
KeePassDX (2.5.0.0beta11)
* Fix crash in beta10 version
KeepassDX (2.5.0.0beta10)
KeePassDX (2.5.0.0beta10)
* Dynamically change Algorithm and Key Derivation Function in settings
* Upgrade translations
* New red volcano theme, fix classic dark theme
@@ -133,7 +137,7 @@ KeepassDX (2.5.0.0beta10)
* Update fingerprint state with checkbox
* Fix bugs
KeepassDX (2.5.0.0beta9)
KeePassDX (2.5.0.0beta9)
* Education Screens to learn how to use the app
* New designs
* New custom font for character visibility
@@ -142,9 +146,9 @@ KeepassDX (2.5.0.0beta9)
* Change setting organisation
* Pro version
KeepassDX (2.5.0.0beta8)
KeePassDX (2.5.0.0beta8)
* Hide custom entries protected
* Best management of field references (https://keepass.info/help/base/fieldrefs.html)
* Best management of field references (https://KeePass.info/help/base/fieldrefs.html)
* Change database / default settings
* Add Autofill for search
* Add sorting by last access and by creation time
@@ -152,7 +156,7 @@ KeepassDX (2.5.0.0beta8)
* Refactor old code
* Fix bugs
KeepassDX (2.5.0.0beta7)
KeePassDX (2.5.0.0beta7)
* Rebuild Notifications
* Change links to https
* Add extended Ascii (ñæËÌÂÝÜ...)
@@ -161,10 +165,10 @@ KeepassDX (2.5.0.0beta7)
* Add setting to prevent the password copy
* Fix bugs
KeepassDX (2.5.0.0beta6)
KeePassDX (2.5.0.0beta6)
* Fix crash
KeepassDX (2.5.0.0beta5)
KeePassDX (2.5.0.0beta5)
* Autofill (Android O)
* Deletion for group
* New sorts with (Asc/Dsc, Groups before or after)
@@ -185,7 +189,7 @@ KeepassDX (2.5.0.0beta5)
* Fix many small bugs
* Add recycle bin setting (not yet accessible)
KeepassDX (2.5.0.0beta4)
KeePassDX (2.5.0.0beta4)
* Show only file name
* Setting for full path
* Add information for each database file
@@ -194,7 +198,7 @@ KeepassDX (2.5.0.0beta4)
* Delete view assignment for fingerprint opening
* Merge KeePassDroid 2.2.1
KeepassDX (2.5.0.0beta3)
KeePassDX (2.5.0.0beta3)
* New database workflow with new screens and folder selection
* Settings for default password generation
* Fingerprint dialog for explanations
@@ -205,17 +209,17 @@ KeepassDX (2.5.0.0beta3)
* Merge KeePassDroid 2.2.0.9
* Add corruption fix mode
KeepassDX (2.5.0.0beta2)
KeePassDX (2.5.0.0beta2)
* Remove libs for F-Droid
KeepassDX (2.5.0.0beta1)
* Fork KeepassDroid
KeePassDX (2.5.0.0beta1)
* Fork KeePassDroid
* Add Material Design
* Add Light and Night theme
* Min API is 14
* Solve bug for fingerprint
* Update French translation
* Change donation (see KeepassDroid to contribute on both projects)
* Change donation (see KeePassDroid to contribute on both projects)
KeePassDroid (2.2.1)
* Fix kdbx4 date corruption
@@ -476,7 +480,7 @@ KeePassDroid (1.9.10)
KeePassDroid (1.9.9)
* Go back to explicitly storing blank fields in the database
(works around bug in keepassx)
(works around bug in KeePassx)
* Add support for native code on MIPS architectures
* Adding Vibrate permission. On some devices notifications fail
without the vibrate permission.

View File

@@ -4,21 +4,28 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
compileSdkVersion 29
buildToolsVersion '29.0.3'
defaultConfig {
applicationId "com.kunzisoft.keepass"
minSdkVersion 14
targetSdkVersion 28
versionCode = 27
versionName = "2.5beta27"
targetSdkVersion 29
versionCode = 28
versionName = "2.5beta28"
multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests"
testInstrumentationRunner = "android.test.InstrumentationTestRunner"
buildConfigField "String[]", "ICON_PACKS", "{\"classic\",\"material\"}"
kapt {
arguments {
arg("room.incremental", "true")
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
}
}
externalNativeBuild {
@@ -79,7 +86,7 @@ android {
}
def spongycastleVersion = "1.58.0.0"
def room_version = "2.2.1"
def room_version = "2.2.4"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
@@ -88,7 +95,9 @@ dependencies {
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.biometric:biometric:1.0.0'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.biometric:biometric:1.0.1'
// To upgrade with style
implementation 'com.google.android.material:material:1.0.0'
implementation "androidx.room:room-runtime:$room_version"

View File

@@ -0,0 +1,84 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "56438e5f7372ef3e36e33b782aed245d",
"entities": [
{
"tableName": "file_database_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`database_uri` TEXT NOT NULL, `database_alias` TEXT NOT NULL, `keyfile_uri` TEXT, `updated` INTEGER NOT NULL, PRIMARY KEY(`database_uri`))",
"fields": [
{
"fieldPath": "databaseUri",
"columnName": "database_uri",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "databaseAlias",
"columnName": "database_alias",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "keyFileUri",
"columnName": "keyfile_uri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "updated",
"columnName": "updated",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"database_uri"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "cipher_database",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`database_uri` TEXT NOT NULL, `encrypted_value` TEXT NOT NULL, `specs_parameters` TEXT NOT NULL, PRIMARY KEY(`database_uri`))",
"fields": [
{
"fieldPath": "databaseUri",
"columnName": "database_uri",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encryptedValue",
"columnName": "encrypted_value",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "specParameters",
"columnName": "specs_parameters",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"database_uri"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '56438e5f7372ef3e36e33b782aed245d')"
]
}
}

View File

@@ -150,9 +150,11 @@ class EntryActivity : LockingActivity() {
// Get Entry from UUID
try {
val keyEntry: NodeId<UUID> = intent.getParcelableExtra(KEY_ENTRY)
val keyEntry: NodeId<UUID>? = intent.getParcelableExtra(KEY_ENTRY)
if (keyEntry != null) {
mEntry = mDatabase?.getEntryById(keyEntry)
mEntryLastVersion = mEntry
}
} catch (e: ClassCastException) {
Log.e(TAG, "Unable to retrieve the entry key")
}

View File

@@ -28,7 +28,6 @@ import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.preference.PreferenceManager
import android.util.Log
import android.view.Menu
import android.view.MenuItem
@@ -142,8 +141,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
if (!(savedInstanceState != null
&& savedInstanceState.containsKey(EXTRA_STAY)
&& savedInstanceState.getBoolean(EXTRA_STAY, false))) {
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val databasePath = prefs.getString(PasswordActivity.KEY_DEFAULT_DATABASE_PATH, "")
val databasePath = PreferencesUtil.getDefaultDatabasePath(this)
UriUtil.parse(databasePath)?.let { databaseFileUri ->
launchPasswordActivityWithPath(databaseFileUri)

View File

@@ -346,7 +346,8 @@ class GroupActivity : LockingActivity(),
// If it's a search
if (Intent.ACTION_SEARCH == intent.action) {
return mDatabase?.search(intent.getStringExtra(SearchManager.QUERY).trim { it <= ' ' })
val searchString = intent.getStringExtra(SearchManager.QUERY)?.trim { it <= ' ' } ?: ""
return mDatabase?.search(searchString)
}
// else a real group
else {
@@ -859,8 +860,8 @@ class GroupActivity : LockingActivity(),
.iconPicked(bundle)
}
override fun onSortSelected(sortNodeEnum: SortNodeEnum, ascending: Boolean, groupsBefore: Boolean, recycleBinBottom: Boolean) {
mListNodesFragment?.onSortSelected(sortNodeEnum, ascending, groupsBefore, recycleBinBottom)
override fun onSortSelected(sortNodeEnum: SortNodeEnum, sortNodeParameters: SortNodeEnum.SortNodeParameters) {
mListNodesFragment?.onSortSelected(sortNodeEnum, sortNodeParameters)
}
override fun startActivity(intent: Intent) {

View File

@@ -21,9 +21,7 @@ package com.kunzisoft.keepass.activities
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.util.Log
@@ -69,8 +67,6 @@ class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionLis
private var notFoundView: View? = null
private var isASearchResult: Boolean = false
// Preferences for sorting
private var prefs: SharedPreferences? = null
private var readOnly: Boolean = false
get() {
@@ -155,7 +151,6 @@ class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionLis
})
}
}
prefs = PreferenceManager.getDefaultSharedPreferences(context)
}
override fun onSaveInstanceState(outState: Bundle) {
@@ -213,26 +208,26 @@ class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionLis
fun rebuildList() {
// Add elements to the list
mainGroup?.let { mainGroup ->
mAdapter?.rebuildList(mainGroup)
mAdapter?.apply {
rebuildList(mainGroup)
// To visually change the elements
if (PreferencesUtil.APPEARANCE_CHANGED) {
notifyDataSetChanged()
PreferencesUtil.APPEARANCE_CHANGED = false
}
}
}
}
override fun onSortSelected(sortNodeEnum: SortNodeEnum,
ascending: Boolean,
groupsBefore: Boolean,
recycleBinBottom: Boolean) {
// Toggle setting
prefs?.edit()?.apply {
putString(getString(R.string.sort_node_key), sortNodeEnum.name)
putBoolean(getString(R.string.sort_ascending_key), ascending)
putBoolean(getString(R.string.sort_group_before_key), groupsBefore)
putBoolean(getString(R.string.sort_recycle_bin_bottom_key), recycleBinBottom)
apply()
sortNodeParameters: SortNodeEnum.SortNodeParameters) {
// Save setting
context?.let {
PreferencesUtil.saveNodeSort(it, sortNodeEnum, sortNodeParameters)
}
// Tell the adapter to refresh it's list
mAdapter?.notifyChangeSort(sortNodeEnum,
SortNodeEnum.SortNodeParameters(ascending, groupsBefore, recycleBinBottom))
mAdapter?.notifyChangeSort(sortNodeEnum, sortNodeParameters)
rebuildList()
}

View File

@@ -23,12 +23,10 @@ import android.app.Activity
import android.app.assist.AssistStructure
import android.app.backup.BackupManager
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.preference.PreferenceManager
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
@@ -91,8 +89,6 @@ open class PasswordActivity : StylishActivity() {
private var mDatabaseFileUri: Uri? = null
private var mDatabaseKeyFileUri: Uri? = null
private var mSharedPreferences: SharedPreferences? = null
private var mRememberKeyFile: Boolean = false
private var mOpenFileHelper: OpenFileHelper? = null
@@ -115,8 +111,6 @@ open class PasswordActivity : StylishActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
setContentView(R.layout.activity_password)
@@ -309,7 +303,7 @@ open class PasswordActivity : StylishActivity() {
keyFileUri = intent.getParcelableExtra(KEY_KEYFILE)
}
mForceReadOnly = UriUtil.isUriNotWritable(contentResolver, databaseUri)
mForceReadOnly = !UriUtil.isUriWritable(contentResolver, databaseUri)
// Post init uri with KeyFile if needed
if (mRememberKeyFile && (keyFileUri == null || keyFileUri.toString().isEmpty())) {
@@ -344,19 +338,12 @@ open class PasswordActivity : StylishActivity() {
// Define listeners for default database checkbox and validate button
checkboxDefaultDatabaseView?.setOnCheckedChangeListener { _, isChecked ->
var newDefaultFileName: Uri? = null
var newDefaultFileUri: Uri? = null
if (isChecked) {
newDefaultFileName = databaseFileUri ?: newDefaultFileName
newDefaultFileUri = databaseFileUri ?: newDefaultFileUri
}
mSharedPreferences?.edit()?.apply {
newDefaultFileName?.let {
putString(KEY_DEFAULT_DATABASE_PATH, newDefaultFileName.toString())
} ?: kotlin.run {
remove(KEY_DEFAULT_DATABASE_PATH)
}
apply()
}
PreferencesUtil.saveDefaultDatabasePath(this, newDefaultFileUri)
val backupManager = BackupManager(this@PasswordActivity)
backupManager.dataChanged()
@@ -364,7 +351,7 @@ open class PasswordActivity : StylishActivity() {
confirmButtonView?.setOnClickListener { verifyCheckboxesAndLoadDatabase() }
// Retrieve settings for default database
val defaultFilename = mSharedPreferences?.getString(KEY_DEFAULT_DATABASE_PATH, "")
val defaultFilename = PreferencesUtil.getDefaultDatabasePath(this)
if (databaseFileUri != null
&& databaseFileUri.path != null && databaseFileUri.path!!.isNotEmpty()
&& databaseFileUri == UriUtil.parse(defaultFilename)) {
@@ -703,8 +690,6 @@ open class PasswordActivity : StylishActivity() {
private val TAG = PasswordActivity::class.java.name
const val KEY_DEFAULT_DATABASE_PATH = "KEY_DEFAULT_DATABASE_PATH"
private const val KEY_FILENAME = "fileName"
private const val KEY_KEYFILE = "keyFile"
private const val VIEW_INTENT = "android.intent.action.VIEW"

View File

@@ -112,7 +112,7 @@ class IconPickerDialogFragment : DialogFragment() {
// Retrieve the textColor to tint the icon
val ta = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
ImageViewCompat.setImageTintList(iconImageView, ColorStateList.valueOf(ta.getColor(0, Color.BLACK)))
ta?.recycle()
ta.recycle()
}
}

View File

@@ -82,7 +82,9 @@ class SortDialogFragment : DialogFragment() {
builder.setView(rootView)
// Add action buttons
.setPositiveButton(android.R.string.ok
) { _, _ -> mListener?.onSortSelected(mSortNodeEnum, mAscending, mGroupsBefore, mRecycleBinBottom) }
) { _, _ -> mListener?.onSortSelected(mSortNodeEnum,
SortNodeEnum.SortNodeParameters(mAscending, mGroupsBefore, mRecycleBinBottom))
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
val ascendingView = rootView.findViewById<CompoundButton>(R.id.sort_selection_ascending)
@@ -150,10 +152,7 @@ class SortDialogFragment : DialogFragment() {
}
interface SortSelectionListener {
fun onSortSelected(sortNodeEnum: SortNodeEnum,
ascending: Boolean,
groupsBefore: Boolean,
recycleBinBottom: Boolean)
fun onSortSelected(sortNodeEnum: SortNodeEnum, sortNodeParameters: SortNodeEnum.SortNodeParameters)
}
companion object {

View File

@@ -313,8 +313,9 @@ class AdvancedUnlockedManager(var context: FragmentActivity,
}
override fun onBiometricException(e: Exception) {
if (e.localizedMessage != null)
setAdvancedUnlockedMessageView(e.localizedMessage)
e.localizedMessage?.let {
setAdvancedUnlockedMessageView(it)
}
}
private fun showFingerPrintViews(show: Boolean) {

View File

@@ -493,10 +493,11 @@ class Database {
var outputStream: OutputStream? = null
try {
outputStream = contentResolver.openOutputStream(uri)
val pmo =
mDatabaseKDB?.let { DatabaseOutputKDB(it, outputStream) }
?: mDatabaseKDBX?.let { DatabaseOutputKDBX(it, outputStream) }
pmo?.output()
outputStream?.let { definedOutputStream ->
val databaseOutput = mDatabaseKDB?.let { DatabaseOutputKDB(it, definedOutputStream) }
?: mDatabaseKDBX?.let { DatabaseOutputKDBX(it, definedOutputStream) }
databaseOutput?.output()
}
} catch (e: Exception) {
throw IOException(e)
} finally {
@@ -723,7 +724,7 @@ class Database {
fun canRecycle(entry: Entry): Boolean {
var canRecycle: Boolean? = null
entry.entryKDB?.let {
canRecycle = mDatabaseKDB?.canRecycle(it)
canRecycle = mDatabaseKDB?.canRecycle()
}
entry.entryKDBX?.let {
canRecycle = mDatabaseKDBX?.canRecycle(it)
@@ -734,7 +735,7 @@ class Database {
fun canRecycle(group: Group): Boolean {
var canRecycle: Boolean? = null
group.groupKDB?.let {
canRecycle = mDatabaseKDB?.canRecycle(it)
canRecycle = mDatabaseKDB?.canRecycle()
}
group.groupKDBX?.let {
canRecycle = mDatabaseKDBX?.canRecycle(it)

View File

@@ -46,7 +46,7 @@ class DateInstant : Parcelable {
}
constructor(string: String) {
jDate = dateFormat.parse(string)
jDate = dateFormat.parse(string) ?: jDate
}
constructor() {
@@ -121,7 +121,7 @@ class DateInstant : Parcelable {
}
}
private fun isSameDate(d1: Date?, d2: Date?): Boolean {
private fun isSameDate(d1: Date, d2: Date): Boolean {
val cal1 = Calendar.getInstance()
cal1.time = d1
cal1.set(Calendar.MILLISECOND, 0)

View File

@@ -26,17 +26,25 @@ import java.util.UUID
class DeletedObject {
var uuid: UUID = DatabaseVersioned.UUID_ZERO
var deletionTime: Date? = null
get() = if (field == null) {
Date(System.currentTimeMillis())
} else field
private var mDeletionTime: Date? = null
fun getDeletionTime(): Date {
if (mDeletionTime == null) {
mDeletionTime = Date(System.currentTimeMillis())
}
return mDeletionTime!!
}
fun setDeletionTime(deletionTime: Date) {
this.mDeletionTime = deletionTime
}
constructor()
@JvmOverloads
constructor(uuid: UUID, deletionTime: Date = Date()) {
this.uuid = uuid
this.deletionTime = deletionTime
this.mDeletionTime = deletionTime
}
override fun equals(other: Any?): Boolean {

View File

@@ -231,8 +231,9 @@ class DatabaseKDB : DatabaseVersioned<Int, UUID, GroupKDB, EntryKDB>() {
* @param node Node to remove
* @return true if node can be recycle, false elsewhere
*/
fun canRecycle(node: NodeVersioned<*, GroupKDB, EntryKDB>): Boolean {
// TODO #394 Backup pw3
// TODO #394 Backup KDB
// fun canRecycle(node: NodeVersioned<*, GroupKDB, EntryKDB>): Boolean {
fun canRecycle(): Boolean {
return true
}

View File

@@ -40,6 +40,7 @@ interface GroupVersionedInterface<Group: GroupVersionedInterface<Group, Entry>,
fun allowAddEntryIfIsRoot(): Boolean
@Suppress("UNCHECKED_CAST")
fun doForEachChildAndForIt(entryHandler: NodeHandler<Entry>,
groupHandler: NodeHandler<Group>) {
doForEachChild(entryHandler, groupHandler)

View File

@@ -61,7 +61,9 @@ class BinaryAttachment : Parcelable {
val compressedByte = parcel.readByte().toInt()
isCompressed = if (compressedByte == 2) null else compressedByte != 0
isProtected = parcel.readByte().toInt() != 0
dataFile = File(parcel.readString())
parcel.readString()?.let {
dataFile = File(it)
}
}
@Throws(IOException::class)
@@ -74,10 +76,10 @@ class BinaryAttachment : Parcelable {
@Throws(IOException::class)
fun compress(bufferSize: Int = DEFAULT_BUFFER_SIZE) {
if (dataFile != null) {
dataFile?.let { concreteDataFile ->
// To compress, create a new binary with file
if (isCompressed != true) {
val fileBinaryCompress = File(dataFile!!.parent, dataFile!!.name + "_temp")
val fileBinaryCompress = File(concreteDataFile.parent, concreteDataFile.name + "_temp")
var outputStream: GZIPOutputStream? = null
var inputStream: InputStream? = null
try {
@@ -91,8 +93,8 @@ class BinaryAttachment : Parcelable {
outputStream?.close()
// Remove unGzip file
if (dataFile!!.delete()) {
if (fileBinaryCompress.renameTo(dataFile)) {
if (concreteDataFile.delete()) {
if (fileBinaryCompress.renameTo(concreteDataFile)) {
// Harmonize with database compression
isCompressed = true
}
@@ -104,9 +106,9 @@ class BinaryAttachment : Parcelable {
@Throws(IOException::class)
fun decompress(bufferSize: Int = DEFAULT_BUFFER_SIZE) {
if (dataFile != null) {
dataFile?.let { concreteDataFile ->
if (isCompressed != false) {
val fileBinaryDecompress = File(dataFile!!.parent, dataFile!!.name + "_temp")
val fileBinaryDecompress = File(concreteDataFile.parent, concreteDataFile.name + "_temp")
var outputStream: FileOutputStream? = null
var inputStream: GZIPInputStream? = null
try {
@@ -120,8 +122,8 @@ class BinaryAttachment : Parcelable {
outputStream?.close()
// Remove gzip file
if (dataFile!!.delete()) {
if (fileBinaryDecompress.renameTo(dataFile)) {
if (concreteDataFile.delete()) {
if (fileBinaryDecompress.renameTo(concreteDataFile)) {
// Harmonize with database compression
isCompressed = false
}

View File

@@ -127,11 +127,7 @@ object DatabaseKDBXXML {
const val ElemCustomData = "CustomData"
const val ElemStringDictExItem = "Item"
val dateFormatter: ThreadLocal<SimpleDateFormat> = object : ThreadLocal<SimpleDateFormat>() {
override fun initialValue(): SimpleDateFormat {
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
dateFormat.timeZone = TimeZone.getTimeZone("UTC")
return dateFormat
}
val DateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
}

View File

@@ -660,7 +660,7 @@ class DatabaseInputKDBX(cacheDirectory: File,
KdbContext.DeletedObject -> if (name.equals(DatabaseKDBXXML.ElemUuid, ignoreCase = true)) {
ctxDeletedObject?.uuid = readUuid(xpp)
} else if (name.equals(DatabaseKDBXXML.ElemDeletionTime, ignoreCase = true)) {
ctxDeletedObject?.deletionTime = readTime(xpp)
ctxDeletedObject?.setDeletionTime(readTime(xpp))
} else {
readUnknown(xpp)
}
@@ -829,7 +829,7 @@ class DatabaseInputKDBX(cacheDirectory: File,
} else {
try {
utcDate = DatabaseKDBXXML.dateFormatter.get()?.parse(sDate)
utcDate = DatabaseKDBXXML.DateFormatter.parse(sDate)
} catch (e: ParseException) {
// Catch with null test below
}

View File

@@ -384,9 +384,9 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
}
@Throws(IllegalArgumentException::class, IllegalStateException::class, IOException::class)
private fun writeObject(name: String, value: Date?) {
private fun writeObject(name: String, value: Date) {
if (header!!.version < DatabaseHeaderKDBX.FILE_VERSION_32_4) {
writeObject(name, DatabaseKDBXXML.dateFormatter.get().format(value))
writeObject(name, DatabaseKDBXXML.DateFormatter.format(value))
} else {
val dt = DateTime(value)
val seconds = DateKDBXUtil.convertDateToKDBX4Time(dt)
@@ -553,7 +553,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
xml.startTag(null, DatabaseKDBXXML.ElemDeletedObject)
writeUuid(DatabaseKDBXXML.ElemUuid, value.uuid)
writeObject(DatabaseKDBXXML.ElemDeletionTime, value.deletionTime)
writeObject(DatabaseKDBXXML.ElemDeletionTime, value.getDeletionTime())
xml.endTag(null, DatabaseKDBXXML.ElemDeletedObject)
}

View File

@@ -22,8 +22,8 @@ package com.kunzisoft.keepass.education
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.preference.PreferenceManager
import android.util.Log
import androidx.preference.PreferenceManager
import com.getkeepsafe.taptargetview.TapTarget
import com.getkeepsafe.taptargetview.TapTargetView
import com.kunzisoft.keepass.R

View File

@@ -45,7 +45,7 @@ class EntryInfo : Parcelable {
password = parcel.readString() ?: password
url = parcel.readString() ?: url
notes = parcel.readString() ?: notes
parcel.readList(customFields, Field::class.java.classLoader)
parcel.readList(customFields as List<Field>, Field::class.java.classLoader)
otpModel = parcel.readParcelable(OtpModel::class.java.classLoader) ?: otpModel
}

View File

@@ -94,10 +94,10 @@ class AttachmentFileNotificationService: LockNotificationService() {
val nextNotificationId = (downloadFileUris.values.maxBy { it.notificationId }
?.notificationId ?: notificationId) + 1
val entryAttachment: EntryAttachment = intent.getParcelableExtra(ATTACHMENT_KEY)
try {
intent.getParcelableExtra<EntryAttachment>(ATTACHMENT_KEY)?.let { entryAttachment ->
val attachmentNotification = AttachmentNotification(nextNotificationId, entryAttachment)
downloadFileUris[downloadFileUri] = attachmentNotification
try {
AttachmentFileAsyncTask(downloadFileUri,
attachmentNotification,
contentResolver).apply {
@@ -108,6 +108,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
}
}
}.execute()
}
} catch (e: Exception) {
Log.e(TAG, "Unable to download $downloadFileUri", e)
}

View File

@@ -22,14 +22,11 @@ package com.kunzisoft.keepass.notifications
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.preference.PreferenceManager
import android.util.Log
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.exception.ClipboardException
import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.ClipboardHelper
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.timeout.TimeoutHelper.NEVER
import com.kunzisoft.keepass.utils.LOCK_ACTION
import java.util.*
@@ -62,9 +59,7 @@ class ClipboardEntryNotificationService : LockNotificationService() {
mEntryInfo = intent?.getParcelableExtra(EXTRA_ENTRY_INFO)
//Get settings
notificationTimeoutMilliSecs = PreferenceManager.getDefaultSharedPreferences(this)
.getString(getString(R.string.clipboard_timeout_key),
getString(R.string.clipboard_timeout_default))?.toLong() ?: TimeoutHelper.DEFAULT_TIMEOUT
notificationTimeoutMilliSecs = PreferencesUtil.getClipboardTimeout(this)
when {
intent == null -> Log.w(TAG, "null intent")
@@ -78,8 +73,9 @@ class ClipboardEntryNotificationService : LockNotificationService() {
}
else -> for (actionKey in ClipboardEntryNotificationField.allActionKeys) {
if (actionKey == intent.action) {
val fieldToCopy = intent.getParcelableExtra<ClipboardEntryNotificationField>(
ClipboardEntryNotificationField.getExtraKeyLinkToActionKey(actionKey))
intent.getParcelableExtra<ClipboardEntryNotificationField>(
ClipboardEntryNotificationField.getExtraKeyLinkToActionKey(actionKey))?.let {
fieldToCopy ->
val nextFields = constructListOfField(intent)
// Remove the current field from the next fields
nextFields.remove(fieldToCopy)
@@ -87,14 +83,17 @@ class ClipboardEntryNotificationService : LockNotificationService() {
}
}
}
}
return START_NOT_STICKY
}
private fun constructListOfField(intent: Intent?): ArrayList<ClipboardEntryNotificationField> {
var fieldList = ArrayList<ClipboardEntryNotificationField>()
if (intent != null && intent.extras != null) {
if (intent.extras!!.containsKey(EXTRA_CLIPBOARD_FIELDS))
fieldList = intent.getParcelableArrayListExtra(EXTRA_CLIPBOARD_FIELDS)
val fieldList = ArrayList<ClipboardEntryNotificationField>()
if (intent?.extras?.containsKey(EXTRA_CLIPBOARD_FIELDS) == true) {
intent.getParcelableArrayListExtra<ClipboardEntryNotificationField>(EXTRA_CLIPBOARD_FIELDS)?.let { retrieveFields ->
fieldList.clear()
fieldList.addAll(retrieveFields)
}
}
return fieldList
}

View File

@@ -32,6 +32,7 @@ import com.kunzisoft.keepass.database.action.history.DeleteEntryHistoryDatabaseR
import com.kunzisoft.keepass.database.action.history.RestoreEntryHistoryDatabaseRunnable
import com.kunzisoft.keepass.database.action.node.*
import com.kunzisoft.keepass.database.element.*
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
import com.kunzisoft.keepass.database.element.node.Node
import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.database.element.node.Type
@@ -209,8 +210,12 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(KEY_FILE_CHECKED_KEY)
&& intent.hasExtra(KEY_FILE_KEY)
) {
val databaseUri: Uri = intent.getParcelableExtra(DATABASE_URI_KEY)
val databaseUri: Uri? = intent.getParcelableExtra(DATABASE_URI_KEY)
val keyFileUri: Uri? = intent.getParcelableExtra(KEY_FILE_KEY)
if (databaseUri == null)
return null
return CreateDatabaseRunnable(this,
Database.getInstance(),
databaseUri,
@@ -236,12 +241,15 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(FIX_DUPLICATE_UUID_KEY)
) {
val database = Database.getInstance()
val databaseUri: Uri = intent.getParcelableExtra(DATABASE_URI_KEY)
val databaseUri: Uri? = intent.getParcelableExtra(DATABASE_URI_KEY)
val masterPassword: String? = intent.getStringExtra(MASTER_PASSWORD_KEY)
val keyFileUri: Uri? = intent.getParcelableExtra(KEY_FILE_KEY)
val readOnly: Boolean = intent.getBooleanExtra(READ_ONLY_KEY, true)
val cipherEntity: CipherDatabaseEntity? = intent.getParcelableExtra(CIPHER_ENTITY_KEY)
if (databaseUri == null)
return null
return LoadDatabaseRunnable(
this,
database,
@@ -275,9 +283,10 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(KEY_FILE_CHECKED_KEY)
&& intent.hasExtra(KEY_FILE_KEY)
) {
val databaseUri: Uri = intent.getParcelableExtra(DATABASE_URI_KEY) ?: return null
AssignPasswordInDatabaseRunnable(this,
Database.getInstance(),
intent.getParcelableExtra(DATABASE_URI_KEY),
databaseUri,
intent.getBooleanExtra(MASTER_PASSWORD_CHECKED_KEY, false),
intent.getStringExtra(MASTER_PASSWORD_KEY),
intent.getBooleanExtra(KEY_FILE_CHECKED_KEY, false),
@@ -304,10 +313,17 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val database = Database.getInstance()
database.getGroupById(intent.getParcelableExtra(PARENT_ID_KEY))?.let { parent ->
val parentId: NodeId<*>? = intent.getParcelableExtra(PARENT_ID_KEY)
val newGroup: Group? = intent.getParcelableExtra(GROUP_KEY)
if (parentId == null
|| newGroup == null)
return null
database.getGroupById(parentId)?.let { parent ->
AddGroupRunnable(this,
database,
intent.getParcelableExtra(GROUP_KEY),
newGroup,
parent,
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
AfterActionNodesRunnable())
@@ -323,8 +339,14 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val database = Database.getInstance()
database.getGroupById(intent.getParcelableExtra(GROUP_ID_KEY))?.let { oldGroup ->
val newGroup: Group = intent.getParcelableExtra(GROUP_KEY)
val groupId: NodeId<*>? = intent.getParcelableExtra(GROUP_ID_KEY)
val newGroup: Group? = intent.getParcelableExtra(GROUP_KEY)
if (groupId == null
|| newGroup == null)
return null
database.getGroupById(groupId)?.let { oldGroup ->
UpdateGroupRunnable(this,
database,
oldGroup,
@@ -343,10 +365,17 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val database = Database.getInstance()
database.getGroupById(intent.getParcelableExtra(PARENT_ID_KEY))?.let { parent ->
val parentId: NodeId<*>? = intent.getParcelableExtra(PARENT_ID_KEY)
val newEntry: Entry? = intent.getParcelableExtra(ENTRY_KEY)
if (parentId == null
|| newEntry == null)
return null
database.getGroupById(parentId)?.let { parent ->
AddEntryRunnable(this,
database,
intent.getParcelableExtra(ENTRY_KEY),
newEntry,
parent,
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
AfterActionNodesRunnable())
@@ -362,8 +391,14 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val database = Database.getInstance()
database.getEntryById(intent.getParcelableExtra(ENTRY_ID_KEY))?.let { oldEntry ->
val newEntry: Entry = intent.getParcelableExtra(ENTRY_KEY)
val entryId: NodeId<UUID>? = intent.getParcelableExtra(ENTRY_ID_KEY)
val newEntry: Entry? = intent.getParcelableExtra(ENTRY_KEY)
if (entryId == null
|| newEntry == null)
return null
database.getEntryById(entryId)?.let { oldEntry ->
UpdateEntryRunnable(this,
database,
oldEntry,
@@ -383,7 +418,9 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val database = Database.getInstance()
database.getGroupById(intent.getParcelableExtra(PARENT_ID_KEY))?.let { newParent ->
val parentId: NodeId<*> = intent.getParcelableExtra(PARENT_ID_KEY) ?: return null
database.getGroupById(parentId)?.let { newParent ->
CopyNodesRunnable(this,
database,
getListNodesFromBundle(database, intent.extras!!),
@@ -403,7 +440,9 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val database = Database.getInstance()
database.getGroupById(intent.getParcelableExtra(PARENT_ID_KEY))?.let { newParent ->
val parentId: NodeId<*> = intent.getParcelableExtra(PARENT_ID_KEY) ?: return null
database.getGroupById(parentId)?.let { newParent ->
MoveNodesRunnable(this,
database,
getListNodesFromBundle(database, intent.extras!!),
@@ -438,7 +477,9 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val database = Database.getInstance()
database.getEntryById(intent.getParcelableExtra(ENTRY_ID_KEY))?.let { mainEntry ->
val entryId: NodeId<UUID> = intent.getParcelableExtra(ENTRY_ID_KEY) ?: return null
database.getEntryById(entryId)?.let { mainEntry ->
RestoreEntryHistoryDatabaseRunnable(this,
database,
mainEntry,
@@ -456,7 +497,9 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
&& intent.hasExtra(SAVE_DATABASE_KEY)
) {
val database = Database.getInstance()
database.getEntryById(intent.getParcelableExtra(ENTRY_ID_KEY))?.let { mainEntry ->
val entryId: NodeId<UUID> = intent.getParcelableExtra(ENTRY_ID_KEY) ?: return null
database.getEntryById(entryId)?.let { mainEntry ->
DeleteEntryHistoryDatabaseRunnable(this,
database,
mainEntry,
@@ -472,10 +515,18 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
return if (intent.hasExtra(OLD_ELEMENT_KEY)
&& intent.hasExtra(NEW_ELEMENT_KEY)
&& intent.hasExtra(SAVE_DATABASE_KEY)) {
val oldElement: CompressionAlgorithm? = intent.getParcelableExtra(OLD_ELEMENT_KEY)
val newElement: CompressionAlgorithm? = intent.getParcelableExtra(NEW_ELEMENT_KEY)
if (oldElement == null
|| newElement == null)
return null
return UpdateCompressionBinariesDatabaseRunnable(this,
Database.getInstance(),
intent.getParcelableExtra(OLD_ELEMENT_KEY),
intent.getParcelableExtra(NEW_ELEMENT_KEY),
oldElement,
newElement,
intent.getBooleanExtra(SAVE_DATABASE_KEY, false)
).apply {
mAfterSaveDatabase = { result ->

View File

@@ -62,7 +62,9 @@ class KeyboardEntryNotificationService : LockNotificationService() {
else -> {
notificationManager?.cancel(notificationId)
if (intent.hasExtra(ENTRY_INFO_KEY)) {
newNotification(intent.getParcelableExtra(ENTRY_INFO_KEY))
intent.getParcelableExtra<EntryInfo>(ENTRY_INFO_KEY)?.let {
newNotification(it)
}
}
}
}

View File

@@ -281,8 +281,10 @@ object OtpEntryFields {
// malformed
return false
}
otpElement.period = matcher.group(1).toIntOrNull() ?: TOTP_DEFAULT_PERIOD
otpElement.tokenType = OtpTokenType.getFromString(matcher.group(2))
otpElement.period = matcher.group(1)?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD
otpElement.tokenType = matcher.group(2)?.let {
OtpTokenType.getFromString(it)
} ?: OtpTokenType.RFC6238
}
} catch (exception: Exception) {
return false

View File

@@ -276,6 +276,9 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
private fun onCreateAppearancePreferences(rootKey: String?) {
setPreferencesFromResource(R.xml.preferences_appearance, rootKey)
// To change list items appearance
PreferencesUtil.APPEARANCE_CHANGED = true
activity?.let { activity ->
findPreference<ListPreference>(getString(R.string.setting_style_key))?.setOnPreferenceChangeListener { _, newValue ->
var styleEnabled = true

View File

@@ -20,7 +20,8 @@
package com.kunzisoft.keepass.settings
import android.content.Context
import android.preference.PreferenceManager
import android.net.Uri
import androidx.preference.PreferenceManager
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.SortNodeEnum
import com.kunzisoft.keepass.timeout.TimeoutHelper
@@ -28,6 +29,40 @@ import java.util.*
object PreferencesUtil {
var APPEARANCE_CHANGED = false
private const val KEY_DEFAULT_DATABASE_PATH = "KEY_DEFAULT_DATABASE_PATH"
fun saveDefaultDatabasePath(context: Context, defaultDatabaseUri: Uri?) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
prefs?.edit()?.apply {
defaultDatabaseUri?.let {
putString(KEY_DEFAULT_DATABASE_PATH, it.toString())
} ?: kotlin.run {
remove(KEY_DEFAULT_DATABASE_PATH)
}
apply()
}
}
fun getDefaultDatabasePath(context: Context): String? {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getString(KEY_DEFAULT_DATABASE_PATH, "")
}
fun saveNodeSort(context: Context,
sortNodeEnum: SortNodeEnum,
sortNodeParameters: SortNodeEnum.SortNodeParameters) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
prefs?.edit()?.apply {
putString(context.getString(R.string.sort_node_key), sortNodeEnum.name)
putBoolean(context.getString(R.string.sort_ascending_key), sortNodeParameters.ascending)
putBoolean(context.getString(R.string.sort_group_before_key), sortNodeParameters.groupsBefore)
putBoolean(context.getString(R.string.sort_recycle_bin_bottom_key), sortNodeParameters.recycleBinBottom)
apply()
}
}
fun rememberDatabaseLocations(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.remember_database_locations_key),
@@ -147,6 +182,13 @@ object PreferencesUtil {
}
}
fun getClipboardTimeout(context: Context): Long {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getString(context.getString(R.string.clipboard_timeout_key),
context.getString(R.string.clipboard_timeout_default))?.toLong()
?: TimeoutHelper.DEFAULT_TIMEOUT
}
fun isLockDatabaseWhenScreenShutOffEnable(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.lock_database_screen_off_key),

View File

@@ -120,7 +120,7 @@ class HashedBlockInputStream(inputStream: InputStream) : InputStream() {
}
val computedHash = messageDigest.digest(buffer)
if (computedHash == null || computedHash.size != HASH_SIZE) {
if (computedHash.size != HASH_SIZE) {
throw IOException("Hash wrong size")
}

View File

@@ -23,6 +23,7 @@ import java.io.IOException
import java.io.OutputStream
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import kotlin.math.min
class HashedBlockOutputStream : OutputStream {
@@ -61,11 +62,11 @@ class HashedBlockOutputStream : OutputStream {
override fun close() {
if (bufferPos != 0) {
// Write remaining buffered amount
WriteHashedBlock()
writeHashedBlock()
}
// Write terminating block
WriteHashedBlock()
writeHashedBlock()
flush()
baseStream!!.close()
@@ -82,12 +83,12 @@ class HashedBlockOutputStream : OutputStream {
var counter = count
while (counter > 0) {
if (bufferPos == buffer!!.size) {
WriteHashedBlock()
writeHashedBlock()
}
val copyLen = Math.min(buffer!!.size - bufferPos, counter)
val copyLen = min(buffer!!.size - bufferPos, counter)
System.arraycopy(b, currentOffset, buffer, bufferPos, copyLen)
System.arraycopy(b, currentOffset, buffer!!, bufferPos, copyLen)
currentOffset += copyLen
bufferPos += copyLen
@@ -97,21 +98,21 @@ class HashedBlockOutputStream : OutputStream {
}
@Throws(IOException::class)
private fun WriteHashedBlock() {
private fun writeHashedBlock() {
baseStream!!.writeUInt(bufferIndex)
bufferIndex++
if (bufferPos > 0) {
var md: MessageDigest? = null
val messageDigest: MessageDigest
try {
md = MessageDigest.getInstance("SHA-256")
messageDigest = MessageDigest.getInstance("SHA-256")
} catch (e: NoSuchAlgorithmException) {
throw IOException("SHA-256 not implemented here.")
}
val hash: ByteArray
md!!.update(buffer, 0, bufferPos)
hash = md.digest()
messageDigest.update(buffer!!, 0, bufferPos)
hash = messageDigest.digest()
/*
if ( bufferPos == buffer.length) {
hash = md.digest(buffer);

View File

@@ -25,7 +25,6 @@ import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Build
import android.preference.PreferenceManager
import android.text.SpannableString
import android.text.method.LinkMovementMethod
import android.text.util.Linkify
@@ -33,6 +32,7 @@ import android.widget.TextView
import android.widget.Toast
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.exception.ClipboardException
import com.kunzisoft.keepass.settings.PreferencesUtil
import java.util.*
class ClipboardHelper(private val context: Context) {
@@ -58,13 +58,9 @@ class ClipboardHelper(private val context: Context) {
return
}
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val sClipClear = prefs.getString(context.getString(R.string.clipboard_timeout_key),
context.getString(R.string.clipboard_timeout_default))
val clipClearTime = (sClipClear ?: "300000").toLong()
if (clipClearTime > 0) {
mTimer.schedule(ClearClipboardTask(context, text), clipClearTime)
val clipboardTimeout = PreferencesUtil.getClipboardTimeout(context)
if (clipboardTimeout > 0) {
mTimer.schedule(ClearClipboardTask(context, text), clipboardTimeout)
}
}
@@ -89,7 +85,7 @@ class ClipboardHelper(private val context: Context) {
@Throws(ClipboardException::class)
fun copyToClipboard(label: String, value: String) {
try {
getClipboardManager()?.primaryClip = ClipData.newPlainText(label, value)
getClipboardManager()?.setPrimaryClip(ClipData.newPlainText(label, value))
} catch (e: Exception) {
throw ClipboardException(e)
}

View File

@@ -100,5 +100,5 @@ object ParcelableUtil {
inline fun <reified T : Enum<T>> Parcel.readEnum() =
readString()?.let { enumValueOf<T>(it) }
inline fun <T : Enum<T>> Parcel.writeEnum(value: T?) =
fun <T : Enum<T>> Parcel.writeEnum(value: T?) =
writeString(value?.name)

View File

@@ -42,7 +42,7 @@ object UriUtil {
return false
return try {
//https://developer.android.com/reference/android/content/res/AssetFileDescriptor
contentResolver.openAssetFileDescriptor(fileUri, "r")?.close()
contentResolver.openInputStream(fileUri)?.close()
true
} catch (e: Exception) {
Log.e(UriUtil.javaClass.name, "Unable to access uri $fileUri : ${e.message}")
@@ -50,16 +50,11 @@ object UriUtil {
}
}
fun isUriNotWritable(contentResolver: ContentResolver, fileUri: Uri?): Boolean {
fun isUriWritable(contentResolver: ContentResolver, fileUri: Uri?): Boolean {
if (fileUri == null)
return false
// TODO Uri writeable detection
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? {

View File

@@ -103,7 +103,7 @@ class EntryEditCustomField @JvmOverloads constructor(context: Context,
parent.removeView(this)
parent.invalidate()
} catch (e: ClassCastException) {
Log.e(javaClass.name, e.message)
Log.e(javaClass.name, "Unable to delete view", e)
}
}
}

View File

@@ -384,7 +384,7 @@ typedef struct _master_key {
} master_key;
void *generate_key_material(void *arg) {
uint32_t generate_key_material(void *arg) {
#if defined(KPD_PROFILE)
struct timespec start, end;
#endif
@@ -435,7 +435,7 @@ void *generate_key_material(void *arg) {
pthread_mutex_unlock(&mk->lock2);
}
return (void *)flip;
return flip;
}
JNIEXPORT jbyteArray JNICALL Java_com_kunzisoft_keepass_crypto_finalkey_NativeFinalKey_nTransformMasterKey(JNIEnv *env, jobject this, jbyteArray seed, jbyteArray key, jlong rounds) {
@@ -474,12 +474,12 @@ JNIEXPORT jbyteArray JNICALL Java_com_kunzisoft_keepass_crypto_finalkey_NativeFi
(*env)->GetByteArrayRegion(env, key, 0, MASTER_KEY_SIZE, (jbyte *)mk.key1);
// step 2: encrypt the hash "rounds" (default: 6000) times
iret = pthread_create( &t1, NULL, generate_key_material, (void*)&mk );
iret = pthread_create( &t1, NULL, (void*)generate_key_material, (void*)&mk );
if( iret != 0 ) {
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: failed to launch thread 1"); // FIXME: get a better exception class for this...
return NULL;
}
iret = pthread_create( &t2, NULL, generate_key_material, (void*)&mk );
iret = pthread_create( &t2, NULL, (void*)generate_key_material, (void*)&mk );
if( iret != 0 ) {
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: failed to launch thread 2"); // FIXME: get a better exception class for this...
return NULL;

View File

@@ -450,7 +450,7 @@
<string name="keyboard_auto_go_action_summary">Automatická akce klíče Jít po stisknutí klíče Pole</string>
<string name="download_attachment">Stáhnout %1$s</string>
<string name="download_initialization">Zahajuji…</string>
<string name="download_progression">Probíhá: %1$d%</string>
<string name="download_progression">Probíhá: %1$d&#37;</string>
<string name="download_finalization">Dokončuji…</string>
<string name="download_complete">Ukončeno! Klepnout pro otevření souboru.</string>
<string name="hide_expired_entries_title">Skrýt propadlé záznamy</string>

View File

@@ -449,7 +449,7 @@
<string name="keyboard_auto_go_action_summary">Handling af Gå-tasten udføres automatisk, efter der er trykket på en Felt nøgle</string>
<string name="download_attachment">Hent %1$s</string>
<string name="download_initialization">Initialiserer…</string>
<string name="download_progression">I gang: %1$d%</string>
<string name="download_progression">I gang: %1$d&#37;</string>
<string name="download_finalization">Færdiggørelse…</string>
<string name="download_complete">Komplet! Tryk for at åbne filen.</string>
<string name="hide_expired_entries_title">Skjul udløbne poster</string>

View File

@@ -453,7 +453,7 @@
<string name="keyboard_auto_go_action_summary">Aktion der Go-Taste, die automatisch nach dem Drücken einer Feldtaste ausgeführt wird</string>
<string name="download_attachment">%1$s herunterladen</string>
<string name="download_initialization">Initialisieren…</string>
<string name="download_progression">Fortschritt: %1$d%</string>
<string name="download_progression">Fortschritt: %1$d&#37;</string>
<string name="download_finalization">Fertigstellung…</string>
<string name="download_complete">Vollständig! Tippen Sie, um die Datei zu öffnen.</string>
<string name="hide_expired_entries_title">Abgelaufene Einträge ausblenden</string>

View File

@@ -449,7 +449,7 @@
<string name="keyboard_auto_go_action_summary">Η ενέργεια του πλήκτρου Go γίνεται αυτόματα αφού πατήσετε ένα πλήκτρο πεδίου</string>
<string name="download_attachment">Λήψη %1$s</string>
<string name="download_initialization">Αρχικοποίηση…</string>
<string name="download_progression">Σε εξέλιξη: %1$d%</string>
<string name="download_progression">Σε εξέλιξη: %1$d&#37;</string>
<string name="download_finalization">Ολοκλήρωση…</string>
<string name="download_complete">Ολοκληρώθηκε! Πατήστε για να ανοίξετε το αρχείο.</string>
<string name="hide_expired_entries_title">Απόκρυψη καταχωρίσεων που έχουν λήξει</string>

View File

@@ -460,9 +460,23 @@
<string name="keyboard_auto_go_action_summary">Action de la touche Go effectuée automatiquement après avoir appuyé sur une touche de champ</string>
<string name="download_attachment">Téléchargement %1$s</string>
<string name="download_initialization">Initialisation…</string>
<string name="download_progression">En cours : %1$d%</string>
<string name="download_progression">En cours : %1$d&#37;</string>
<string name="download_finalization">Finalisation…</string>
<string name="download_complete">Terminé ! Appuyer pour ouvrir le fichier.</string>
<string name="hide_expired_entries_title">Masquer les entrées expirées</string>
<string name="hide_expired_entries_summary">Les entrées expirées seront masquées</string>
<string name="contact">Contact</string>
<string name="contribution">Contribution</string>
<string name="html_about_contribution">Afin de &lt;strong&gt;garder notre liberté&lt;/strong&gt;, &lt;strong&gt;corriger les bugs&lt;/strong&gt;, &lt;strong&gt;ajouter des fonctionnalités&lt;/strong&gt; et &lt;strong&gt;être toujours actif&lt;/strong&gt;, nous comptons sur votre &lt;strong&gt;contribution&lt;/strong&gt;.</string>
<string name="auto_focus_search_title">Recherche rapide</string>
<string name="auto_focus_search_summary">Demander une recherche lors de l\'ouverture d\'une base de données</string>
<string name="remember_database_locations_title">Enregistrer l\'emplacement des bases de données</string>
<string name="remember_database_locations_summary">Se souvenir de l\'emplacement des bases de données</string>
<string name="remember_keyfile_locations_title">Enregistrer l\'emplacement des fichiers clés</string>
<string name="remember_keyfile_locations_summary">Se souvenir de l\'emplacement des fichiers de clés des bases de données</string>
<string name="show_recent_files_title">Afficher les fichiers récents</string>
<string name="show_recent_files_summary">Afficher les emplacements des bases de données récentes</string>
<string name="hide_broken_locations_title">Masquer les liens rompus de base de données</string>
<string name="hide_broken_locations_summary">Masquer les liens rompus dans la liste des bases de données récentes</string>
<string name="warning_database_read_only">Accorder un accès en écriture au fichier pour enregistrer les modifications de la base de données</string>
</resources>

View File

@@ -408,7 +408,7 @@
<string name="menu_restore_entry_history">Gjenopprett historikk</string>
<string name="menu_delete_entry_history">Slett historikk</string>
<string name="download_attachment">Last ned %1$s</string>
<string name="download_progression">Underveis: %1$d%</string>
<string name="download_progression">Underveis: %1$d&#37;</string>
<string name="download_finalization">Fullfører…</string>
<string name="download_complete">Fullført. Trykk for å åpne filen.</string>
<string name="hide_expired_entries_title">Skjul utløpte oppføringer</string>

View File

@@ -449,7 +449,7 @@
<string name="keyboard_auto_go_action_summary">Działanie klawisza Go wykonywane jest automatycznie po naciśnięciu klawisza Field</string>
<string name="download_attachment">Pobierz %1$s</string>
<string name="download_initialization">Inicjowanie…</string>
<string name="download_progression">W trakcie realizacji: %1$d%</string>
<string name="download_progression">W trakcie realizacji: %1$d&#37;</string>
<string name="download_finalization">Kończę…</string>
<string name="download_complete">Kompletny! Stuknij, aby otworzyć plik.</string>
<string name="hide_expired_entries_title">Ukryj wygasłe wpisy</string>

View File

@@ -1,2 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="about_description">Implementarea Android a managerului de parole KeePass</string>
<string name="accept">Accept</string>
<string name="add_entry">Introduce intrarea</string>
<string name="edit_entry">Editeaza intrarea</string>
<string name="add_group">Aduce grup</string>
<string name="master_key">Cheia generala</string>
<string name="security">Securitate</string>
<string name="encryption">Criptare</string>
<string name="encryption_algorithm">Algoritm de criptare</string>
<string name="key_derivation_function">Functie derivata a cheii</string>
<string name="app_timeout">Timpul aplicatiei a expirat</string>
<string name="app_timeout_summary">Timpul de asteptare inaintea blocarii bancii de date</string>
<string name="application">Aplicatie</string>
<string name="beta_dontask">Nu mai arata inca odata</string>
<string name="brackets">Paranteze patrate</string>
<string name="extended_ASCII">ASCII extins</string>
<string name="file_manager_install_description">Un manager de fișiere care acceptă acțiunea de creeare ACTION_CREATE_DOCUMENT si ACTION_OPEN_DOCUMENT este necesara sa creeze ,deschida si salveze fisierele din banca de date</string>
<string name="allow">Permite</string>
<string name="clipboard_cleared">Carnetelul din memorie curatat</string>
<string name="clipboard_error_title">Eroare de citire copiere memorie</string>
<string name="clipboard_error">Unele dispozitive nu permit aplicatiei sa foloseasca memoria de citire din carnetel.</string>
<string name="clipboard_error_clear">Nu s-a putut curata memoria carnetelului</string>
<string name="clipboard_timeout">Timp expirat de citire a carnetelului</string>
<string name="clipboard_timeout_summary">Durata de memorare din carnetel</string>
<string name="clipboard_swipe_clean">Schimba ca sa cureti carnetelul acum</string>
<string name="content_description_background">In spate</string>
<string name="content_description_open_file">Deschide fisier</string>
<string name="content_description_node_children">Copil nod</string>
<string name="content_description_add_node">Introduce nod</string>
<string name="content_description_add_entry">Introduce o intrare</string>
<string name="content_description_add_group">Aduce un grup</string>
<string name="content_description_file_information">Informatia fisierului</string>
<string name="content_description_password_checkbox">Verifica parola</string>
<string name="content_description_keyfile_checkbox">Verifica fisierul cheie</string>
<string name="content_description_repeat_toggle_password_visibility">Repetați pentru a comuta vizibilitatea parolei</string>
<string name="content_description_entry_icon">Pictograma de intrare</string>
<string name="content_description_entry_save">Salvați intrarea</string>
<string name="content_description_password_generator">Generator de parole</string>
<string name="content_description_password_length">Lungimea parolei</string>
<string name="content_description_add_field">Adăugați câmp</string>
<string name="content_description_remove_field">Elimina câmp</string>
<string name="content_description_update_from_list">Actualizați</string>
<string name="content_description_remove_from_list">Elimina</string>
<string name="content_description_keyboard_close_fields">Câmpuri închise</string>
<string name="select_to_copy">%1$s is either \\\"Nume\\\" si \\\"Parola\\\".</string>
<string name="retrieving_db_key">Obtinerea cheii bazei de date…</string>
<string name="database">Baza de date</string>
<string name="decrypting_db">Decriptarea continutului bazei de date.…</string>
<string name="contact">Contact</string>
<string name="contribution">Contributie</string>
<string name="feedback">Opinii</string>
<string name="homepage">Pagina acasa</string>
<string name="default_checkbox">Folosiți ca bază de date implicită</string>
<string name="digits">Digits</string>
<string name="entry_accessed">Accesat</string>
<string name="entry_cancel">Anuleaza</string>
<string name="entry_notes">Note</string>
<string name="entry_confpassword">Confirma parola</string>
<string name="entry_created">Creeat</string>
<string name="entry_expires">Expira</string>
<string name="entry_UUID">UUID</string>
<string name="entry_history">Istoric</string>
<string name="entry_attachments">Atasamente</string>
<string name="entry_keyfile">Fisiercheie</string>
<string name="entry_modified">Modificat</string>
<string name="entry_not_found">Nu s-au putut găsi date de intrare.</string>
<string name="entry_password">Parola</string>
<string name="entry_save">Salveaza</string>
<string name="entry_title">Titlu</string>
<string name="entry_setup_otp">Setați o singură parolă</string>
<string name="otp_type">Tipul OTP</string>
<string name="otp_secret">Secret</string>
<string name="otp_period">Perioada(secunde)</string>
<string name="otp_counter">Numaratoare</string>
<string name="otp_digits">Digiti</string>
<string name="otp_algorithm">Algoritm</string>
<string name="entry_otp">OTP</string>
<string name="entry_url">URL</string>
<string name="entry_user_name">Nume utilizator</string>
<string name="error_arc4">Cifrarea fluxului Arcfour nu este acceptată.</string>
<string name="error_can_not_handle_uri">Nu s-a putut gestiona acest URI în KeePassDX.</string>
<string name="error_file_not_create">Nu s-a putut creea fisierul:</string>
<string name="error_invalid_db">Nu s-a putut citi baza de date.</string>
<string name="error_invalid_path">Asigurați-vă că calea este corectă.</string>
<string name="error_invalid_OTP">Secret OTP nevalid.</string>
<string name="error_no_name">Introduce un nume.</string>
<string name="error_nokeyfile">Alege un fisier cheie.</string>
<string name="error_out_of_memory">Nicio memorie pentru a încărca întreaga dvs. bază de date.</string>
<string name="error_load_database">Nu s-a putut încărca baza de date.</string>
<string name="error_load_database_KDF_memory">Nu s-a putut încărca cheia. Încercați să reduceți KDF „Utilizarea memoriei”.</string>
<string name="error_pass_gen_type">Trebuie selectat cel puțin un tip de generare a parolei.</string>
<string name="error_disallow_no_credentials">Trebuie să fie stabilit cel puțin o acreditare.</string>
<string name="error_pass_match">Parolele nu se potrivesc.</string>
<string name="error_rounds_too_large">\"Transformările rotunde\" prea sus. Setarea la 2147483648.</string>
<string name="error_string_key">Fiecare șir trebuie să aibă un nume de câmp.</string>
<string name="error_title_required">Adăugați un titlu.</string>
<string name="error_wrong_length">Introduceți un număr întreg pozitiv în câmpul \"Lungime\".</string>
<string name="error_autofill_enable_service">Nu s-a putut activa serviciul de completare automată.</string>
<string name="error_move_folder_in_itself">Nu puteți muta un grup în sine.</string>
<string name="error_move_entry_here">Nu puteți muta o intrare aici.</string>
<string name="error_copy_entry_here">Nu puteți copia o intrare aici.</string>
<string name="error_copy_group_here">Nu puteți copia un grup aici.</string>
<string name="error_create_database_file">Nu se poate crea baza de date cu această parolă și cu fișierul cheie.</string>
<string name="error_save_database">Nu s-a putut salva baza de date.</string>
<string name="error_otp_secret_key">Cheia secretă trebuie să fie în format Base32.</string>
<string name="error_otp_counter">Contorul trebuie să fie între %1$d and %2$d.</string>
<string name="error_otp_period">Perioada trebuie să fie cuprinsă între%1$d and %2$d seconds.</string>
<string name="error_otp_digits">Tokenul trebuie să conțină cifre de la %1$d to %2$d digits.</string>
<string name="field_name">Numele domeniului</string>
<string name="field_value">Valoarea câmpului</string>
<string name="file_not_found_content">Nu s-a putut găsi fișierul. Încercați să-l redeschideți din browserul de fișiere.</string>
<string name="file_browser">Browser de fișiere</string>
<string name="generate_password">Generați parola</string>
<string name="hint_conf_pass">Confirmă parola</string>
<string name="hint_generated_password">Parola generata</string>
<string name="hint_group_name">Numele Grupului</string>
<string name="hint_keyfile">Fisier cheie</string>
<string name="hint_length">Lungime</string>
<string name="hint_pass">Parola</string>
<string name="password">Parola</string>
<string name="install_from_f_droid">Instalați din F-Droid</string>
<string name="install_from_play_store">Instalați din Play Store</string>
<string name="invalid_credentials">Nu s-a putut citi datele de acreditare. Dacă reîncepe, baza de date a dumneavoastra poate fi coruptă.</string>
<string name="invalid_algorithm">Algoritm greșit.</string>
<string name="invalid_db_same_uuid">%1$s cu același UUID %2$s există deja.</string>
<string name="invalid_db_sig">Nu s-a putut recunoaște formatul bazei de date.</string>
<string name="keyfile_is_empty">Fișierul cheie este gol.</string>
<string name="length">Lungime</string>
<string name="list_entries_show_username_title">Afișați numele de utilizator</string>
<string name="list_entries_show_username_summary">Afișați numele de utilizator în listele de intrare</string>
<string name="list_groups_show_number_entries_title">Afișează numărul de intrări</string>
<string name="list_groups_show_number_entries_summary">Afișează numărul de intrări dintr-un grup</string>
<string name="list_size_title">Mărimea articolelor din listă</string>
<string name="list_size_summary">Dimensiunea textului în lista de elemente</string>
<string name="creating_database">Crearea bazei de date …</string>
<string name="loading_database">Se încarcă baza de date …</string>
<string name="lowercase">Caz jos</string>
<string name="menu_change_key_settings">Schimbă cheia principală</string>
<string name="copy_field">Copie din %1$s</string>
<string name="settings">Setări</string>
<string name="menu_app_settings">Setările aplicației</string>
<string name="menu_form_filling_settings">Completarea formularului</string>
<string name="menu_advanced_unlock_settings">Deblocare avansată</string>
<string name="menu_database_settings">Setările bazei de date</string>
<string name="menu_security_settings">Setări de securitate</string>
<string name="menu_master_key_settings">Setări cheie master</string>
<string name="menu_donate">Donează</string>
<string name="menu_edit">Editați</string>
<string name="menu_copy">Copie</string>
<string name="menu_move">Muta</string>
<string name="menu_paste">Lipeste</string>
<string name="menu_delete">Șterge</string>
<string name="menu_cancel">Anulare</string>
<string name="menu_hide_password">Ascunde parola</string>
<string name="menu_lock">Blocați baza de date</string>
<string name="menu_save_database">Salvați baza de date</string>
<string name="menu_open">Deschide</string>
<string name="menu_search">Căutare</string>
<string name="menu_showpass">Arata parola</string>
<string name="menu_biometric_remove_key">Ștergeți cheia biometrică salvată</string>
<string name="menu_url">Accesați adresa URL</string>
<string name="menu_file_selection_read_only">Protejat la scriere</string>
<string name="menu_open_file_read_and_write">Modificabil</string>
<string name="menu_empty_recycle_bin">Golește coșul de gunoi</string>
<string name="menu_restore_entry_history">Restaurați istoria</string>
<string name="menu_delete_entry_history">Ștergeți istoricul</string>
<string name="minus">Minus</string>
<string name="never">Niciodata</string>
<string name="no_results">Nu există Rezultate</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft is &lt;strong&gt;sursa deschisa&lt;strong&gt; and &lt;strong&gt;fara publicitate&lt;strong&gt;.
\nEste prevăzut așa cum este, sub &lt;strong&gt;GPLv3&lt;strong&gt; licenta,fara nici un fel de garantie.</string>
<string name="html_about_contribution">In oridine sa &lt;strong&gt;pastram libertatea noastra &lt;strong&gt;, &lt;strong&gt;fix bugs&lt;strong&gt;, &lt;strong&gt;adăugați funcții&lt;strong&gt; si&lt;strong&gt;sa fie intotdeauna activ&lt;strong&gt;", ne bazam pe "&lt;strong&gt;contributie.&lt;strong&gt;</string>
<string name="hide_password_title">Ascundeți parolele</string>
<string name="hide_password_summary">Mascați parolele (***) în mod implicit</string>
<string name="about">Despre</string>
</resources>

View File

@@ -38,12 +38,13 @@
<string name="clipboard_timeout">Задержка очистки буфера обмена</string>
<string name="clipboard_timeout_summary">Продолжительность хранения в буфере обмена</string>
<string name="select_to_copy">Выберите %1$s для копирования в буфер обмена</string>
<string name="retrieving_db_key">Создание ключа базы…</string>
<string name="retrieving_db_key">Получение ключа базы…</string>
<string name="database">База</string>
<string name="decrypting_db">Расшифровка базы…</string>
<string name="default_checkbox">База по умолчанию</string>
<string name="digits">Цифры</string>
<string name="html_about_licence">Приложение KeePassDX © %1$d Kunzisoft предоставляется без каких-либо гарантий. Распространяется свободно по лицензии GPL v3 или новее.</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft с &lt;strong&gt;открытым исходным кодом&lt;strong&gt; и &lt;strong&gt;без рекламы&lt;strong&gt;.
\nРаспространяется под лицензией &lt;strong&gt;GPLv3&lt;strong&gt; без каких-либо гарантий.</string>
<string name="select_database_file">Открыть существующую базу</string>
<string name="entry_accessed">Доступ</string>
<string name="entry_cancel">Отмена</string>
@@ -115,7 +116,7 @@
<string name="never">Никогда</string>
<string name="no_results">Совпадения не найдены</string>
<string name="no_url_handler">Установите браузер, чтобы открыть этот URL.</string>
<string name="open_recent">Недавно открытые</string>
<string name="open_recent">Недавно открытые базы</string>
<string name="omit_backup_search_title">Не искать в резервных копиях</string>
<string name="omit_backup_search_summary">Не искать в группах \"Резервирование\" и \"Корзина\"</string>
<string name="progress_create">Создание новой базы…</string>
@@ -284,7 +285,7 @@
<string name="education_generate_password_title">Создайте надёжный пароль для записи.</string>
<string name="education_generate_password_summary">Создайте надёжный пароль, связанный с записью, легко настраиваемый под критерии формы. И не забудьте главный пароль от базы.</string>
<string name="education_entry_new_field_title">Добавляйте настраиваемые поля</string>
<string name="education_entry_new_field_summary">Зарегистрируйте дополнительное поле, просто заполнив его, добавьте значение и при необходимости защитите.</string>
<string name="education_entry_new_field_summary">Зарегистрируйте дополнительное поле, добавьте значение и при необходимости защитите его.</string>
<string name="education_unlock_title">Разблокируйте базу</string>
<string name="education_read_only_title">База только для чтения</string>
<string name="education_read_only_summary">Изменяйте режим открытия в сессии.
@@ -301,7 +302,7 @@
<string name="education_sort_summary">Выберите критерий сортировки записей и групп.</string>
<string name="education_donation_title">Участвуйте</string>
<string name="education_donation_summary">Примите участие в проекте для повышения стабильности, безопасности и добавления новых возможностей.</string>
<string name="html_text_ad_free">В отличие от многих приложений управления паролями, это &lt;strong&gt;без рекламы&lt;/strong&gt;, &lt;strong&gt;с открытым исходным кодом&lt;/strong&gt; и &lt;strong&gt;свободно от лицензирования&lt;/strong&gt;. Оно &lt;strong&gt;не хранит ваши личные данные&lt;/strong&gt; на своих серверах независимо от того, какую версию (бесплатную или профессиональную) вы используете.</string>
<string name="html_text_ad_free">В отличие от многих приложений управления паролями, это &lt;strong&gt;без рекламы&lt;strong&gt; и &lt;strong&gt;свободно от лицензирования&lt;strong&gt;. Оно не собирает ваши личные данные на своих серверах независимо от того, какую версию вы используете.</string>
<string name="html_text_buy_pro">При покупке Pro-версии вы будете иметь доступ к этим &lt;strong&gt;визуальным стилям&lt;/strong&gt; и особенно поможете &lt;strong&gt;реализации общественных проектов&lt;/strong&gt;.</string>
<string name="html_text_feature_generosity">Эти &lt;strong&gt;визуальные стили&lt;/strong&gt; доступны благодаря вашей щедрости.</string>
<string name="html_text_donation">Для того, чтобы сохранить нашу независимость и быть всегда активными, мы рассчитываем на ваш &lt;strong&gt;вклад&lt;/strong&gt;.</string>
@@ -449,9 +450,23 @@
<string name="keyboard_auto_go_action_summary">Выполнять команду \"Ввод\" автоматически после нажатия кнопки заполнения поля</string>
<string name="download_attachment">Скачать %1$s</string>
<string name="download_initialization">Инициализация…</string>
<string name="download_progression">Выполнение: %1$d%</string>
<string name="download_progression">Выполнение: %1$d&#37;</string>
<string name="download_finalization">Завершение…</string>
<string name="download_complete">Готово! Нажмите, чтобы открыть файл.</string>
<string name="hide_expired_entries_title">Скрывать устаревшие записи</string>
<string name="hide_expired_entries_summary">Записи с истёкшим сроком окончания будут скрыты</string>
<string name="contact">Контактная информация</string>
<string name="contribution">Вклад</string>
<string name="html_about_contribution">Для &lt;strong&gt;сохранения нашей независимости&lt;strong&gt;, &lt;strong&gt;исправления ошибок&lt;strong&gt;, &lt;strong&gt;добавления новых функций&lt;strong&gt; и &lt;strong&gt;поддержания разработки в активном состоянии&lt;strong&gt;, мы рассчитываем на ваш &lt;strong&gt;вклад&lt;strong&gt;.</string>
<string name="auto_focus_search_title">Быстрый поиск</string>
<string name="auto_focus_search_summary">Открывать поисковый запрос при открытии базы</string>
<string name="remember_database_locations_title">Хранить расположение баз</string>
<string name="remember_database_locations_summary">Запоминать расположение баз</string>
<string name="remember_keyfile_locations_title">Хранить расположение файлов ключей</string>
<string name="remember_keyfile_locations_summary">Запоминать расположение файлов ключей баз</string>
<string name="show_recent_files_title">Показывать последние базы</string>
<string name="show_recent_files_summary">Показывать расположение последних открытых баз</string>
<string name="hide_broken_locations_title">Скрывать отсутствующие</string>
<string name="hide_broken_locations_summary">Не показывать неработающие ссылки в списке последних открытых баз</string>
<string name="warning_database_read_only">Необходимо разрешение на запись в файл для сохранения изменений базы</string>
</resources>

View File

@@ -150,8 +150,17 @@
<string name="extended_ASCII">Rozšírené ASCII</string>
<string name="allow">Povoliť</string>
<string name="clipboard_error_title">Chyba schránky</string>
<string name="clipboard_error">Niektoré Samsungy nedovolia aplikáciám používať schránku.</string>
<string name="clipboard_error">Niektoré zariadenia nedovolia aplikáciám používať schránku.</string>
<string name="clipboard_error_clear">Nepodarilo sa vymazať schránku</string>
<string name="clipboard_swipe_clean">Schránku vymažete potiahnutím prsta cez políčko</string>
<string name="entry_not_found">Nenašli sa údaje záznamu</string>
<string name="contact">Kontakt</string>
<string name="content_description_open_file">Otvoriť súbor</string>
<string name="content_description_file_information">Informácie o súbore</string>
<string name="content_description_entry_save">Uložiť záznam</string>
<string name="content_description_password_generator">Generátor hesla</string>
<string name="content_description_password_length">Dĺžka hesla</string>
<string name="content_description_background">Pozadie</string>
<string name="security">Bezpečnosť</string>
<string name="contribution">Príspevok</string>
</resources>

View File

@@ -433,7 +433,7 @@
<string name="keyboard_auto_go_action_summary">Alan tuşuna bastıktan sonra otomatik olarak gerçekleştirilen Git tuşunun eylemi</string>
<string name="download_attachment">İndir %1$s</string>
<string name="download_initialization">Başlatılıyor…</string>
<string name="download_progression">Devam ediyor: %1$d%</string>
<string name="download_progression">Devam ediyor: %1$d&#37;</string>
<string name="download_finalization">Sonlandırılıyor…</string>
<string name="download_complete">Tamamlandı! Dosyayı açmak için dokunun.</string>
<string name="hide_expired_entries_title">Süresi dolmuş girdileri gizle</string>

View File

@@ -39,7 +39,8 @@
<string name="decrypting_db">正在解密数据库内容…</string>
<string name="default_checkbox">设为默认数据库</string>
<string name="digits">数字</string>
<string name="html_about_licence">磐密码©%1$dKunzisoft程序绝对不带有担保。本程序是自由程序可在遵循GPLv3或者此开源协议的更高版本的情况下重新发布。</string>
<string name="html_about_licence">KeePassDX © %1$dKunzisoft的一个&lt;strong&gt;开源&lt;strong&gt;&lt;strong&gt;无广告&lt;strong&gt;软件。
\n它是根据&lt;strong&gt;GPLv3 &lt;strong&gt;许可证分发的您可在遵循GPL 3或者更高版本的协议下重新发布。对软件的质量和性能等问题不提供任何形式的担保。</string>
<string name="select_database_file">打开已有数据库</string>
<string name="entry_accessed">访问时间</string>
<string name="entry_cancel">取消</string>
@@ -55,7 +56,7 @@
<string name="entry_url">链接</string>
<string name="entry_user_name">用户名</string>
<string name="error_arc4">不支持Arcfour流式加密。</string>
<string name="error_can_not_handle_uri">无法在磐密码中处理此URI。</string>
<string name="error_can_not_handle_uri">无法在KeePassDX中处理此URI。</string>
<string name="error_file_not_create">无法新建文件:</string>
<string name="error_invalid_db">无法读取数据库。</string>
<string name="error_invalid_path">请确保路径正确。</string>
@@ -78,7 +79,7 @@
<string name="hint_pass">密码</string>
<string name="install_from_play_store">从Play商店安装</string>
<string name="install_from_f_droid">从F-Droid安装</string>
<string name="invalid_credentials">无法读取凭据。如果再次发生,则数据库文件可能已损坏。</string>
<string name="invalid_credentials">无法读取您的密码或密钥文件。如果重试后仍然如此,你的数据库可能已损坏。</string>
<string name="invalid_db_sig">无法识别数据库格式。</string>
<string name="length">长度</string>
<string name="list_size_title">列表项目尺寸</string>
@@ -109,8 +110,8 @@
<string name="content_description_remove_from_list">移除</string>
<string name="encryption_rijndael">Rijndael(AES)</string>
<string name="root">Root</string>
<string name="rounds">转换次数</string>
<string name="rounds_explanation">更多的转换次数能更好地抵抗暴力破解攻击,但也的确会增加读取和保存的时间。</string>
<string name="rounds">迭代次数</string>
<string name="rounds_explanation">更多的迭代次数能更好地抵抗暴力破解攻击,但也会增加读取和保存的时间。</string>
<string name="saving_database">正在保存数据库…</string>
<string name="space">空格</string>
<string name="search_label">搜索</string>
@@ -146,7 +147,7 @@
<string name="extended_ASCII">ASCII拓展区字符</string>
<string name="allow">允许</string>
<string name="clipboard_error_title">剪切板错误</string>
<string name="clipboard_error">一些设备不程序使用剪切板。</string>
<string name="clipboard_error">一些设备不允许程序使用剪切板。</string>
<string name="clipboard_error_clear">无法清空剪切板</string>
<string name="clipboard_swipe_clean">滑动以清空剪切板</string>
<string name="encryption_chacha20">ChaCha20</string>
@@ -180,11 +181,11 @@
<string name="omit_backup_search_summary">搜索时忽略“备份”与“回收站”群组</string>
<string name="protection">保护</string>
<string name="read_only">只读</string>
<string name="read_only_warning">磐密码需要写入权限以修改数据库。</string>
<string name="read_only_warning">KeePassDX需要写入权限以修改数据库。</string>
<string name="show_recent_files_title">最近文件历史</string>
<string name="show_recent_files_summary">记住最近使用的文件名</string>
<string name="encryption_explanation">加密所有数据时采用的算法。</string>
<string name="kdf_explanation">转换主密钥以生成加密数据库所需的密钥,转换方式为随机加盐算法。</string>
<string name="kdf_explanation">迭代主密钥以生成加密数据库所需的密钥,转换方式为随机加盐算法。</string>
<string name="memory_usage">内存使用量</string>
<string name="memory_usage_explanation">密钥推导算法使用的内存(以二进制字节计)。</string>
<string name="parallelism">并行</string>
@@ -203,8 +204,8 @@
<string name="menu_appearance_settings">外观</string>
<string name="general">常规</string>
<string name="autofill">自动填充</string>
<string name="autofill_service_name">磐密码自动填充</string>
<string name="autofill_sign_in_prompt">使用密码登录</string>
<string name="autofill_service_name">使用KeePassDX自动填充</string>
<string name="autofill_sign_in_prompt">使用KeePassDX密码登录</string>
<string name="clipboard">剪贴板</string>
<string name="clipboard_notifications_title">剪贴板通知</string>
<string name="lock">锁定</string>
@@ -221,7 +222,7 @@
<string name="application_appearance">程序</string>
<string name="other">其他</string>
<string name="keyboard">键盘</string>
<string name="magic_keyboard_title">磐密码键盘</string>
<string name="magic_keyboard_title">魔法键盘</string>
<string name="enable_read_only_title">写保护(只读模式)</string>
<string name="enable_read_only_summary">默认以只读方式打开数据库</string>
<string name="download">下载</string>
@@ -238,14 +239,14 @@
<string name="warning_empty_password">确定不用密码解锁?</string>
<string name="warning_no_encryption_key">确认使用空密钥吗?</string>
<string name="build_label">版本%1$s</string>
<string name="configure_biometric">支持但未配置生物识别。</string>
<string name="configure_biometric">支持生物识别设置,但并未启用生物识别。</string>
<string name="open_biometric_prompt_unlock_database">打开生物识别对话框以解锁数据库</string>
<string name="encrypted_value_stored">加密密码已保存</string>
<string name="biometric_invalid_key">不能读取生物识别密钥。请将其删除后重新设置</string>
<string name="biometric_invalid_key">不能读取生物识别密钥,请删除所有生物密钥,并重新录入</string>
<string name="biometric_not_recognized">无法识别生物识别信息</string>
<string name="biometric_scanning_error">生物识别错误:%1$s</string>
<string name="no_credentials_stored">当前数据库无密码。</string>
<string name="set_autofill_service_title">设为默认填充服务</string>
<string name="set_autofill_service_title">设为默认填充服务</string>
<string name="autofill_explanation_summary">启用自动填充功能,以便捷地在其他程序中填写信息</string>
<string name="password_size_title">密码生成长度</string>
<string name="password_size_summary">设置生成密码的默认长度</string>
@@ -268,20 +269,20 @@
<string name="recycle_bin_summary">删除群组和条目前先移至回收站</string>
<string name="monospace_font_fields_enable_title">字段字体</string>
<string name="monospace_font_fields_enable_summary">更改字段字体,可以使字符更清楚</string>
<string name="allow_copy_password_summary">让剪切板保存条目密码及保密字段</string>
<string name="allow_copy_password_summary">允许复制整段密码和受保护的字段至剪切板</string>
<string name="allow_copy_password_warning">警告:复制密码时密码在剪贴板中,而所有程序都可访问剪切板。因此复制密码时,设备上的其他程序也能看到密码。</string>
<string name="magic_keyboard_explanation_summary">激活自定义键盘以填写密码和所有身份字段</string>
<string name="allow_copy_password_title">信任剪贴板</string>
<string name="keyboard_name">磐密码键盘</string>
<string name="keyboard_label">磐密码键盘</string>
<string name="keyboard_setting_label">磐密码键盘设置</string>
<string name="keyboard_name">魔法键盘</string>
<string name="keyboard_label">魔法键盘KeePassDX</string>
<string name="keyboard_setting_label">魔法键盘设置</string>
<string name="keyboard_entry_category">条目</string>
<string name="keyboard_entry_timeout_title">超时</string>
<string name="keyboard_entry_timeout_summary">设置多久后清空键盘记录</string>
<string name="keyboard_notification_entry_title">通知信息</string>
<string name="keyboard_notification_entry_summary">在条目可用时显示通知</string>
<string name="keyboard_notification_entry_content_title_text">条目</string>
<string name="keyboard_notification_entry_content_title">%1$s在磐密码键盘中可用</string>
<string name="keyboard_notification_entry_content_title">%1$s 在魔法键盘中可用</string>
<string name="keyboard_notification_entry_content_text">%1$s</string>
<string name="keyboard_notification_entry_clear_close_title">关闭时清空</string>
<string name="keyboard_notification_entry_clear_close_summary">在关闭通知时锁定数据库</string>
@@ -314,7 +315,7 @@
<string name="education_generate_password_title">为记录新建强密码。</string>
<string name="education_generate_password_summary">依据表格中的标准生成新密码,并将密码与条目关联起来,永不忘记。</string>
<string name="education_entry_new_field_title">添加自定义字段</string>
<string name="education_entry_new_field_summary">可能有的字段程序没有提供。这时可以新建可以被保护字段。</string>
<string name="education_entry_new_field_summary">添加一个新的字段并添加为其添加一个值,此时可以选择是否保护字段及其值</string>
<string name="education_unlock_title">解锁数据库</string>
<string name="education_read_only_title">为数据库开启写保护(只读)</string>
<string name="education_read_only_summary">在会话中改变打开模式。
@@ -331,7 +332,7 @@
<string name="education_sort_summary">选择条目和群组的排序方式。</string>
<string name="education_donation_title">参与开发</string>
<string name="education_donation_summary">帮助增加稳定性,安全性并添加更多的功能。</string>
<string name="html_text_ad_free">不同于大多数的密码管理程序,不论使用免费还是付费版本的磐密码,都没有&lt;strong&gt;广告&lt;/strong&gt;并且&lt;strong&gt;开源&lt;/strong&gt;,使用&lt;strong&gt;自由程序协议&lt;/strong&gt;&lt;strong&gt;不收集&lt;/strong&gt;任何用户的个人信息。</string>
<string name="html_text_ad_free">不同于大多数的密码管理程序,无论您是使用免费版本还是付费版本的KeePassDX这都是一款&lt;strong&gt;没有广告&lt;strong&gt;&lt;strong&gt;基于copylefted版权协议的免费软件&lt;strong&gt;,同样的本软件的任何版本也不会收集您的个人信息。</string>
<string name="html_text_buy_pro">通过购买高级版本,您将解锁全部&lt;strong&gt;主题样式&lt;/strong&gt;,重要的是,您会为&lt;strong&gt;社区项目的进行&lt;/strong&gt;提供的帮助</string>
<string name="html_text_feature_generosity">&lt;strong&gt;主题样式&lt;/strong&gt;现在已经可用,感谢慷慨相助。</string>
<string name="html_text_donation">为继续建设此自由项目,我们需要&lt;strong&gt;捐助。&lt;/strong&gt;</string>
@@ -347,12 +348,12 @@
<string name="lock_database_back_root_title">按返回键以锁定</string>
<string name="lock_database_back_root_summary">在点按根屏幕上的后退按钮时锁定数据库</string>
<string name="clear_clipboard_notification_title">关闭程序时清空剪贴板</string>
<string name="clear_clipboard_notification_summary">关闭通知时关闭数据库</string>
<string name="clear_clipboard_notification_summary">清除通知时锁定数据库</string>
<string name="recycle_bin">回收站</string>
<string name="keyboard_selection_entry_title">条目选择</string>
<string name="keyboard_selection_entry_summary">在查看条目时,在专用键盘中显示输入字段</string>
<string name="delete_entered_password_title">删除密码</string>
<string name="delete_entered_password_summary">删除尝试连接后输入的密码</string>
<string name="delete_entered_password_summary">密码错误后删除已输入的密码</string>
<string name="content_description_open_file">打开文件</string>
<string name="content_description_node_children">子节点</string>
<string name="content_description_add_node">增加节点</string>
@@ -379,7 +380,7 @@
<string name="error_create_database_file">无法使用此密码和密钥文件新建数据库。</string>
<string name="menu_advanced_unlock_settings">高级解锁</string>
<string name="biometric_prompt_store_credential_title">保存生物识别信息</string>
<string name="biometric_prompt_store_credential_message">警告:即使用生物识别数据存储了凭据,你仍需牢记主密码。</string>
<string name="biometric_prompt_store_credential_message">警告:即使您已经使用生物识别数据存储了凭据,你仍需牢记主密码。</string>
<string name="biometric_prompt_extract_credential_title">使用生物识别功能打开数据库</string>
<string name="biometric_prompt_extract_credential_message">使用生物识别数据提取数据库凭据</string>
<string name="biometric">生物识别</string>
@@ -410,7 +411,7 @@
<string name="menu_security_settings">安全设置</string>
<string name="menu_master_key_settings">主密钥设置</string>
<string name="contains_duplicate_uuid">数据库包含重复UUID。</string>
<string name="contains_duplicate_uuid_procedure">通过验证此对话框,磐密码将解决这个问题通过给重复项生成新的UUID并继续。</string>
<string name="contains_duplicate_uuid_procedure">通过验证此对话框,KeePassDX将解决这个问题通过给重复项生成新的UUID并继续。</string>
<string name="database_opened">数据库开启</string>
<string name="clipboard_explanation_summary">使用设备的剪贴板来复制输入字段</string>
<string name="persistent_notification_title">持久通知</string>
@@ -443,17 +444,29 @@
<string name="recycle_bin_group_title">回收站(组)</string>
<string name="enable_auto_save_database_title">自动保存数据库</string>
<string name="enable_auto_save_database_summary">在进行重要操作后自动保存数据库(仅在编辑模式下有效)</string>
<string name="keystore_not_accessible">密钥库未正确初始化。</string>
<string name="keystore_not_accessible">密钥库未正确初始化。</string>
<string name="entry_attachments">附件</string>
<string name="menu_restore_entry_history">恢复历史记录</string>
<string name="menu_delete_entry_history">删除历史记录</string>
<string name="keyboard_auto_go_action_title">自动键操作</string>
<string name="keyboard_auto_go_action_summary">按下Field键后自动执行Go键的动作</string>
<string name="keyboard_auto_go_action_summary">填入用户名或密码后直接登录</string>
<string name="download_attachment">下载%1$s</string>
<string name="download_initialization">正在初始化…</string>
<string name="download_progression">进行中:%1$d%</string>
<string name="download_progression">进行中:%1$d&#37;</string>
<string name="download_finalization">正在完成…</string>
<string name="download_complete">完成!点击打开文件。</string>
<string name="hide_expired_entries_title">隐藏过期条目</string>
<string name="hide_expired_entries_summary">过期条目将被隐藏</string>
<string name="contact">联系我们</string>
<string name="contribution">贡献</string>
<string name="html_about_contribution">为了&lt;strong&gt;保持我们的自由&lt;strong&gt;&lt;strong&gt;修复错误&lt;strong&gt;&lt;strong&gt;添加功能&lt;strong&gt;&lt;strong&gt;始终保持活跃&lt;strong&gt;,我们期待您的 &lt;strong&gt;贡献。&lt;strong&gt;</string>
<string name="auto_focus_search_title">快速搜索</string>
<string name="auto_focus_search_summary">打开数据库时询问是否进行搜索</string>
<string name="remember_database_locations_title">数据库保存的路径</string>
<string name="remember_database_locations_summary">记住数据库的路径</string>
<string name="remember_keyfile_locations_title">密钥文件保存的路径</string>
<string name="remember_keyfile_locations_summary">记住密钥文件的路径</string>
<string name="hide_broken_locations_title">隐藏已损坏的数据库路径</string>
<string name="hide_broken_locations_summary">在最近的数据库列表中隐藏已损坏的数据库的链接</string>
<string name="warning_database_read_only">授予软件文件读写访问权限以保存数据库更改</string>
</resources>

View File

@@ -143,7 +143,7 @@
<string name="extended_ASCII">增強的ASCII</string>
<string name="allow">允許</string>
<string name="clipboard_error_title">剪貼簿錯誤</string>
<string name="clipboard_error">部份 Samsung 手機不容許其他程式使用剪貼簿。</string>
<string name="clipboard_error">部份設備不容許其他程式使用剪貼簿。</string>
<string name="clipboard_error_clear">無法清除剪貼簿</string>
<string name="clipboard_swipe_clean">滑动即可清除剪贴板</string>
<string name="error_autofill_enable_service">無法啟用自動填入服務。</string>
@@ -251,4 +251,15 @@
<string name="menu_security_settings">安全設定</string>
<string name="contains_duplicate_uuid">資料庫包含重複的 UUID。</string>
<string name="contains_duplicate_uuid_procedure">通過驗證此對話方塊KeePassDX 將修復問題(通過為重複項生成新的 UUID並繼續。</string>
<string name="set_autofill_service_title">設置為默認的填充服務</string>
<string name="password_size_title">生成密碼的長度</string>
<string name="password_size_summary">設置生成密碼的默認長度</string>
<string name="list_password_generator_options_title">密碼字符集</string>
<string name="list_password_generator_options_summary">設置密碼生成時所需要的字符集</string>
<string name="clipboard">剪貼板</string>
<string name="autofill_explanation_summary">啟用自動填充功能以快速填寫其他應用程序中的用戶名和密碼</string>
<string name="database_opened">數據庫已打開</string>
<string name="clipboard_explanation_summary">使用設備的剪貼板複製輸入密碼</string>
<string name="contact">聯繫方式</string>
<string name="contribution">貢獻</string>
</resources>

View File

@@ -73,7 +73,7 @@
<string name="default_checkbox">Use as default database</string>
<string name="digits">Digits</string>
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft is &lt;strong&gt;open source&lt;/strong&gt; and &lt;strong&gt;without advertising&lt;/strong&gt;. \nIt is provided as is, under &lt;strong&gt;GPLv3&lt;/strong&gt; license, without any warranty.</string>
<string name="html_about_contribution">In order to &lt;strong&gt;keep our freedom&lt;/strong&gt;, &lt;strong&gt;fix bugs&lt;/strong&gt;, &lt;strong&gt;add features&lt;/strong&gt; and &lt;strong&gt;to be always active&lt;/strong&gt;, we count on your &lt;strong&gt;contribution.&lt;/strong&gt;</string>
<string name="html_about_contribution">In order to &lt;strong&gt;keep our freedom&lt;/strong&gt;, &lt;strong&gt;fix bugs&lt;/strong&gt;, &lt;strong&gt;add features&lt;/strong&gt; and &lt;strong&gt;to be always active&lt;/strong&gt;, we count on your &lt;strong&gt;contribution&lt;/strong&gt;.</string>
<string name="entry_accessed">Accessed</string>
<string name="entry_cancel">Cancel</string>
<string name="entry_notes">Notes</string>
@@ -405,7 +405,7 @@
<string name="education_generate_password_title">Create a strong password for your entry.</string>
<string name="education_generate_password_summary">Generate a strong password to associate with your entry, easily define it according to the criteria of the form and don\'t forget secure password.</string>
<string name="education_entry_new_field_title">Add custom fields</string>
<string name="education_entry_new_field_summary">Register a basic non-supplied field by filling in a new one that you can also protect.</string>
<string name="education_entry_new_field_summary">Register an additional field, add a value and optionally protect it.</string>
<string name="education_unlock_title">Unlock your database</string>
<string name="education_unlock_summary">Enter the password and/or keyfile to unlock your database.\n\nBackup your database file in a safe place after each change.</string>
<string name="education_read_only_title">Write protect your database</string>
@@ -433,7 +433,7 @@
<string name="contribute">Contribute</string>
<string name="download_attachment">Download %1$s</string>
<string name="download_initialization">Initializing…</string>
<string name="download_progression">In progress: %1$d\%%</string>
<string name="download_progression">In progress: %1$d&#37;</string>
<string name="download_finalization">Finalizing…</string>
<string name="download_complete">Complete! Tap to open the file.</string>
<!-- Encryption Algorithms -->

View File

@@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.41'
ext.kotlin_version = '1.3.61'
repositories {
jcenter()
maven {
@@ -10,7 +10,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
classpath 'com.android.tools.build:gradle:3.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View File

@@ -0,0 +1,2 @@
* Fix read only database
* Upgrade to Android SDK 29

View File

@@ -0,0 +1,2 @@
* Correction base de données en lecture seule
* Mise à jour vers Android SDK 29

View File

@@ -1,3 +1,4 @@
android.enableJetifier=true
android.useAndroidX=true
kapt.incremental.apt=true
org.gradle.jvmargs=-Xmx2048M

View File

@@ -1,6 +1,6 @@
#Thu Aug 29 16:23:48 CEST 2019
#Sun Mar 08 08:59:59 CET 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip