mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a846ec29ca | ||
|
|
4533e96bff | ||
|
|
0a401c3ac9 | ||
|
|
468abaf077 | ||
|
|
4ccf2f641c | ||
|
|
34eb2785cf | ||
|
|
09dbfe323e | ||
|
|
1f06c5b425 | ||
|
|
b98e089f7a | ||
|
|
a0ad06ed0a | ||
|
|
ec63365429 | ||
|
|
2cb85e4346 | ||
|
|
0d7c479c51 | ||
|
|
5a6c21e662 | ||
|
|
d6cadac98f | ||
|
|
dac2fc2c37 | ||
|
|
0fb45cef0d | ||
|
|
5ebdbd4003 | ||
|
|
b30f1023cb | ||
|
|
e5f65a4d1e | ||
|
|
ab42a65aa4 | ||
|
|
e351456bfe | ||
|
|
452e68b08f | ||
|
|
d65beed7a1 | ||
|
|
f5a5a0e8cb | ||
|
|
98380a0906 | ||
|
|
22fe7508f3 | ||
|
|
c8e241fc76 | ||
|
|
2c943e00d0 | ||
|
|
7ddb83b72d | ||
|
|
50bac01699 | ||
|
|
e0a92dfadd | ||
|
|
b50c951091 | ||
|
|
2f589a95a9 | ||
|
|
53eac86a95 | ||
|
|
9412f8955e | ||
|
|
71c98d82b1 | ||
|
|
42c1a925b4 | ||
|
|
1e84534ffd |
66
CHANGELOG
66
CHANGELOG
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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')"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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? {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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%</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>
|
||||
|
||||
@@ -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%</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>
|
||||
|
||||
@@ -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%</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>
|
||||
|
||||
@@ -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%</string>
|
||||
<string name="download_finalization">Ολοκλήρωση…</string>
|
||||
<string name="download_complete">Ολοκληρώθηκε! Πατήστε για να ανοίξετε το αρχείο.</string>
|
||||
<string name="hide_expired_entries_title">Απόκρυψη καταχωρίσεων που έχουν λήξει</string>
|
||||
|
||||
@@ -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%</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 <strong>garder notre liberté</strong>, <strong>corriger les bugs</strong>, <strong>ajouter des fonctionnalités</strong> et <strong>être toujours actif</strong>, nous comptons sur votre <strong>contribution</strong>.</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>
|
||||
@@ -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%</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>
|
||||
|
||||
@@ -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%</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>
|
||||
|
||||
@@ -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 <strong>sursa deschisa<strong> and <strong>fara publicitate<strong>.
|
||||
\nEste prevăzut așa cum este, sub <strong>GPLv3<strong> licenta,fara nici un fel de garantie.</string>
|
||||
<string name="html_about_contribution">In oridine sa <strong>pastram libertatea noastra <strong>, <strong>fix bugs<strong>, <strong>adăugați funcții<strong> si<strong>sa fie intotdeauna activ<strong>", ne bazam pe "<strong>contributie.<strong></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>
|
||||
@@ -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 с <strong>открытым исходным кодом<strong> и <strong>без рекламы<strong>.
|
||||
\nРаспространяется под лицензией <strong>GPLv3<strong> без каких-либо гарантий.</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">В отличие от многих приложений управления паролями, это <strong>без рекламы</strong>, <strong>с открытым исходным кодом</strong> и <strong>свободно от лицензирования</strong>. Оно <strong>не хранит ваши личные данные</strong> на своих серверах независимо от того, какую версию (бесплатную или профессиональную) вы используете.</string>
|
||||
<string name="html_text_ad_free">В отличие от многих приложений управления паролями, это <strong>без рекламы<strong> и <strong>свободно от лицензирования<strong>. Оно не собирает ваши личные данные на своих серверах независимо от того, какую версию вы используете.</string>
|
||||
<string name="html_text_buy_pro">При покупке Pro-версии вы будете иметь доступ к этим <strong>визуальным стилям</strong> и особенно поможете <strong>реализации общественных проектов</strong>.</string>
|
||||
<string name="html_text_feature_generosity">Эти <strong>визуальные стили</strong> доступны благодаря вашей щедрости.</string>
|
||||
<string name="html_text_donation">Для того, чтобы сохранить нашу независимость и быть всегда активными, мы рассчитываем на ваш <strong>вклад</strong>.</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%</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">Для <strong>сохранения нашей независимости<strong>, <strong>исправления ошибок<strong>, <strong>добавления новых функций<strong> и <strong>поддержания разработки в активном состоянии<strong>, мы рассчитываем на ваш <strong>вклад<strong>.</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>
|
||||
@@ -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>
|
||||
@@ -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%</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>
|
||||
|
||||
@@ -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$d 是Kunzisoft的一个<strong>开源<strong>和<strong>无广告<strong>软件。
|
||||
\n它是根据<strong>GPLv3 <strong>许可证分发的,您可在遵循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">不同于大多数的密码管理程序,不论使用免费还是付费版本的磐密码,都没有<strong>广告</strong>,并且<strong>开源</strong>,使用<strong>自由程序协议</strong>也<strong>不收集</strong>任何用户的个人信息。</string>
|
||||
<string name="html_text_ad_free">不同于大多数的密码管理程序,无论您是使用免费版本还是付费版本的KeePassDX,这都是一款<strong>没有广告<strong>,<strong>基于copylefted版权协议的免费软件<strong>,同样的本软件的任何版本也不会收集您的个人信息。</string>
|
||||
<string name="html_text_buy_pro">通过购买高级版本,您将解锁全部<strong>主题样式</strong>,重要的是,您会为<strong>社区项目的进行</strong>提供的帮助</string>
|
||||
<string name="html_text_feature_generosity">此<strong>主题样式</strong>现在已经可用,感谢慷慨相助。</string>
|
||||
<string name="html_text_donation">为继续建设此自由项目,我们需要<strong>捐助。</strong></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%</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">为了<strong>保持我们的自由<strong>,<strong>修复错误<strong>,<strong>添加功能<strong>和<strong>始终保持活跃<strong>,我们期待您的 <strong>贡献。<strong></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>
|
||||
@@ -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>
|
||||
@@ -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 <strong>open source</strong> and <strong>without advertising</strong>. \nIt is provided as is, under <strong>GPLv3</strong> license, without any warranty.</string>
|
||||
<string name="html_about_contribution">In order to <strong>keep our freedom</strong>, <strong>fix bugs</strong>, <strong>add features</strong> and <strong>to be always active</strong>, we count on your <strong>contribution.</strong></string>
|
||||
<string name="html_about_contribution">In order to <strong>keep our freedom</strong>, <strong>fix bugs</strong>, <strong>add features</strong> and <strong>to be always active</strong>, we count on your <strong>contribution</strong>.</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%</string>
|
||||
<string name="download_finalization">Finalizing…</string>
|
||||
<string name="download_complete">Complete! Tap to open the file.</string>
|
||||
<!-- Encryption Algorithms -->
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
2
fastlane/metadata/android/en-US/changelogs/28.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/28.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
* Fix read only database
|
||||
* Upgrade to Android SDK 29
|
||||
2
fastlane/metadata/android/fr-FR/changelogs/28.txt
Normal file
2
fastlane/metadata/android/fr-FR/changelogs/28.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
* Correction base de données en lecture seule
|
||||
* Mise à jour vers Android SDK 29
|
||||
@@ -1,3 +1,4 @@
|
||||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
||||
kapt.incremental.apt=true
|
||||
org.gradle.jvmargs=-Xmx2048M
|
||||
|
||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user