mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Compare commits
160 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d91f07646 | ||
|
|
db882a26ab | ||
|
|
7f01619358 | ||
|
|
ee109b4ceb | ||
|
|
7a398e5453 | ||
|
|
d4655d7034 | ||
|
|
9feb96b541 | ||
|
|
e939278193 | ||
|
|
d4ef1a2617 | ||
|
|
5f8746ced3 | ||
|
|
40a063e94f | ||
|
|
8f5439b958 | ||
|
|
e347f57d8b | ||
|
|
2efb8e8b8c | ||
|
|
e5bb69ea5f | ||
|
|
6ae186b2af | ||
|
|
71fdd2d92d | ||
|
|
3656689ff3 | ||
|
|
7d78406db6 | ||
|
|
ac47748e41 | ||
|
|
80f9b46479 | ||
|
|
999f1bf47a | ||
|
|
9e114eb2b8 | ||
|
|
d89b6529ef | ||
|
|
5caf11556a | ||
|
|
78cc6f0f40 | ||
|
|
0007cd4668 | ||
|
|
05195e41de | ||
|
|
66f44ef87d | ||
|
|
a0585d9b11 | ||
|
|
5067946b13 | ||
|
|
f52241d5a8 | ||
|
|
04ccb25fa3 | ||
|
|
5a3f4b60b8 | ||
|
|
4408b2e488 | ||
|
|
9a26acee35 | ||
|
|
6ac377348b | ||
|
|
daeb88d4f4 | ||
|
|
47bf199f52 | ||
|
|
91540b022d | ||
|
|
505a51b6b5 | ||
|
|
28400488aa | ||
|
|
45ae600289 | ||
|
|
8be6874651 | ||
|
|
f694a500e0 | ||
|
|
c415fa01fc | ||
|
|
5225a9459c | ||
|
|
2974b150af | ||
|
|
cf353c8067 | ||
|
|
3aacb5d8b3 | ||
|
|
114fbdbe01 | ||
|
|
f1f83cbec4 | ||
|
|
335c28c2c9 | ||
|
|
daf12cbcce | ||
|
|
bf56eca003 | ||
|
|
a12b7fd58a | ||
|
|
98d004edbf | ||
|
|
67586a98b3 | ||
|
|
c6d8911883 | ||
|
|
12e398ce9b | ||
|
|
5c4a202616 | ||
|
|
adc1ec8444 | ||
|
|
0227d2fcb4 | ||
|
|
95abe3b5ac | ||
|
|
133a902c54 | ||
|
|
aacb03d9ef | ||
|
|
fbeaa1781f | ||
|
|
ca73aad538 | ||
|
|
4a4bfefd17 | ||
|
|
6796b0cd2a | ||
|
|
29e1f824b0 | ||
|
|
51263a2911 | ||
|
|
dd7f857475 | ||
|
|
f0fdd4a537 | ||
|
|
9b847a0561 | ||
|
|
469e76b80a | ||
|
|
9c6994b476 | ||
|
|
52ba487617 | ||
|
|
21c57c9484 | ||
|
|
9b1ea6a07a | ||
|
|
f7d7bb0ea3 | ||
|
|
dd96b9ef53 | ||
|
|
b6b01893ba | ||
|
|
ad531d793d | ||
|
|
a9dd11e24a | ||
|
|
115983830b | ||
|
|
442cece081 | ||
|
|
14e08457b9 | ||
|
|
fabcc08cd5 | ||
|
|
7750843b04 | ||
|
|
c03188e976 | ||
|
|
d7da1ce333 | ||
|
|
dd9ee8c3f8 | ||
|
|
34bbd8f439 | ||
|
|
053f57cff5 | ||
|
|
365d2e2844 | ||
|
|
c0ac01a34a | ||
|
|
22c0bc0adb | ||
|
|
1b88f2ddf0 | ||
|
|
b4f2a1eb89 | ||
|
|
e9fc9cbc2a | ||
|
|
b809180a1b | ||
|
|
ecc75df3a1 | ||
|
|
d1b6863143 | ||
|
|
faf27143aa | ||
|
|
aee58a4475 | ||
|
|
c4cbf07d78 | ||
|
|
c5e07f643f | ||
|
|
818f5820d5 | ||
|
|
77c6e28876 | ||
|
|
fb7f66012d | ||
|
|
0f7f7bbe6c | ||
|
|
8dedb8deb4 | ||
|
|
dbb2c10bba | ||
|
|
67a5eef7d6 | ||
|
|
979f651251 | ||
|
|
3b93cbb009 | ||
|
|
30c63bfc4b | ||
|
|
bed40324a1 | ||
|
|
bc035de377 | ||
|
|
4db3cb6936 | ||
|
|
ed4b91f4bd | ||
|
|
24c7151276 | ||
|
|
804a9c07b8 | ||
|
|
528ea56821 | ||
|
|
7ba9c69ff8 | ||
|
|
0fc34da08a | ||
|
|
3fbf8cdbc8 | ||
|
|
e21f20d818 | ||
|
|
9fd9a60ca3 | ||
|
|
78b683d724 | ||
|
|
ad2f5036e1 | ||
|
|
4afbad8faa | ||
|
|
d284db4d3c | ||
|
|
ae8b1c0c29 | ||
|
|
27978c459c | ||
|
|
1dc7f5c666 | ||
|
|
12ac870d3a | ||
|
|
dd1baa0224 | ||
|
|
bb27ef41cc | ||
|
|
2d35ac1df8 | ||
|
|
589ffc0c06 | ||
|
|
1f7f38c7d3 | ||
|
|
83817a2dc0 | ||
|
|
11af9da66f | ||
|
|
af3926acf3 | ||
|
|
ab40c2b3fd | ||
|
|
fd05670dbc | ||
|
|
1ac094bfae | ||
|
|
fdf052cddb | ||
|
|
9a8d50ba6f | ||
|
|
136c97c312 | ||
|
|
bf00b88ef3 | ||
|
|
bafd1ea549 | ||
|
|
982618511b | ||
|
|
a4ad7ca3b1 | ||
|
|
99d71b57a4 | ||
|
|
1b2d8502e0 | ||
|
|
53e4ea9334 | ||
|
|
3ce704155c |
21
CHANGELOG
21
CHANGELOG
@@ -1,3 +1,24 @@
|
||||
KeePassDX(3.0.3)
|
||||
* Change default Argon2 parameters #1098
|
||||
* Add & edit custom icon name #976
|
||||
* Fix templates #1128 #1133 #1138
|
||||
* Update Autofill compatibility list #725 #1154
|
||||
* Improve fingerprint usage #1137 #1145
|
||||
* Change backup configuration #1144
|
||||
* Add lock button in database notification
|
||||
|
||||
KeePassDX(3.0.2)
|
||||
* Samsung DeX mode #1114 #245 (Thx @chenxiaolong)
|
||||
|
||||
KeePassDX(3.0.1)
|
||||
* Fix text size and smallest margin #1085
|
||||
* Fix number of lines during an edition #1073
|
||||
* Fix Magikeyboard URL auto action #1100
|
||||
* Fix exception after group name change and save #1112
|
||||
* Fix timeout reset #1107
|
||||
* Fix search actions #1091 #1092
|
||||
* Small changes #1106 #1085
|
||||
|
||||
KeePassDX(3.0.0)
|
||||
* Add / Manage dynamic templates #191
|
||||
* Manually select RecycleBin group and Templates group #191
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
- Material design with **themes**.
|
||||
- **Auto-Fill** and Integration.
|
||||
- Field filling **keyboard**.
|
||||
- Dynamic **templates**
|
||||
- **History** of each entry.
|
||||
- Precise management of **settings**.
|
||||
- Code written in **native languages** *(Kotlin / Java / JNI / C)*.
|
||||
|
||||
@@ -11,8 +11,8 @@ android {
|
||||
applicationId "com.kunzisoft.keepass"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 30
|
||||
versionCode = 87
|
||||
versionName = "3.0.0"
|
||||
versionCode = 90
|
||||
versionName = "3.0.3"
|
||||
multiDexEnabled true
|
||||
|
||||
testApplicationId = "com.kunzisoft.keepass.tests"
|
||||
@@ -99,33 +99,33 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
def room_version = "2.2.6"
|
||||
def room_version = "2.3.0"
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation "androidx.appcompat:appcompat:$android_appcompat_version"
|
||||
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
|
||||
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
implementation 'androidx.biometric:biometric:1.1.0'
|
||||
implementation 'androidx.media:media:1.4.3'
|
||||
// Lifecycle - LiveData - ViewModel - Coroutines
|
||||
implementation "androidx.core:core-ktx:1.3.2"
|
||||
implementation 'androidx.fragment:fragment-ktx:1.2.5'
|
||||
// WARNING: Don't upgrade because slowdown https://github.com/Kunzisoft/KeePassDX/issues/923
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
implementation "androidx.core:core-ktx:$android_core_version"
|
||||
implementation 'androidx.fragment:fragment-ktx:1.3.6'
|
||||
implementation "com.google.android.material:material:$android_material_version"
|
||||
// Database
|
||||
implementation "androidx.room:room-runtime:$room_version"
|
||||
kapt "androidx.room:room-compiler:$room_version"
|
||||
// Autofill
|
||||
implementation "androidx.autofill:autofill:1.1.0"
|
||||
// Time
|
||||
implementation 'joda-time:joda-time:2.10.6'
|
||||
implementation 'joda-time:joda-time:2.10.13'
|
||||
// Color
|
||||
implementation 'com.github.Kunzisoft:AndroidClearChroma:2.4'
|
||||
// Education
|
||||
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.0'
|
||||
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.3'
|
||||
// Apache Commons
|
||||
implementation 'commons-io:commons-io:2.8.0'
|
||||
implementation 'commons-codec:commons-codec:1.15'
|
||||
@@ -136,6 +136,6 @@ dependencies {
|
||||
implementation project(path: ':icon-pack-material')
|
||||
|
||||
// Tests
|
||||
androidTestImplementation 'androidx.test:runner:1.3.0'
|
||||
androidTestImplementation 'androidx.test:rules:1.3.0'
|
||||
androidTestImplementation "androidx.test:runner:$android_test_version"
|
||||
androidTestImplementation "androidx.test:rules:$android_test_version"
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
android:theme="@style/KeepassDXStyle.SplashScreen"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:exported="true"
|
||||
android:configChanges="keyboardHidden"
|
||||
android:windowSoftInputMode="stateHidden|stateAlwaysHidden" >
|
||||
<intent-filter>
|
||||
@@ -53,6 +54,7 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.kunzisoft.keepass.activities.PasswordActivity"
|
||||
android:exported="true"
|
||||
android:configChanges="keyboardHidden"
|
||||
android:windowSoftInputMode="adjustResize|stateUnchanged">
|
||||
<intent-filter>
|
||||
@@ -111,6 +113,7 @@
|
||||
<!-- Main Activity -->
|
||||
<activity
|
||||
android:name="com.kunzisoft.keepass.activities.GroupActivity"
|
||||
android:exported="false"
|
||||
android:configChanges="keyboardHidden"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
<meta-data
|
||||
@@ -154,7 +157,8 @@
|
||||
android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
|
||||
<activity
|
||||
android:name="com.kunzisoft.keepass.activities.EntrySelectionLauncherActivity"
|
||||
android:theme="@style/Theme.Transparent">
|
||||
android:theme="@style/Theme.Transparent"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -173,7 +177,8 @@
|
||||
android:theme="@style/Theme.Transparent" />
|
||||
<activity
|
||||
android:name="com.kunzisoft.keepass.settings.MagikeyboardSettingsActivity"
|
||||
android:label="@string/keyboard_setting_label">
|
||||
android:label="@string/keyboard_setting_label"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
</intent-filter>
|
||||
@@ -199,6 +204,7 @@
|
||||
<service
|
||||
android:name="com.kunzisoft.keepass.autofill.KeeAutofillService"
|
||||
android:label="@string/autofill_service_name"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_AUTOFILL_SERVICE">
|
||||
<meta-data
|
||||
android:name="android.autofill"
|
||||
@@ -210,6 +216,7 @@
|
||||
<service
|
||||
android:name="com.kunzisoft.keepass.magikeyboard.MagikeyboardService"
|
||||
android:label="@string/keyboard_label"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_INPUT_METHOD" >
|
||||
<meta-data android:name="android.view.im"
|
||||
android:resource="@xml/keyboard_method"/>
|
||||
@@ -221,6 +228,14 @@
|
||||
android:name="com.kunzisoft.keepass.services.KeyboardEntryNotificationService"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
<receiver
|
||||
android:name="com.kunzisoft.keepass.receivers.DexModeReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.app.action.ENTER_KNOX_DESKTOP_MODE" />
|
||||
<action android:name="android.app.action.EXIT_KNOX_DESKTOP_MODE" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
||||
</application>
|
||||
|
||||
@@ -23,10 +23,10 @@ import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentSender
|
||||
import android.os.Build
|
||||
import android.view.inputmethod.InlineSuggestionsRequest
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
|
||||
@@ -40,11 +40,15 @@ import com.kunzisoft.keepass.database.search.SearchHelper
|
||||
import com.kunzisoft.keepass.model.RegisterInfo
|
||||
import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.utils.LOCK_ACTION
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
|
||||
private var mAutofillActivityResultLauncher: ActivityResultLauncher<Intent>? =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
AutofillHelper.buildActivityResultLauncher(this, true)
|
||||
else null
|
||||
|
||||
override fun applyCustomStyle(): Boolean {
|
||||
return false
|
||||
}
|
||||
@@ -119,6 +123,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
// Show the database UI to select the entry
|
||||
GroupActivity.launchForAutofillResult(this,
|
||||
openedDatabase,
|
||||
mAutofillActivityResultLauncher,
|
||||
autofillComponent,
|
||||
searchInfo,
|
||||
false)
|
||||
@@ -126,6 +131,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
{
|
||||
// If database not open
|
||||
FileDatabaseSelectActivity.launchForAutofillResult(this,
|
||||
mAutofillActivityResultLauncher,
|
||||
autofillComponent,
|
||||
searchInfo)
|
||||
}
|
||||
@@ -186,17 +192,6 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
Toast.makeText(this.applicationContext, R.string.autofill_read_only_save, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
|
||||
|
||||
if (PreferencesUtil.isAutofillCloseDatabaseEnable(this)) {
|
||||
// Close the database
|
||||
sendBroadcast(Intent(LOCK_ACTION))
|
||||
}
|
||||
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val KEY_MANUAL_SELECTION = "KEY_MANUAL_SELECTION"
|
||||
@@ -210,31 +205,41 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
||||
searchInfo: SearchInfo? = null,
|
||||
inlineSuggestionsRequest: InlineSuggestionsRequest? = null): PendingIntent {
|
||||
return PendingIntent.getActivity(context, 0,
|
||||
// Doesn't work with Parcelable (don't know why?)
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
searchInfo?.let {
|
||||
putExtra(KEY_SEARCH_APPLICATION_ID, it.applicationId)
|
||||
putExtra(KEY_SEARCH_DOMAIN, it.webDomain)
|
||||
putExtra(KEY_SEARCH_SCHEME, it.webScheme)
|
||||
putExtra(KEY_MANUAL_SELECTION, it.manualSelection)
|
||||
// Doesn't work with Parcelable (don't know why?)
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
searchInfo?.let {
|
||||
putExtra(KEY_SEARCH_APPLICATION_ID, it.applicationId)
|
||||
putExtra(KEY_SEARCH_DOMAIN, it.webDomain)
|
||||
putExtra(KEY_SEARCH_SCHEME, it.webScheme)
|
||||
putExtra(KEY_MANUAL_SELECTION, it.manualSelection)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
inlineSuggestionsRequest?.let {
|
||||
putExtra(EXTRA_INLINE_SUGGESTIONS_REQUEST, it)
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
inlineSuggestionsRequest?.let {
|
||||
putExtra(EXTRA_INLINE_SUGGESTIONS_REQUEST, it)
|
||||
}
|
||||
}
|
||||
},
|
||||
PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
}
|
||||
},
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// TODO Mutable
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
})
|
||||
}
|
||||
|
||||
fun getPendingIntentForRegistration(context: Context,
|
||||
registerInfo: RegisterInfo): PendingIntent {
|
||||
return PendingIntent.getActivity(context, 0,
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
EntrySelectionHelper.addSpecialModeInIntent(this, SpecialMode.REGISTRATION)
|
||||
putExtra(KEY_REGISTER_INFO, registerInfo)
|
||||
},
|
||||
PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
Intent(context, AutofillLauncherActivity::class.java).apply {
|
||||
EntrySelectionHelper.addSpecialModeInIntent(this, SpecialMode.REGISTRATION)
|
||||
putExtra(KEY_REGISTER_INFO, registerInfo)
|
||||
},
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// TODO Mutable
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
})
|
||||
}
|
||||
|
||||
fun launchForRegistration(context: Context,
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
@@ -62,7 +63,6 @@ import com.kunzisoft.keepass.view.hideByFading
|
||||
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
|
||||
import com.kunzisoft.keepass.viewmodels.EntryViewModel
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
|
||||
class EntryActivity : DatabaseLockActivity() {
|
||||
|
||||
@@ -84,8 +84,13 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
private var mEntryLoaded = false
|
||||
|
||||
private var mAttachmentFileBinderManager: AttachmentFileBinderManager? = null
|
||||
private var mAttachmentsToDownload: HashMap<Int, Attachment> = HashMap()
|
||||
private var mExternalFileHelper: ExternalFileHelper? = null
|
||||
private var mAttachmentSelected: Attachment? = null
|
||||
|
||||
private var mEntryActivityResultLauncher = EntryEditActivity.registerForEntryResult(this) {
|
||||
// Reload the current id from database
|
||||
mEntryViewModel.loadDatabase(mDatabase)
|
||||
}
|
||||
|
||||
private var mIcon: IconImage? = null
|
||||
private var mIconColor: Int = 0
|
||||
@@ -133,6 +138,15 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
|
||||
// Init SAF manager
|
||||
mExternalFileHelper = ExternalFileHelper(this)
|
||||
mExternalFileHelper?.buildCreateDocument { createdFileUri ->
|
||||
mAttachmentSelected?.let { attachment ->
|
||||
if (createdFileUri != null) {
|
||||
mAttachmentFileBinderManager
|
||||
?.startDownloadAttachment(createdFileUri, attachment)
|
||||
}
|
||||
mAttachmentSelected = null
|
||||
}
|
||||
}
|
||||
// Init attachment service binder manager
|
||||
mAttachmentFileBinderManager = AttachmentFileBinderManager(this)
|
||||
|
||||
@@ -209,9 +223,8 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
}
|
||||
|
||||
mEntryViewModel.attachmentSelected.observe(this) { attachmentSelected ->
|
||||
mExternalFileHelper?.createDocument(attachmentSelected.name)?.let { requestCode ->
|
||||
mAttachmentsToDownload[requestCode] = attachmentSelected
|
||||
}
|
||||
mAttachmentSelected = attachmentSelected
|
||||
mExternalFileHelper?.createDocument(attachmentSelected.name)
|
||||
}
|
||||
|
||||
mEntryViewModel.historySelected.observe(this) { historySelected ->
|
||||
@@ -220,7 +233,8 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
this,
|
||||
database,
|
||||
historySelected.nodeId,
|
||||
historySelected.historyPosition
|
||||
historySelected.historyPosition,
|
||||
mEntryActivityResultLauncher
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -290,26 +304,6 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
when (requestCode) {
|
||||
EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE -> {
|
||||
// Reload the current id from database
|
||||
mEntryViewModel.loadDatabase(mDatabase)
|
||||
}
|
||||
}
|
||||
|
||||
mExternalFileHelper?.onCreateDocumentResult(requestCode, resultCode, data) { createdFileUri ->
|
||||
if (createdFileUri != null) {
|
||||
mAttachmentsToDownload[requestCode]?.let { attachmentToDownload ->
|
||||
mAttachmentFileBinderManager
|
||||
?.startDownloadAttachment(createdFileUri, attachmentToDownload)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
super.onCreateOptionsMenu(menu)
|
||||
if (mEntryLoaded) {
|
||||
@@ -391,7 +385,8 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
EntryEditActivity.launchToUpdate(
|
||||
this,
|
||||
database,
|
||||
entryId
|
||||
entryId,
|
||||
mEntryActivityResultLauncher
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -432,7 +427,7 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
// Transit data in previous Activity after an update
|
||||
Intent().apply {
|
||||
putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mMainEntryId)
|
||||
setResult(EntryEditActivity.ADD_OR_UPDATE_ENTRY_RESULT_CODE, this)
|
||||
setResult(Activity.RESULT_OK, this)
|
||||
}
|
||||
super.finish()
|
||||
}
|
||||
@@ -450,15 +445,13 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
*/
|
||||
fun launch(activity: Activity,
|
||||
database: Database,
|
||||
entryId: NodeId<UUID>) {
|
||||
entryId: NodeId<UUID>,
|
||||
activityResultLauncher: ActivityResultLauncher<Intent>) {
|
||||
if (database.loaded) {
|
||||
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
|
||||
val intent = Intent(activity, EntryActivity::class.java)
|
||||
intent.putExtra(KEY_ENTRY, entryId)
|
||||
activity.startActivityForResult(
|
||||
intent,
|
||||
EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE
|
||||
)
|
||||
activityResultLauncher.launch(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -469,16 +462,14 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
fun launch(activity: Activity,
|
||||
database: Database,
|
||||
entryId: NodeId<UUID>,
|
||||
historyPosition: Int) {
|
||||
historyPosition: Int,
|
||||
activityResultLauncher: ActivityResultLauncher<Intent>) {
|
||||
if (database.loaded) {
|
||||
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
|
||||
val intent = Intent(activity, EntryActivity::class.java)
|
||||
intent.putExtra(KEY_ENTRY, entryId)
|
||||
intent.putExtra(KEY_ENTRY_HISTORY_POSITION, historyPosition)
|
||||
activity.startActivityForResult(
|
||||
intent,
|
||||
EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE
|
||||
)
|
||||
activityResultLauncher.launch(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +33,17 @@ import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.dialogs.*
|
||||
@@ -96,6 +101,7 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
private var mTemplate: Template? = null
|
||||
private var mIsTemplate: Boolean = false
|
||||
private var mEntryLoaded: Boolean = false
|
||||
private var mTemplatesSelectorAdapter: TemplatesSelectorAdapter? = null
|
||||
|
||||
private var mAllowCustomFields = false
|
||||
private var mAllowOTP = false
|
||||
@@ -106,6 +112,10 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
// Education
|
||||
private var entryEditActivityEducation: EntryEditActivityEducation? = null
|
||||
|
||||
private var mIconSelectionActivityResultLauncher = IconPickerActivity.registerIconSelectionForResult(this) { icon ->
|
||||
mEntryEditViewModel.selectIcon(icon)
|
||||
}
|
||||
|
||||
// To ask data lost only one time
|
||||
private var backPressedAlreadyApproved = false
|
||||
|
||||
@@ -154,6 +164,21 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
|
||||
// To retrieve attachment
|
||||
mExternalFileHelper = ExternalFileHelper(this)
|
||||
mExternalFileHelper?.buildOpenDocument { uri ->
|
||||
uri?.let { attachmentToUploadUri ->
|
||||
UriUtil.getFileData(this, attachmentToUploadUri)?.also { documentFile ->
|
||||
documentFile.name?.let { fileName ->
|
||||
if (documentFile.length() > MAX_WARNING_BINARY_FILE) {
|
||||
FileTooBigDialogFragment.build(attachmentToUploadUri, fileName)
|
||||
.show(supportFragmentManager, "fileTooBigFragment")
|
||||
} else {
|
||||
mEntryEditViewModel.buildNewAttachment(attachmentToUploadUri, fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mAttachmentFileBinderManager = AttachmentFileBinderManager(this)
|
||||
// Verify the education views
|
||||
entryEditActivityEducation = EntryEditActivityEducation(this)
|
||||
@@ -175,11 +200,13 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
templateSelectorSpinner?.apply {
|
||||
// Build template selector
|
||||
if (templates.isNotEmpty()) {
|
||||
adapter = TemplatesSelectorAdapter(
|
||||
mTemplatesSelectorAdapter = TemplatesSelectorAdapter(
|
||||
this@EntryEditActivity,
|
||||
mIconDrawableFactory,
|
||||
templates
|
||||
)
|
||||
).apply {
|
||||
iconDrawableFactory = mIconDrawableFactory
|
||||
}
|
||||
adapter = mTemplatesSelectorAdapter
|
||||
val selectedTemplate = if (mTemplate != null)
|
||||
mTemplate
|
||||
else
|
||||
@@ -213,7 +240,7 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
|
||||
// View model listeners
|
||||
mEntryEditViewModel.requestIconSelection.observe(this) { iconImage ->
|
||||
IconPickerActivity.launch(this@EntryEditActivity, iconImage)
|
||||
IconPickerActivity.launch(this@EntryEditActivity, iconImage, mIconSelectionActivityResultLauncher)
|
||||
}
|
||||
|
||||
mEntryEditViewModel.requestDateTimeSelection.observe(this) { dateInstant ->
|
||||
@@ -321,6 +348,10 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
mAllowCustomFields = database?.allowEntryCustomFields() == true
|
||||
mAllowOTP = database?.allowOTP == true
|
||||
mEntryEditViewModel.loadDatabase(database)
|
||||
mTemplatesSelectorAdapter?.apply {
|
||||
iconDrawableFactory = mIconDrawableFactory
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDatabaseActionFinished(
|
||||
@@ -472,29 +503,6 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
IconPickerActivity.onActivityResult(requestCode, resultCode, data) { icon ->
|
||||
mEntryEditViewModel.selectIcon(icon)
|
||||
}
|
||||
|
||||
mExternalFileHelper?.onOpenDocumentResult(requestCode, resultCode, data) { uri ->
|
||||
uri?.let { attachmentToUploadUri ->
|
||||
UriUtil.getFileData(this, attachmentToUploadUri)?.also { documentFile ->
|
||||
documentFile.name?.let { fileName ->
|
||||
if (documentFile.length() > MAX_WARNING_BINARY_FILE) {
|
||||
FileTooBigDialogFragment.build(attachmentToUploadUri, fileName)
|
||||
.show(supportFragmentManager, "fileTooBigFragment")
|
||||
} else {
|
||||
mEntryEditViewModel.buildNewAttachment(attachmentToUploadUri, fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up OTP (HOTP or TOTP) and add it as extra field
|
||||
*/
|
||||
@@ -585,7 +593,7 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
&& entryEditActivityEducation.checkAndPerformedAttachmentEducation(
|
||||
attachmentView,
|
||||
{
|
||||
mExternalFileHelper?.openDocument()
|
||||
addNewAttachment()
|
||||
},
|
||||
{
|
||||
performedNextEducation(entryEditActivityEducation)
|
||||
@@ -686,7 +694,7 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
val intentEntry = Intent()
|
||||
bundle.putParcelable(ADD_OR_UPDATE_ENTRY_KEY, entry.nodeId)
|
||||
intentEntry.putExtras(bundle)
|
||||
setResult(ADD_OR_UPDATE_ENTRY_RESULT_CODE, intentEntry)
|
||||
setResult(Activity.RESULT_OK, intentEntry)
|
||||
super.finish()
|
||||
} catch (e: Exception) {
|
||||
// Exception when parcelable can't be done
|
||||
@@ -701,23 +709,46 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
// Keys for current Activity
|
||||
const val KEY_ENTRY = "entry"
|
||||
const val KEY_PARENT = "parent"
|
||||
|
||||
// Keys for callback
|
||||
const val ADD_OR_UPDATE_ENTRY_RESULT_CODE = 31
|
||||
const val ADD_OR_UPDATE_ENTRY_REQUEST_CODE = 7129
|
||||
const val ADD_OR_UPDATE_ENTRY_KEY = "ADD_OR_UPDATE_ENTRY_KEY"
|
||||
|
||||
fun registerForEntryResult(fragment: Fragment,
|
||||
entryAddedOrUpdatedListener: (NodeId<UUID>?) -> Unit): ActivityResultLauncher<Intent> {
|
||||
return fragment.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
entryAddedOrUpdatedListener.invoke(
|
||||
result.data?.getParcelableExtra(ADD_OR_UPDATE_ENTRY_KEY)
|
||||
)
|
||||
} else {
|
||||
entryAddedOrUpdatedListener.invoke(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun registerForEntryResult(activity: FragmentActivity,
|
||||
entryAddedOrUpdatedListener: (NodeId<UUID>?) -> Unit): ActivityResultLauncher<Intent> {
|
||||
return activity.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
entryAddedOrUpdatedListener.invoke(
|
||||
result.data?.getParcelableExtra(ADD_OR_UPDATE_ENTRY_KEY)
|
||||
)
|
||||
} else {
|
||||
entryAddedOrUpdatedListener.invoke(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch EntryEditActivity to update an existing entry by his [entryId]
|
||||
*/
|
||||
fun launchToUpdate(activity: Activity,
|
||||
database: Database,
|
||||
entryId: NodeId<UUID>) {
|
||||
entryId: NodeId<UUID>,
|
||||
activityResultLauncher: ActivityResultLauncher<Intent>) {
|
||||
if (database.loaded && !database.isReadOnly) {
|
||||
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
|
||||
val intent = Intent(activity, EntryEditActivity::class.java)
|
||||
intent.putExtra(KEY_ENTRY, entryId)
|
||||
activity.startActivityForResult(intent, ADD_OR_UPDATE_ENTRY_REQUEST_CODE)
|
||||
activityResultLauncher.launch(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -727,12 +758,13 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
*/
|
||||
fun launchToCreate(activity: Activity,
|
||||
database: Database,
|
||||
groupId: NodeId<*>) {
|
||||
groupId: NodeId<*>,
|
||||
activityResultLauncher: ActivityResultLauncher<Intent>) {
|
||||
if (database.loaded && !database.isReadOnly) {
|
||||
if (TimeoutHelper.checkTimeAndLockIfTimeout(activity)) {
|
||||
val intent = Intent(activity, EntryEditActivity::class.java)
|
||||
intent.putExtra(KEY_PARENT, groupId)
|
||||
activity.startActivityForResult(intent, ADD_OR_UPDATE_ENTRY_REQUEST_CODE)
|
||||
activityResultLauncher.launch(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -795,8 +827,9 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
* Launch EntryEditActivity to add a new entry in autofill selection
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
fun launchForAutofillResult(activity: Activity,
|
||||
fun launchForAutofillResult(activity: AppCompatActivity,
|
||||
database: Database,
|
||||
activityResultLauncher: ActivityResultLauncher<Intent>?,
|
||||
autofillComponent: AutofillComponent,
|
||||
groupId: NodeId<*>,
|
||||
searchInfo: SearchInfo? = null) {
|
||||
@@ -807,6 +840,7 @@ class EntryEditActivity : DatabaseLockActivity(),
|
||||
AutofillHelper.startActivityForAutofillResult(
|
||||
activity,
|
||||
intent,
|
||||
activityResultLauncher,
|
||||
autofillComponent,
|
||||
searchInfo
|
||||
)
|
||||
|
||||
@@ -31,8 +31,10 @@ import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@@ -85,9 +87,20 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
||||
|
||||
private var mExternalFileHelper: ExternalFileHelper? = null
|
||||
|
||||
private var mAutofillActivityResultLauncher: ActivityResultLauncher<Intent>? =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
AutofillHelper.buildActivityResultLauncher(this)
|
||||
else null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// Enabling/disabling MagikeyboardService is normally done by DexModeReceiver, but this
|
||||
// additional check will allow the keyboard to be reenabled more easily if the app crashes
|
||||
// or is force quit within DeX mode and then the user leaves DeX mode. Without this, the
|
||||
// user would need to enter and exit DeX mode once to reenable the service.
|
||||
MagikeyboardUtil.setEnabled(this, !DexUtil.isDexMode(resources.configuration))
|
||||
|
||||
mFileDatabaseHistoryAction = FileDatabaseHistoryAction.getInstance(applicationContext)
|
||||
|
||||
setContentView(R.layout.activity_file_selection)
|
||||
@@ -103,6 +116,22 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
||||
|
||||
// Open database button
|
||||
mExternalFileHelper = ExternalFileHelper(this)
|
||||
mExternalFileHelper?.buildOpenDocument { uri ->
|
||||
uri?.let {
|
||||
launchPasswordActivityWithPath(uri)
|
||||
}
|
||||
}
|
||||
mExternalFileHelper?.buildCreateDocument("application/x-keepass") { databaseFileCreatedUri ->
|
||||
mDatabaseFileUri = databaseFileCreatedUri
|
||||
if (mDatabaseFileUri != null) {
|
||||
AssignMasterKeyDialogFragment.getInstance(true)
|
||||
.show(supportFragmentManager, "passwordDialog")
|
||||
} else {
|
||||
val error = getString(R.string.error_create_database)
|
||||
Snackbar.make(coordinatorLayout, error, Snackbar.LENGTH_LONG).asError().show()
|
||||
Log.e(TAG, error)
|
||||
}
|
||||
}
|
||||
openDatabaseButtonView = findViewById(R.id.open_keyfile_button)
|
||||
openDatabaseButtonView?.setOpenDocumentClickListener(mExternalFileHelper)
|
||||
|
||||
@@ -250,8 +279,9 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
||||
* Create a new file by calling the content provider
|
||||
*/
|
||||
private fun createNewFile() {
|
||||
mExternalFileHelper?.createDocument( getString(R.string.database_file_name_default) +
|
||||
getString(R.string.database_file_extension_default), "application/x-keepass")
|
||||
mExternalFileHelper?.createDocument(
|
||||
getString(R.string.database_file_name_default) +
|
||||
getString(R.string.database_file_extension_default))
|
||||
}
|
||||
|
||||
private fun fileNoFoundAction(e: FileNotFoundException) {
|
||||
@@ -268,7 +298,8 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
||||
fileNoFoundAction(exception)
|
||||
},
|
||||
{ onCancelSpecialMode() },
|
||||
{ onLaunchActivitySpecialMode() })
|
||||
{ onLaunchActivitySpecialMode() },
|
||||
mAutofillActivityResultLauncher)
|
||||
}
|
||||
|
||||
private fun launchGroupActivityIfLoaded(database: Database) {
|
||||
@@ -277,7 +308,8 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
||||
database,
|
||||
{ onValidateSpecialMode() },
|
||||
{ onCancelSpecialMode() },
|
||||
{ onLaunchActivitySpecialMode() })
|
||||
{ onLaunchActivitySpecialMode() },
|
||||
mAutofillActivityResultLauncher)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,33 +385,6 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
||||
|
||||
override fun onAssignKeyDialogNegativeClick(mainCredential: MainCredential) {}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
mExternalFileHelper?.onOpenDocumentResult(requestCode, resultCode, data) { uri ->
|
||||
if (uri != null) {
|
||||
launchPasswordActivityWithPath(uri)
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve the created URI from the file manager
|
||||
mExternalFileHelper?.onCreateDocumentResult(requestCode, resultCode, data) { databaseFileCreatedUri ->
|
||||
mDatabaseFileUri = databaseFileCreatedUri
|
||||
if (mDatabaseFileUri != null) {
|
||||
AssignMasterKeyDialogFragment.getInstance(true)
|
||||
.show(supportFragmentManager, "passwordDialog")
|
||||
} else {
|
||||
val error = getString(R.string.error_create_database)
|
||||
Snackbar.make(coordinatorLayout, error, Snackbar.LENGTH_LONG).asError().show()
|
||||
Log.e(TAG, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
super.onCreateOptionsMenu(menu)
|
||||
|
||||
@@ -493,11 +498,13 @@ class FileDatabaseSelectActivity : DatabaseModeActivity(),
|
||||
*/
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
fun launchForAutofillResult(activity: Activity,
|
||||
fun launchForAutofillResult(activity: AppCompatActivity,
|
||||
activityResultLauncher: ActivityResultLauncher<Intent>?,
|
||||
autofillComponent: AutofillComponent,
|
||||
searchInfo: SearchInfo? = null) {
|
||||
AutofillHelper.startActivityForAutofillResult(activity,
|
||||
Intent(activity, FileDatabaseSelectActivity::class.java),
|
||||
activityResultLauncher,
|
||||
autofillComponent,
|
||||
searchInfo)
|
||||
}
|
||||
|
||||
@@ -33,8 +33,10 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
@@ -111,6 +113,16 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
private var mSearchSuggestionAdapter: SearchEntryCursorAdapter? = null
|
||||
private var mOnSuggestionListener: SearchView.OnSuggestionListener? = null
|
||||
|
||||
private var mIconSelectionActivityResultLauncher = IconPickerActivity.registerIconSelectionForResult(this) { icon ->
|
||||
// To create tree dialog for icon
|
||||
mGroupEditViewModel.selectIcon(icon)
|
||||
}
|
||||
|
||||
private var mAutofillActivityResultLauncher: ActivityResultLauncher<Intent>? =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
AutofillHelper.buildActivityResultLauncher(this)
|
||||
else null
|
||||
|
||||
private var mIconColor: Int = 0
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -211,11 +223,14 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
mDatabase?.let { database ->
|
||||
EntrySelectionHelper.doSpecialAction(intent,
|
||||
{
|
||||
EntryEditActivity.launchToCreate(
|
||||
this@GroupActivity,
|
||||
database,
|
||||
currentGroup.nodeId
|
||||
)
|
||||
mGroupFragment?.mEntryActivityResultLauncher?.let { resultLauncher ->
|
||||
EntryEditActivity.launchToCreate(
|
||||
this@GroupActivity,
|
||||
database,
|
||||
currentGroup.nodeId,
|
||||
resultLauncher
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
// Search not used
|
||||
@@ -243,6 +258,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
EntryEditActivity.launchForAutofillResult(
|
||||
this@GroupActivity,
|
||||
database,
|
||||
mAutofillActivityResultLauncher,
|
||||
autofillComponent,
|
||||
currentGroup.nodeId,
|
||||
searchInfo
|
||||
@@ -277,7 +293,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
}
|
||||
|
||||
mGroupEditViewModel.requestIconSelection.observe(this) { iconImage ->
|
||||
IconPickerActivity.launch(this@GroupActivity, iconImage)
|
||||
IconPickerActivity.launch(this@GroupActivity, iconImage, mIconSelectionActivityResultLauncher)
|
||||
}
|
||||
|
||||
mGroupEditViewModel.requestDateTimeSelection.observe(this) { dateInstant ->
|
||||
@@ -594,11 +610,14 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
val entryVersioned = node as Entry
|
||||
EntrySelectionHelper.doSpecialAction(intent,
|
||||
{
|
||||
EntryActivity.launch(
|
||||
this@GroupActivity,
|
||||
database,
|
||||
entryVersioned.nodeId
|
||||
)
|
||||
mGroupFragment?.mEntryActivityResultLauncher?.let { resultLauncher ->
|
||||
EntryActivity.launch(
|
||||
this@GroupActivity,
|
||||
database,
|
||||
entryVersioned.nodeId,
|
||||
resultLauncher
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
// Nothing here, a search is simply performed
|
||||
@@ -653,6 +672,8 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
Log.e(TAG, "Node can't be cast in Entry")
|
||||
}
|
||||
}
|
||||
|
||||
reloadGroupIfSearch()
|
||||
}
|
||||
|
||||
private fun entrySelectedForSave(database: Database, entry: Entry, searchInfo: SearchInfo) {
|
||||
@@ -738,6 +759,12 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
actionNodeMode?.finish()
|
||||
}
|
||||
|
||||
private fun reloadGroupIfSearch() {
|
||||
if (Intent.ACTION_SEARCH == intent.action) {
|
||||
reloadCurrentGroup()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNodeSelected(
|
||||
database: Database,
|
||||
nodes: List<Node>
|
||||
@@ -787,12 +814,18 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
GroupEditDialogFragment.TAG_CREATE_GROUP
|
||||
)
|
||||
}
|
||||
Type.ENTRY -> EntryEditActivity.launchToUpdate(
|
||||
this@GroupActivity,
|
||||
database,
|
||||
(node as Entry).nodeId
|
||||
)
|
||||
Type.ENTRY -> {
|
||||
mGroupFragment?.mEntryActivityResultLauncher?.let { resultLauncher ->
|
||||
EntryEditActivity.launchToUpdate(
|
||||
this@GroupActivity,
|
||||
database,
|
||||
(node as Entry).nodeId,
|
||||
resultLauncher
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
reloadGroupIfSearch()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -847,6 +880,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
): Boolean {
|
||||
deleteNodes(nodes)
|
||||
finishNodeAction()
|
||||
reloadGroupIfSearch()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1047,6 +1081,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun startActivityForResult(intent: Intent, requestCode: Int, options: Bundle?) {
|
||||
/*
|
||||
* ACTION_SEARCH automatically forces a new task. This occurs when you open a kdb file in
|
||||
@@ -1062,22 +1097,6 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
super.startActivityForResult(intent, requestCode, options)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
// To create tree dialog for icon
|
||||
IconPickerActivity.onActivityResult(requestCode, resultCode, data) { icon ->
|
||||
mGroupEditViewModel.selectIcon(icon)
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
// Directly used the onActivityResult in fragment
|
||||
mGroupFragment?.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
private fun removeSearch() {
|
||||
intent.removeExtra(AUTO_SEARCH_KEY)
|
||||
if (Intent.ACTION_SEARCH == intent.action) {
|
||||
@@ -1093,7 +1112,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
try {
|
||||
mGroupViewModel.loadGroup(mDatabase, mCurrentGroupState)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to rebuild the list after deletion", e)
|
||||
Log.e(TAG, "Unable to rebuild the group", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1282,8 +1301,9 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
* -------------------------
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
fun launchForAutofillResult(activity: Activity,
|
||||
fun launchForAutofillResult(activity: AppCompatActivity,
|
||||
database: Database,
|
||||
activityResultLaunch: ActivityResultLauncher<Intent>?,
|
||||
autofillComponent: AutofillComponent,
|
||||
searchInfo: SearchInfo? = null,
|
||||
autoSearch: Boolean = false) {
|
||||
@@ -1293,6 +1313,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
AutofillHelper.startActivityForAutofillResult(
|
||||
activity,
|
||||
intent,
|
||||
activityResultLaunch,
|
||||
autofillComponent,
|
||||
searchInfo
|
||||
)
|
||||
@@ -1325,11 +1346,12 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
* Global Launch
|
||||
* -------------------------
|
||||
*/
|
||||
fun launch(activity: Activity,
|
||||
fun launch(activity: AppCompatActivity,
|
||||
database: Database,
|
||||
onValidateSpecialMode: () -> Unit,
|
||||
onCancelSpecialMode: () -> Unit,
|
||||
onLaunchActivitySpecialMode: () -> Unit) {
|
||||
onLaunchActivitySpecialMode: () -> Unit,
|
||||
autofillActivityResultLauncher: ActivityResultLauncher<Intent>?) {
|
||||
EntrySelectionHelper.doSpecialAction(activity.intent,
|
||||
{
|
||||
GroupActivity.launch(
|
||||
@@ -1441,6 +1463,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
// Here no search info found, disable auto search
|
||||
GroupActivity.launchForAutofillResult(activity,
|
||||
database,
|
||||
autofillActivityResultLauncher,
|
||||
autofillComponent,
|
||||
searchInfo,
|
||||
false)
|
||||
|
||||
@@ -27,12 +27,16 @@ import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.commit
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.dialogs.IconEditDialogFragment
|
||||
import com.kunzisoft.keepass.activities.fragments.IconPickerFragment
|
||||
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
||||
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
|
||||
@@ -81,6 +85,9 @@ class IconPickerActivity : DatabaseLockActivity() {
|
||||
coordinatorLayout = findViewById(R.id.icon_picker_coordinator)
|
||||
|
||||
mExternalFileHelper = ExternalFileHelper(this)
|
||||
mExternalFileHelper?.buildOpenDocument { uri ->
|
||||
addCustomIcon(uri)
|
||||
}
|
||||
|
||||
uploadButton = findViewById(R.id.icon_picker_upload)
|
||||
|
||||
@@ -139,6 +146,16 @@ class IconPickerActivity : DatabaseLockActivity() {
|
||||
}
|
||||
uploadButton.isEnabled = true
|
||||
}
|
||||
iconPickerViewModel.customIconUpdated.observe(this) { iconCustomUpdated ->
|
||||
if (iconCustomUpdated.error && !iconCustomUpdated.errorConsumed) {
|
||||
Snackbar.make(coordinatorLayout, iconCustomUpdated.errorStringId, Snackbar.LENGTH_LONG).asError().show()
|
||||
iconCustomUpdated.errorConsumed = true
|
||||
}
|
||||
iconCustomUpdated.iconCustom?.let {
|
||||
mDatabase?.updateCustomIcon(it)
|
||||
}
|
||||
iconPickerViewModel.deselectAllCustomIcons()
|
||||
}
|
||||
}
|
||||
|
||||
override fun viewToInvalidateTimeout(): View? {
|
||||
@@ -197,6 +214,10 @@ class IconPickerActivity : DatabaseLockActivity() {
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
|
||||
menu?.findItem(R.id.menu_edit)?.apply {
|
||||
isEnabled = mIconsSelected.size == 1
|
||||
isVisible = isEnabled
|
||||
}
|
||||
menu?.findItem(R.id.menu_delete)?.apply {
|
||||
isEnabled = mCustomIconsSelectionMode
|
||||
isVisible = isEnabled
|
||||
@@ -213,6 +234,9 @@ class IconPickerActivity : DatabaseLockActivity() {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
R.id.menu_edit -> {
|
||||
updateCustomIcon(mIconsSelected[0])
|
||||
}
|
||||
R.id.menu_delete -> {
|
||||
mIconsSelected.forEach { iconToRemove ->
|
||||
removeCustomIcon(iconToRemove)
|
||||
@@ -277,6 +301,11 @@ class IconPickerActivity : DatabaseLockActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCustomIcon(iconImageCustom: IconImageCustom) {
|
||||
IconEditDialogFragment.update(iconImageCustom)
|
||||
.show(supportFragmentManager, IconEditDialogFragment.TAG_UPDATE_ICON)
|
||||
}
|
||||
|
||||
private fun removeCustomIcon(iconImageCustom: IconImageCustom) {
|
||||
uploadButton.isEnabled = false
|
||||
iconPickerViewModel.deselectAllCustomIcons()
|
||||
@@ -286,14 +315,6 @@ class IconPickerActivity : DatabaseLockActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
mExternalFileHelper?.onOpenDocumentResult(requestCode, resultCode, data) { uri ->
|
||||
addCustomIcon(uri)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setResult() {
|
||||
setResult(Activity.RESULT_OK, Intent().apply {
|
||||
putExtra(EXTRA_ICON, mIconImage)
|
||||
@@ -308,30 +329,28 @@ class IconPickerActivity : DatabaseLockActivity() {
|
||||
companion object {
|
||||
|
||||
private const val ICON_PICKER_FRAGMENT_TAG = "ICON_PICKER_FRAGMENT_TAG"
|
||||
|
||||
private const val ICON_SELECTED_REQUEST = 15861
|
||||
private const val EXTRA_ICON = "EXTRA_ICON"
|
||||
|
||||
private const val MAX_ICON_SIZE = 5242880
|
||||
|
||||
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?, listener: (icon: IconImage) -> Unit) {
|
||||
if (requestCode == ICON_SELECTED_REQUEST) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
listener.invoke(data?.getParcelableExtra(EXTRA_ICON) ?: IconImage())
|
||||
fun registerIconSelectionForResult(context: FragmentActivity,
|
||||
listener: (icon: IconImage) -> Unit): ActivityResultLauncher<Intent> {
|
||||
return context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
listener.invoke(result.data?.getParcelableExtra(EXTRA_ICON) ?: IconImage())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun launch(context: Activity,
|
||||
previousIcon: IconImage?) {
|
||||
fun launch(context: FragmentActivity,
|
||||
previousIcon: IconImage?,
|
||||
resultLauncher: ActivityResultLauncher<Intent>) {
|
||||
// Create an instance to return the picker icon
|
||||
context.startActivityForResult(
|
||||
Intent(context,
|
||||
IconPickerActivity::class.java).apply {
|
||||
resultLauncher.launch(
|
||||
Intent(context, IconPickerActivity::class.java).apply {
|
||||
if (previousIcon != null)
|
||||
putExtra(EXTRA_ICON, previousIcon)
|
||||
},
|
||||
ICON_SELECTED_REQUEST)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,10 @@ import android.view.KeyEvent.KEYCODE_ENTER
|
||||
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.*
|
||||
import android.widget.TextView.OnEditorActionListener
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
@@ -71,11 +72,12 @@ import com.kunzisoft.keepass.utils.MenuUtil
|
||||
import com.kunzisoft.keepass.utils.UriUtil
|
||||
import com.kunzisoft.keepass.view.KeyFileSelectionView
|
||||
import com.kunzisoft.keepass.view.asError
|
||||
import com.kunzisoft.keepass.viewmodels.AdvancedUnlockViewModel
|
||||
import com.kunzisoft.keepass.viewmodels.DatabaseFileViewModel
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
|
||||
open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.BuilderListener {
|
||||
class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.BuilderListener {
|
||||
|
||||
// Views
|
||||
private var toolbar: Toolbar? = null
|
||||
@@ -89,7 +91,8 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
private lateinit var coordinatorLayout: CoordinatorLayout
|
||||
private var advancedUnlockFragment: AdvancedUnlockFragment? = null
|
||||
|
||||
private val databaseFileViewModel: DatabaseFileViewModel by viewModels()
|
||||
private val mDatabaseFileViewModel: DatabaseFileViewModel by viewModels()
|
||||
private val mAdvancedUnlockViewModel: AdvancedUnlockViewModel by viewModels()
|
||||
|
||||
private var mDefaultDatabase: Boolean = false
|
||||
private var mDatabaseFileUri: Uri? = null
|
||||
@@ -111,7 +114,10 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
field = value
|
||||
}
|
||||
|
||||
private var mAllowAutoOpenBiometricPrompt: Boolean = true
|
||||
private var mAutofillActivityResultLauncher: ActivityResultLauncher<Intent>? =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
AutofillHelper.buildActivityResultLauncher(this)
|
||||
else null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -142,6 +148,12 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this)
|
||||
|
||||
mExternalFileHelper = ExternalFileHelper(this@PasswordActivity)
|
||||
mExternalFileHelper?.buildOpenDocument { uri ->
|
||||
if (uri != null) {
|
||||
mDatabaseKeyFileUri = uri
|
||||
populateKeyFileTextView(uri)
|
||||
}
|
||||
}
|
||||
keyFileSelectionView?.setOpenDocumentClickListener(mExternalFileHelper)
|
||||
|
||||
passwordView?.setOnEditorActionListener(onEditorActionListener)
|
||||
@@ -170,9 +182,6 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
if (savedInstanceState?.containsKey(KEY_KEYFILE) == true) {
|
||||
mDatabaseKeyFileUri = UriUtil.parse(savedInstanceState.getString(KEY_KEYFILE))
|
||||
}
|
||||
if (savedInstanceState?.containsKey(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT) == true) {
|
||||
mAllowAutoOpenBiometricPrompt = savedInstanceState.getBoolean(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT)
|
||||
}
|
||||
|
||||
// Init Biometric elements
|
||||
advancedUnlockFragment = supportFragmentManager
|
||||
@@ -188,17 +197,17 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
|
||||
// Listen password checkbox to init advanced unlock and confirmation button
|
||||
checkboxPasswordView?.setOnCheckedChangeListener { _, _ ->
|
||||
advancedUnlockFragment?.checkUnlockAvailability()
|
||||
mAdvancedUnlockViewModel.checkUnlockAvailability()
|
||||
enableOrNotTheConfirmationButton()
|
||||
}
|
||||
|
||||
// Observe if default database
|
||||
databaseFileViewModel.isDefaultDatabase.observe(this) { isDefaultDatabase ->
|
||||
mDatabaseFileViewModel.isDefaultDatabase.observe(this) { isDefaultDatabase ->
|
||||
mDefaultDatabase = isDefaultDatabase
|
||||
}
|
||||
|
||||
// Observe database file change
|
||||
databaseFileViewModel.databaseFileLoaded.observe(this) { databaseFile ->
|
||||
mDatabaseFileViewModel.databaseFileLoaded.observe(this) { databaseFile ->
|
||||
// Force read only if the file does not exists
|
||||
mForceReadOnly = databaseFile?.let {
|
||||
!it.databaseFileExists
|
||||
@@ -232,12 +241,12 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
}
|
||||
|
||||
// Don't allow auto open prompt if lock become when UI visible
|
||||
mAllowAutoOpenBiometricPrompt = if (DatabaseLockActivity.LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK == true)
|
||||
false
|
||||
else
|
||||
mAllowAutoOpenBiometricPrompt
|
||||
if (DatabaseLockActivity.LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK == true) {
|
||||
mAdvancedUnlockViewModel.allowAutoOpenBiometricPrompt = false
|
||||
}
|
||||
|
||||
mDatabaseFileUri?.let { databaseFileUri ->
|
||||
databaseFileViewModel.loadDatabaseFile(databaseFileUri)
|
||||
mDatabaseFileViewModel.loadDatabaseFile(databaseFileUri)
|
||||
}
|
||||
|
||||
checkPermission()
|
||||
@@ -263,7 +272,7 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
when (actionTask) {
|
||||
ACTION_DATABASE_LOAD_TASK -> {
|
||||
// Recheck advanced unlock if error
|
||||
advancedUnlockFragment?.initAdvancedUnlockMode()
|
||||
mAdvancedUnlockViewModel.initAdvancedUnlockMode()
|
||||
|
||||
if (result.isSuccess) {
|
||||
launchGroupActivityIfLoaded(database)
|
||||
@@ -311,7 +320,7 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
is FileNotFoundDatabaseException -> {
|
||||
// Remove this default database inaccessible
|
||||
if (mDefaultDatabase) {
|
||||
databaseFileViewModel.removeDefaultDatabase()
|
||||
mDatabaseFileViewModel.removeDefaultDatabase()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,7 +353,7 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
mDatabaseKeyFileUri = intent?.getParcelableExtra(KEY_KEYFILE)
|
||||
}
|
||||
mDatabaseFileUri?.let {
|
||||
databaseFileViewModel.checkIfIsDefaultDatabase(it)
|
||||
mDatabaseFileViewModel.checkIfIsDefaultDatabase(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +370,8 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
database,
|
||||
{ onValidateSpecialMode() },
|
||||
{ onCancelSpecialMode() },
|
||||
{ onLaunchActivitySpecialMode() }
|
||||
{ onLaunchActivitySpecialMode() },
|
||||
mAutofillActivityResultLauncher
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -435,8 +445,7 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
verifyCheckboxesAndLoadDatabase(password, keyFileUri)
|
||||
} else {
|
||||
// Init Biometric elements
|
||||
advancedUnlockFragment?.loadDatabase(databaseFileUri,
|
||||
mAllowAutoOpenBiometricPrompt)
|
||||
mAdvancedUnlockViewModel.databaseFileLoaded(databaseFileUri)
|
||||
}
|
||||
|
||||
enableOrNotTheConfirmationButton()
|
||||
@@ -496,7 +505,6 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
override fun onPause() {
|
||||
// Reinit locking activity UI variable
|
||||
DatabaseLockActivity.LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK = null
|
||||
mAllowAutoOpenBiometricPrompt = true
|
||||
|
||||
super.onPause()
|
||||
}
|
||||
@@ -507,7 +515,6 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
outState.putString(KEY_KEYFILE, it.toString())
|
||||
}
|
||||
outState.putBoolean(KEY_READ_ONLY, mReadOnly)
|
||||
outState.putBoolean(ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT, false)
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
@@ -709,45 +716,6 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onActivityResult(
|
||||
requestCode: Int,
|
||||
resultCode: Int,
|
||||
data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
mAllowAutoOpenBiometricPrompt = false
|
||||
|
||||
// To get device credential unlock result
|
||||
advancedUnlockFragment?.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
// To get entry in result
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
var keyFileResult = false
|
||||
mExternalFileHelper?.let {
|
||||
keyFileResult = it.onOpenDocumentResult(requestCode, resultCode, data) { uri ->
|
||||
if (uri != null) {
|
||||
mDatabaseKeyFileUri = uri
|
||||
populateKeyFileTextView(uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!keyFileResult) {
|
||||
// this block if not a key file response
|
||||
when (resultCode) {
|
||||
DatabaseLockActivity.RESULT_EXIT_LOCK -> {
|
||||
clearCredentialsViews()
|
||||
closeDatabase()
|
||||
}
|
||||
Activity.RESULT_CANCELED -> {
|
||||
clearCredentialsViews()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val TAG = PasswordActivity::class.java.name
|
||||
@@ -764,8 +732,6 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
private const val KEY_PERMISSION_ASKED = "KEY_PERMISSION_ASKED"
|
||||
private const val WRITE_EXTERNAL_STORAGE_REQUEST = 647
|
||||
|
||||
private const val ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT = "ALLOW_AUTO_OPEN_BIOMETRIC_PROMPT"
|
||||
|
||||
private fun buildAndLaunchIntent(activity: Activity, databaseFile: Uri, keyFile: Uri?,
|
||||
intentBuildLauncher: (Intent) -> Unit) {
|
||||
val intent = Intent(activity, PasswordActivity::class.java)
|
||||
@@ -855,15 +821,17 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
@Throws(FileNotFoundException::class)
|
||||
fun launchForAutofillResult(activity: Activity,
|
||||
fun launchForAutofillResult(activity: AppCompatActivity,
|
||||
databaseFile: Uri,
|
||||
keyFile: Uri?,
|
||||
activityResultLauncher: ActivityResultLauncher<Intent>?,
|
||||
autofillComponent: AutofillComponent,
|
||||
searchInfo: SearchInfo?) {
|
||||
buildAndLaunchIntent(activity, databaseFile, keyFile) { intent ->
|
||||
AutofillHelper.startActivityForAutofillResult(
|
||||
activity,
|
||||
intent,
|
||||
activityResultLauncher,
|
||||
autofillComponent,
|
||||
searchInfo)
|
||||
}
|
||||
@@ -891,12 +859,13 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
* Global Launch
|
||||
* -------------------------
|
||||
*/
|
||||
fun launch(activity: Activity,
|
||||
fun launch(activity: AppCompatActivity,
|
||||
databaseUri: Uri,
|
||||
keyFile: Uri?,
|
||||
fileNoFoundAction: (exception: FileNotFoundException) -> Unit,
|
||||
onCancelSpecialMode: () -> Unit,
|
||||
onLaunchActivitySpecialMode: () -> Unit) {
|
||||
onLaunchActivitySpecialMode: () -> Unit,
|
||||
autofillActivityResultLauncher: ActivityResultLauncher<Intent>?) {
|
||||
|
||||
try {
|
||||
EntrySelectionHelper.doSpecialAction(activity.intent,
|
||||
@@ -926,6 +895,7 @@ open class PasswordActivity : DatabaseModeActivity(), AdvancedUnlockFragment.Bui
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
PasswordActivity.launchForAutofillResult(activity,
|
||||
databaseUri, keyFile,
|
||||
autofillActivityResultLauncher,
|
||||
autofillComponent,
|
||||
searchInfo)
|
||||
onLaunchActivitySpecialMode()
|
||||
|
||||
@@ -22,7 +22,6 @@ package com.kunzisoft.keepass.activities.dialogs
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
@@ -133,6 +132,18 @@ class AssignMasterKeyDialogFragment : DatabaseDialogFragment() {
|
||||
keyFileSelectionView = rootView?.findViewById(R.id.keyfile_selection)
|
||||
|
||||
mExternalFileHelper = ExternalFileHelper(this)
|
||||
mExternalFileHelper?.buildOpenDocument { uri ->
|
||||
uri?.let { pathUri ->
|
||||
UriUtil.getFileData(requireContext(), uri)?.length()?.let { lengthFile ->
|
||||
keyFileSelectionView?.error = null
|
||||
keyFileCheckBox?.isChecked = true
|
||||
keyFileSelectionView?.uri = pathUri
|
||||
if (lengthFile <= 0L) {
|
||||
showEmptyKeyFileConfirmationDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
keyFileSelectionView?.setOpenDocumentClickListener(mExternalFileHelper)
|
||||
|
||||
val dialog = builder.create()
|
||||
@@ -208,7 +219,11 @@ class AssignMasterKeyDialogFragment : DatabaseDialogFragment() {
|
||||
passwordRepeatTextInputLayout?.error = getString(R.string.error_pass_match)
|
||||
}
|
||||
|
||||
if (mMasterPassword == null || mMasterPassword!!.isEmpty()) {
|
||||
if ((mMasterPassword == null
|
||||
|| mMasterPassword!!.isEmpty())
|
||||
&& (keyFileCheckBox == null
|
||||
|| !keyFileCheckBox!!.isChecked
|
||||
|| keyFileSelectionView?.uri == null)) {
|
||||
error = true
|
||||
showEmptyPasswordConfirmationDialog()
|
||||
}
|
||||
@@ -282,23 +297,6 @@ class AssignMasterKeyDialogFragment : DatabaseDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
mExternalFileHelper?.onOpenDocumentResult(requestCode, resultCode, data) { uri ->
|
||||
uri?.let { pathUri ->
|
||||
UriUtil.getFileData(requireContext(), uri)?.length()?.let { lengthFile ->
|
||||
keyFileSelectionView?.error = null
|
||||
keyFileCheckBox?.isChecked = true
|
||||
keyFileSelectionView?.uri = pathUri
|
||||
if (lengthFile <= 0L) {
|
||||
showEmptyKeyFileConfirmationDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ALLOW_NO_MASTER_KEY_ARG = "ALLOW_NO_MASTER_KEY_ARG"
|
||||
|
||||
@@ -29,6 +29,7 @@ abstract class DatabaseDialogFragment : DialogFragment(), DatabaseRetrieval {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2021 Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePassDX.
|
||||
*
|
||||
* KeePassDX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePassDX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.activities.dialogs
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
|
||||
import com.kunzisoft.keepass.viewmodels.IconPickerViewModel
|
||||
|
||||
class IconEditDialogFragment : DatabaseDialogFragment() {
|
||||
|
||||
private val mIconPickerViewModel: IconPickerViewModel by activityViewModels()
|
||||
|
||||
private var mPopulateIconMethod: ((ImageView, IconImage) -> Unit)? = null
|
||||
private lateinit var iconView: ImageView
|
||||
private lateinit var nameTextLayoutView: TextInputLayout
|
||||
private lateinit var nameTextView: TextView
|
||||
|
||||
private var mCustomIcon: IconImageCustom? = null
|
||||
|
||||
override fun onDatabaseRetrieved(database: Database?) {
|
||||
super.onDatabaseRetrieved(database)
|
||||
mPopulateIconMethod = { imageView, icon ->
|
||||
database?.iconDrawableFactory?.assignDatabaseIcon(imageView, icon)
|
||||
}
|
||||
mCustomIcon?.let { customIcon ->
|
||||
populateViewsWithCustomIcon(customIcon)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
activity?.let { activity ->
|
||||
val root = activity.layoutInflater.inflate(R.layout.fragment_icon_edit, null)
|
||||
iconView = root.findViewById(R.id.icon_edit_image)
|
||||
nameTextLayoutView = root.findViewById(R.id.icon_edit_name_container)
|
||||
nameTextView = root.findViewById(R.id.icon_edit_name)
|
||||
|
||||
if (savedInstanceState != null
|
||||
&& savedInstanceState.containsKey(KEY_CUSTOM_ICON_ID)) {
|
||||
mCustomIcon = savedInstanceState.getParcelable(KEY_CUSTOM_ICON_ID) ?: mCustomIcon
|
||||
} else {
|
||||
arguments?.apply {
|
||||
if (containsKey(KEY_CUSTOM_ICON_ID)) {
|
||||
mCustomIcon = getParcelable(KEY_CUSTOM_ICON_ID) ?: mCustomIcon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val builder = AlertDialog.Builder(activity)
|
||||
builder.setView(root)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
retrieveIconInfoFromViews()
|
||||
mCustomIcon?.let { customIcon ->
|
||||
mIconPickerViewModel.updateCustomIcon(
|
||||
IconPickerViewModel.IconCustomState(customIcon, false)
|
||||
)
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ ->
|
||||
// Do nothing
|
||||
mIconPickerViewModel.updateCustomIcon(
|
||||
IconPickerViewModel.IconCustomState(null, false)
|
||||
)
|
||||
}
|
||||
|
||||
return builder.create()
|
||||
}
|
||||
return super.onCreateDialog(savedInstanceState)
|
||||
}
|
||||
|
||||
private fun populateViewsWithCustomIcon(customIcon: IconImageCustom) {
|
||||
mPopulateIconMethod?.invoke(iconView, customIcon.getIconImageToDraw())
|
||||
nameTextView.text = customIcon.name
|
||||
}
|
||||
|
||||
private fun retrieveIconInfoFromViews() {
|
||||
mCustomIcon?.name = nameTextView.text.toString()
|
||||
mCustomIcon?.lastModificationTime = DateInstant()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
retrieveIconInfoFromViews()
|
||||
outState.putParcelable(KEY_CUSTOM_ICON_ID, mCustomIcon)
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val TAG_UPDATE_ICON = "TAG_UPDATE_ICON"
|
||||
const val KEY_CUSTOM_ICON_ID = "KEY_CUSTOM_ICON_ID"
|
||||
|
||||
fun update(customIcon: IconImageCustom): IconEditDialogFragment {
|
||||
val bundle = Bundle()
|
||||
bundle.putParcelable(KEY_CUSTOM_ICON_ID, IconImageCustom(customIcon))
|
||||
val fragment = IconEditDialogFragment()
|
||||
fragment.arguments = bundle
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,7 +309,7 @@ class SetOTPDialogFragment : DatabaseDialogFragment() {
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
s?.toString()?.let { userString ->
|
||||
try {
|
||||
mOtpElement.setBase32Secret(userString.toUpperCase(Locale.ENGLISH))
|
||||
mOtpElement.setBase32Secret(userString.uppercase(Locale.ENGLISH))
|
||||
otpSecretContainer?.error = null
|
||||
} catch (exception: Exception) {
|
||||
otpSecretContainer?.error = getString(R.string.error_otp_secret_key)
|
||||
|
||||
@@ -74,6 +74,19 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
|
||||
private var mRecycleBinEnable: Boolean = false
|
||||
private var mRecycleBin: Group? = null
|
||||
|
||||
var mEntryActivityResultLauncher = EntryEditActivity.registerForEntryResult(this) { entryId ->
|
||||
entryId?.let {
|
||||
// Simply refresh the list
|
||||
rebuildList()
|
||||
// Scroll to the new entry
|
||||
mDatabase?.getEntryById(it)?.let { entry ->
|
||||
mAdapter?.indexOf(entry)?.let { position ->
|
||||
mNodesRecyclerView?.scrollToPosition(position)
|
||||
}
|
||||
}
|
||||
} ?: Log.e(this.javaClass.name, "Entry cannot be retrieved in Activity Result")
|
||||
}
|
||||
|
||||
private var mRecycleViewScrollListener = object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
@@ -399,27 +412,6 @@ class GroupFragment : DatabaseFragment(), SortDialogFragment.SortSelectionListen
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
when (requestCode) {
|
||||
EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE -> {
|
||||
if (resultCode == EntryEditActivity.ADD_OR_UPDATE_ENTRY_RESULT_CODE) {
|
||||
data?.getParcelableExtra<NodeId<UUID>>(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY)?.let {
|
||||
// Simply refresh the list
|
||||
rebuildList()
|
||||
// Scroll to the new entry
|
||||
mDatabase?.getEntryById(it)?.let { entry ->
|
||||
mAdapter?.indexOf(entry)?.let { position ->
|
||||
mNodesRecyclerView?.scrollToPosition(position)
|
||||
}
|
||||
}
|
||||
} ?: Log.e(this.javaClass.name, "Entry cannot be retrieved in Activity Result")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback listener to redefine to do an action when a node is click
|
||||
*/
|
||||
|
||||
@@ -55,8 +55,10 @@ class IconCustomFragment : IconFragment<IconImageCustom>() {
|
||||
iconCustomAdded?.iconCustom?.let { icon ->
|
||||
iconPickerAdapter.addIcon(icon)
|
||||
iconCustomAdded.iconCustom = null
|
||||
try {
|
||||
iconsGridView.smoothScrollToPosition(iconPickerAdapter.lastPosition)
|
||||
} catch (ignore: Exception) {}
|
||||
}
|
||||
iconsGridView.smoothScrollToPosition(iconPickerAdapter.lastPosition)
|
||||
}
|
||||
}
|
||||
iconPickerViewModel.customIconRemoved.observe(viewLifecycleOwner) { iconCustomRemoved ->
|
||||
@@ -67,6 +69,14 @@ class IconCustomFragment : IconFragment<IconImageCustom>() {
|
||||
}
|
||||
}
|
||||
}
|
||||
iconPickerViewModel.customIconUpdated.observe(viewLifecycleOwner) { iconCustomUpdated ->
|
||||
if (!iconCustomUpdated.error) {
|
||||
iconCustomUpdated?.iconCustom?.let { icon ->
|
||||
iconPickerAdapter.updateIcon(icon)
|
||||
iconCustomUpdated.iconCustom = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onIconClickListener(icon: IconImageCustom) {
|
||||
|
||||
@@ -20,14 +20,16 @@
|
||||
package com.kunzisoft.keepass.activities.helpers
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.activity.result.ActivityResultCallback
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.kunzisoft.keepass.activities.dialogs.FileManagerDialogFragment
|
||||
@@ -38,6 +40,10 @@ class ExternalFileHelper {
|
||||
private var activity: FragmentActivity? = null
|
||||
private var fragment: Fragment? = null
|
||||
|
||||
private var getContentResultLauncher: ActivityResultLauncher<String>? = null
|
||||
private var openDocumentResultLauncher: ActivityResultLauncher<Array<String>>? = null
|
||||
private var createDocumentResultLauncher: ActivityResultLauncher<String>? = null
|
||||
|
||||
constructor(context: FragmentActivity) {
|
||||
this.activity = context
|
||||
this.fragment = null
|
||||
@@ -48,94 +54,81 @@ class ExternalFileHelper {
|
||||
this.fragment = context
|
||||
}
|
||||
|
||||
fun buildOpenDocument(onFileSelected: ((uri: Uri?) -> Unit)?) {
|
||||
|
||||
val resultCallback = ActivityResultCallback<Uri> { result ->
|
||||
result?.let { uri ->
|
||||
UriUtil.takeUriPermission(activity?.contentResolver, uri)
|
||||
onFileSelected?.invoke(uri)
|
||||
}
|
||||
}
|
||||
|
||||
getContentResultLauncher = if (fragment != null) {
|
||||
fragment?.registerForActivityResult(
|
||||
GetContent(),
|
||||
resultCallback
|
||||
)
|
||||
} else {
|
||||
activity?.registerForActivityResult(
|
||||
GetContent(),
|
||||
resultCallback
|
||||
)
|
||||
}
|
||||
|
||||
openDocumentResultLauncher = if (fragment != null) {
|
||||
fragment?.registerForActivityResult(
|
||||
OpenDocument(),
|
||||
resultCallback
|
||||
)
|
||||
} else {
|
||||
activity?.registerForActivityResult(
|
||||
OpenDocument(),
|
||||
resultCallback
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun buildCreateDocument(typeString: String = "application/octet-stream",
|
||||
onFileCreated: (fileCreated: Uri?)->Unit) {
|
||||
|
||||
val resultCallback = ActivityResultCallback<Uri> { result ->
|
||||
onFileCreated.invoke(result)
|
||||
}
|
||||
|
||||
createDocumentResultLauncher = if (fragment != null) {
|
||||
fragment?.registerForActivityResult(
|
||||
CreateDocument(typeString),
|
||||
resultCallback
|
||||
)
|
||||
} else {
|
||||
activity?.registerForActivityResult(
|
||||
CreateDocument(typeString),
|
||||
resultCallback
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun openDocument(getContent: Boolean = false,
|
||||
typeString: String = "*/*") {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
try {
|
||||
if (getContent) {
|
||||
openActivityWithActionGetContent(typeString)
|
||||
} else {
|
||||
openActivityWithActionOpenDocument(typeString)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to open document", e)
|
||||
showFileManagerDialogFragment()
|
||||
try {
|
||||
if (getContent) {
|
||||
getContentResultLauncher?.launch(typeString)
|
||||
} else {
|
||||
openDocumentResultLauncher?.launch(arrayOf(typeString))
|
||||
}
|
||||
} else {
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to open document", e)
|
||||
showFileManagerDialogFragment()
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.KITKAT)
|
||||
private fun openActivityWithActionOpenDocument(typeString: String) {
|
||||
val intentOpenDocument = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = typeString
|
||||
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
|
||||
}
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
fun createDocument(titleString: String) {
|
||||
try {
|
||||
createDocumentResultLauncher?.launch(titleString)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to create document", e)
|
||||
showFileManagerDialogFragment()
|
||||
}
|
||||
if (fragment != null)
|
||||
fragment?.startActivityForResult(intentOpenDocument, OPEN_DOC)
|
||||
else
|
||||
activity?.startActivityForResult(intentOpenDocument, OPEN_DOC)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.KITKAT)
|
||||
private fun openActivityWithActionGetContent(typeString: String) {
|
||||
val intentGetContent = Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = typeString
|
||||
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
|
||||
}
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
}
|
||||
if (fragment != null)
|
||||
fragment?.startActivityForResult(intentGetContent, GET_CONTENT)
|
||||
else
|
||||
activity?.startActivityForResult(intentGetContent, GET_CONTENT)
|
||||
}
|
||||
|
||||
/**
|
||||
* To use in onActivityResultCallback in Fragment or Activity
|
||||
* @param onFileSelected Callback retrieve from data
|
||||
* @return true if requestCode was captured, false elsewhere
|
||||
*/
|
||||
fun onOpenDocumentResult(requestCode: Int, resultCode: Int, data: Intent?,
|
||||
onFileSelected: ((uri: Uri?) -> Unit)?): Boolean {
|
||||
|
||||
when (requestCode) {
|
||||
FILE_BROWSE -> {
|
||||
if (resultCode == RESULT_OK) {
|
||||
val filename = data?.dataString
|
||||
var keyUri: Uri? = null
|
||||
if (filename != null) {
|
||||
keyUri = UriUtil.parse(filename)
|
||||
}
|
||||
onFileSelected?.invoke(keyUri)
|
||||
}
|
||||
return true
|
||||
}
|
||||
GET_CONTENT, OPEN_DOC -> {
|
||||
if (resultCode == RESULT_OK) {
|
||||
if (data != null) {
|
||||
val uri = data.data
|
||||
if (uri != null) {
|
||||
UriUtil.takeUriPermission(activity?.contentResolver, uri)
|
||||
onFileSelected?.invoke(uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,62 +148,50 @@ class ExternalFileHelper {
|
||||
}
|
||||
}
|
||||
|
||||
fun createDocument(titleString: String,
|
||||
typeString: String = "application/octet-stream"): Int? {
|
||||
val idCode = getUnusedCreateFileRequestCode()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
try {
|
||||
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = typeString
|
||||
putExtra(Intent.EXTRA_TITLE, titleString)
|
||||
class OpenDocument : ActivityResultContracts.OpenDocument() {
|
||||
@SuppressLint("InlinedApi")
|
||||
override fun createIntent(context: Context, input: Array<out String>): Intent {
|
||||
return super.createIntent(context, input).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
|
||||
}
|
||||
if (fragment != null)
|
||||
fragment?.startActivityForResult(intent, idCode)
|
||||
else
|
||||
activity?.startActivityForResult(intent, idCode)
|
||||
return idCode
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to create document", e)
|
||||
showFileManagerDialogFragment()
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
}
|
||||
} else {
|
||||
showFileManagerDialogFragment()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* To use in onActivityResultCallback in Fragment or Activity
|
||||
* @param onFileCreated Callback retrieve from data
|
||||
* @return true if requestCode was captured, false elsewhere
|
||||
*/
|
||||
fun onCreateDocumentResult(requestCode: Int, resultCode: Int, data: Intent?,
|
||||
onFileCreated: (fileCreated: Uri?)->Unit) {
|
||||
// Retrieve the created URI from the file manager
|
||||
if (fileRequestCodes.contains(requestCode) && resultCode == RESULT_OK) {
|
||||
onFileCreated.invoke(data?.data)
|
||||
fileRequestCodes.remove(requestCode)
|
||||
class GetContent : ActivityResultContracts.GetContent() {
|
||||
@SuppressLint("InlinedApi")
|
||||
override fun createIntent(context: Context, input: String): Intent {
|
||||
return super.createIntent(context, input).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
|
||||
}
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CreateDocument(private val typeString: String) : ActivityResultContracts.CreateDocument() {
|
||||
override fun createIntent(context: Context, input: String): Intent {
|
||||
return super.createIntent(context, input).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = typeString
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
private const val TAG = "OpenFileHelper"
|
||||
|
||||
private const val GET_CONTENT = 25745
|
||||
private const val OPEN_DOC = 25845
|
||||
private const val FILE_BROWSE = 25645
|
||||
|
||||
private var CREATE_FILE_REQUEST_CODE_DEFAULT = 3853
|
||||
private var fileRequestCodes = ArrayList<Int>()
|
||||
|
||||
private fun getUnusedCreateFileRequestCode(): Int {
|
||||
val newCreateFileRequestCode = CREATE_FILE_REQUEST_CODE_DEFAULT++
|
||||
fileRequestCodes.add(newCreateFileRequestCode)
|
||||
return newCreateFileRequestCode
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
fun allowCreateDocumentByStorageAccessFramework(packageManager: PackageManager,
|
||||
typeString: String = "application/octet-stream"): Boolean {
|
||||
@@ -231,7 +212,7 @@ class ExternalFileHelper {
|
||||
fun View.setOpenDocumentClickListener(externalFileHelper: ExternalFileHelper?) {
|
||||
externalFileHelper?.let { fileHelper ->
|
||||
setOnClickListener {
|
||||
fileHelper.openDocument()
|
||||
fileHelper.openDocument(false)
|
||||
}
|
||||
setOnLongClickListener {
|
||||
fileHelper.openDocument(true)
|
||||
|
||||
@@ -100,7 +100,7 @@ abstract class DatabaseLockActivity : DatabaseModeActivity(),
|
||||
}
|
||||
|
||||
mDatabaseViewModel.saveDefaultUsername.observe(this) {
|
||||
mDatabaseTaskProvider?.startDatabaseSaveName(it.oldValue, it.newValue, it.save)
|
||||
mDatabaseTaskProvider?.startDatabaseSaveDefaultUsername(it.oldValue, it.newValue, it.save)
|
||||
}
|
||||
|
||||
mDatabaseViewModel.saveColor.observe(this) {
|
||||
@@ -180,8 +180,7 @@ abstract class DatabaseLockActivity : DatabaseModeActivity(),
|
||||
closeDatabase(database)
|
||||
if (LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK == null)
|
||||
LOCKING_ACTIVITY_UI_VISIBLE_DURING_LOCK = LOCKING_ACTIVITY_UI_VISIBLE
|
||||
// Add onActivityForResult response
|
||||
setResult(RESULT_EXIT_LOCK)
|
||||
mExitLock = true
|
||||
closeOptionsMenu()
|
||||
finish()
|
||||
}
|
||||
@@ -353,14 +352,6 @@ abstract class DatabaseLockActivity : DatabaseModeActivity(),
|
||||
mDatabaseTaskProvider?.startDatabaseDeleteEntryHistory(mainEntryId, entryHistoryPosition, mAutoSaveEnable)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == RESULT_EXIT_LOCK) {
|
||||
mExitLock = true
|
||||
lockAndExit()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkRegister() {
|
||||
// If in ave or registration mode, don't allow read only
|
||||
if ((mSpecialMode == SpecialMode.SAVE
|
||||
@@ -440,8 +431,6 @@ abstract class DatabaseLockActivity : DatabaseModeActivity(),
|
||||
|
||||
const val TAG = "LockingActivity"
|
||||
|
||||
const val RESULT_EXIT_LOCK = 1450
|
||||
|
||||
const val TIMEOUT_ENABLE_KEY = "TIMEOUT_ENABLE_KEY"
|
||||
const val TIMEOUT_ENABLE_KEY_DEFAULT = true
|
||||
|
||||
|
||||
@@ -39,7 +39,11 @@ object Stylish {
|
||||
*/
|
||||
fun load(context: Context) {
|
||||
Log.d(Stylish::class.java.name, "Attatching to " + context.packageName)
|
||||
themeString = PreferencesUtil.getStyle(context)
|
||||
try {
|
||||
themeString = PreferencesUtil.getStyle(context)
|
||||
} catch (e: Exception) {
|
||||
Log.e("Stylish", "Unable to get preference style", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun retrieveEquivalentSystemStyle(context: Context, styleString: String): String {
|
||||
|
||||
@@ -23,12 +23,12 @@ import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.StyleRes
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.StyleRes
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
abstract class StylishFragment : Fragment() {
|
||||
|
||||
@@ -42,7 +42,6 @@ abstract class StylishFragment : Fragment() {
|
||||
contextThemed = ContextThemeWrapper(context, themeId)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
// To fix status bar color
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
@@ -58,6 +57,7 @@ abstract class StylishFragment : Fragment() {
|
||||
try {
|
||||
val taWindowStatusLight = contextThemed?.theme?.obtainStyledAttributes(intArrayOf(android.R.attr.windowLightStatusBar))
|
||||
if (taWindowStatusLight?.getBoolean(0, false) == true) {
|
||||
@Suppress("DEPRECATION")
|
||||
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
}
|
||||
taWindowStatusLight?.recycle()
|
||||
|
||||
@@ -67,8 +67,10 @@ class NodeAdapter (private val context: Context,
|
||||
private var mCalculateViewTypeTextSize = Array(2) { true } // number of view type
|
||||
private var mTextSizeUnit: Int = TypedValue.COMPLEX_UNIT_PX
|
||||
private var mPrefSizeMultiplier: Float = 0F
|
||||
private var mSubtextDefaultDimension: Float = 0F
|
||||
private var mInfoTextDefaultDimension: Float = 0F
|
||||
private var mTextDefaultDimension: Float = 0F
|
||||
private var mSubTextDefaultDimension: Float = 0F
|
||||
private var mMetaTextDefaultDimension: Float = 0F
|
||||
private var mOtpTokenTextDefaultDimension: Float = 0F
|
||||
private var mNumberChildrenTextDefaultDimension: Float = 0F
|
||||
private var mIconDefaultDimension: Float = 0F
|
||||
|
||||
@@ -303,8 +305,10 @@ class NodeAdapter (private val context: Context,
|
||||
mInflater.inflate(R.layout.item_list_nodes_entry, parent, false)
|
||||
}
|
||||
val nodeViewHolder = NodeViewHolder(view)
|
||||
mInfoTextDefaultDimension = nodeViewHolder.text.textSize
|
||||
mSubtextDefaultDimension = nodeViewHolder.subText.textSize
|
||||
mTextDefaultDimension = nodeViewHolder.text.textSize
|
||||
mSubTextDefaultDimension = nodeViewHolder.subText?.textSize ?: mSubTextDefaultDimension
|
||||
mMetaTextDefaultDimension = nodeViewHolder.meta.textSize
|
||||
mOtpTokenTextDefaultDimension = nodeViewHolder.otpToken?.textSize ?: mOtpTokenTextDefaultDimension
|
||||
nodeViewHolder.numberChildren?.let {
|
||||
mNumberChildrenTextDefaultDimension = it.textSize
|
||||
}
|
||||
@@ -315,7 +319,9 @@ class NodeAdapter (private val context: Context,
|
||||
val subNode = mNodeSortedList.get(position)
|
||||
|
||||
// Node selection
|
||||
holder.container.isSelected = mActionNodesList.contains(subNode)
|
||||
holder.container.apply {
|
||||
isSelected = mActionNodesList.contains(subNode)
|
||||
}
|
||||
|
||||
// Assign image
|
||||
val iconColor = if (holder.container.isSelected)
|
||||
@@ -337,19 +343,18 @@ class NodeAdapter (private val context: Context,
|
||||
// Assign text
|
||||
holder.text.apply {
|
||||
text = subNode.title
|
||||
setTextSize(mTextSizeUnit, mInfoTextDefaultDimension, mPrefSizeMultiplier)
|
||||
setTextSize(mTextSizeUnit, mTextDefaultDimension, mPrefSizeMultiplier)
|
||||
strikeOut(subNode.isCurrentlyExpires)
|
||||
}
|
||||
// Add subText with username
|
||||
holder.subText.apply {
|
||||
text = ""
|
||||
strikeOut(subNode.isCurrentlyExpires)
|
||||
visibility = View.GONE
|
||||
}
|
||||
// Add meta text to show UUID
|
||||
holder.meta.apply {
|
||||
text = subNode.nodeId.toString()
|
||||
visibility = if (mShowUUID) View.VISIBLE else View.GONE
|
||||
if (mShowUUID) {
|
||||
text = subNode.nodeId.toString()
|
||||
setTextSize(mTextSizeUnit, mMetaTextDefaultDimension, mPrefSizeMultiplier)
|
||||
visibility = View.VISIBLE
|
||||
} else {
|
||||
visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
// Specific elements for entry
|
||||
@@ -358,12 +363,16 @@ class NodeAdapter (private val context: Context,
|
||||
database.startManageEntry(entry)
|
||||
|
||||
holder.text.text = entry.getVisualTitle()
|
||||
holder.subText.apply {
|
||||
// Add subText with username
|
||||
holder.subText?.apply {
|
||||
val username = entry.username
|
||||
if (mShowUserNames && username.isNotEmpty()) {
|
||||
visibility = View.VISIBLE
|
||||
text = username
|
||||
setTextSize(mTextSizeUnit, mSubtextDefaultDimension, mPrefSizeMultiplier)
|
||||
setTextSize(mTextSizeUnit, mSubTextDefaultDimension, mPrefSizeMultiplier)
|
||||
strikeOut(subNode.isCurrentlyExpires)
|
||||
} else {
|
||||
visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,7 +440,10 @@ class NodeAdapter (private val context: Context,
|
||||
}
|
||||
}
|
||||
}
|
||||
holder?.otpToken?.text = otpElement?.token
|
||||
holder?.otpToken?.apply {
|
||||
text = otpElement?.token
|
||||
setTextSize(mTextSizeUnit, mOtpTokenTextDefaultDimension, mPrefSizeMultiplier)
|
||||
}
|
||||
holder?.otpContainer?.setOnClickListener {
|
||||
otpElement?.token?.let { token ->
|
||||
Toast.makeText(
|
||||
@@ -483,7 +495,7 @@ class NodeAdapter (private val context: Context,
|
||||
var imageIdentifier: ImageView? = itemView.findViewById(R.id.node_image_identifier)
|
||||
var icon: ImageView = itemView.findViewById(R.id.node_icon)
|
||||
var text: TextView = itemView.findViewById(R.id.node_text)
|
||||
var subText: TextView = itemView.findViewById(R.id.node_subtext)
|
||||
var subText: TextView? = itemView.findViewById(R.id.node_subtext)
|
||||
var meta: TextView = itemView.findViewById(R.id.node_meta)
|
||||
var otpContainer: ViewGroup? = itemView.findViewById(R.id.node_otp_container)
|
||||
var otpProgress: ProgressBar? = itemView.findViewById(R.id.node_otp_progress)
|
||||
|
||||
@@ -16,9 +16,9 @@ import com.kunzisoft.keepass.icons.IconDrawableFactory
|
||||
|
||||
|
||||
class TemplatesSelectorAdapter(private val context: Context,
|
||||
private val iconDrawableFactory: IconDrawableFactory?,
|
||||
private var templates: List<Template>): BaseAdapter() {
|
||||
|
||||
var iconDrawableFactory: IconDrawableFactory? = null
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
private var mIconColor = Color.BLACK
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.app.PendingIntent
|
||||
import android.app.assist.AssistStructure
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentSender
|
||||
import android.graphics.BlendMode
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
@@ -39,7 +38,10 @@ import android.view.inputmethod.InlineSuggestionsRequest
|
||||
import android.widget.RemoteViews
|
||||
import android.widget.Toast
|
||||
import android.widget.inline.InlinePresentationSpec
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.autofill.inline.UiVersions
|
||||
import androidx.autofill.inline.v1.InlineSuggestionUi
|
||||
import androidx.core.content.ContextCompat
|
||||
@@ -49,19 +51,17 @@ import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
|
||||
import com.kunzisoft.keepass.activities.helpers.SpecialMode
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateField
|
||||
import com.kunzisoft.keepass.model.EntryInfo
|
||||
import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateField
|
||||
import com.kunzisoft.keepass.settings.AutofillSettingsActivity
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import kotlin.collections.ArrayList
|
||||
import com.kunzisoft.keepass.utils.LOCK_ACTION
|
||||
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
object AutofillHelper {
|
||||
|
||||
private const val AUTOFILL_RESPONSE_REQUEST_CODE = 8165
|
||||
|
||||
private const val EXTRA_ASSIST_STRUCTURE = AutofillManager.EXTRA_ASSIST_STRUCTURE
|
||||
const val EXTRA_INLINE_SUGGESTIONS_REQUEST = "com.kunzisoft.keepass.autofill.INLINE_SUGGESTIONS_REQUEST"
|
||||
|
||||
@@ -253,9 +253,13 @@ object AutofillHelper {
|
||||
|
||||
// Build the content for IME UI
|
||||
val pendingIntent = PendingIntent.getActivity(context,
|
||||
0,
|
||||
Intent(context, AutofillSettingsActivity::class.java),
|
||||
0)
|
||||
0,
|
||||
Intent(context, AutofillSettingsActivity::class.java),
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
0
|
||||
})
|
||||
return InlinePresentation(
|
||||
InlineSuggestionUi.newContentBuilder(pendingIntent).apply {
|
||||
setContentDescription(context.getString(R.string.autofill_sign_in_prompt))
|
||||
@@ -427,11 +431,33 @@ object AutofillHelper {
|
||||
}
|
||||
}
|
||||
|
||||
fun buildActivityResultLauncher(activity: AppCompatActivity,
|
||||
lockDatabase: Boolean = false): ActivityResultLauncher<Intent> {
|
||||
return activity.registerForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) {
|
||||
// Utility method to loop and close each activity with return data
|
||||
if (it.resultCode == Activity.RESULT_OK) {
|
||||
activity.setResult(it.resultCode, it.data)
|
||||
}
|
||||
if (it.resultCode == Activity.RESULT_CANCELED) {
|
||||
activity.setResult(Activity.RESULT_CANCELED)
|
||||
}
|
||||
activity.finish()
|
||||
|
||||
if (lockDatabase && PreferencesUtil.isAutofillCloseDatabaseEnable(activity)) {
|
||||
// Close the database
|
||||
activity.sendBroadcast(Intent(LOCK_ACTION))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to start an activity with an Autofill for result
|
||||
*/
|
||||
fun startActivityForAutofillResult(activity: Activity,
|
||||
fun startActivityForAutofillResult(activity: AppCompatActivity,
|
||||
intent: Intent,
|
||||
activityResultLauncher: ActivityResultLauncher<Intent>?,
|
||||
autofillComponent: AutofillComponent,
|
||||
searchInfo: SearchInfo?) {
|
||||
EntrySelectionHelper.addSpecialModeInIntent(intent, SpecialMode.SELECTION)
|
||||
@@ -443,21 +469,6 @@ object AutofillHelper {
|
||||
}
|
||||
}
|
||||
EntrySelectionHelper.addSearchInfoInIntent(intent, searchInfo)
|
||||
activity.startActivityForResult(intent, AUTOFILL_RESPONSE_REQUEST_CODE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to loop and close each activity with return data
|
||||
*/
|
||||
fun onActivityResultSetResultAndFinish(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == AUTOFILL_RESPONSE_REQUEST_CODE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
activity.setResult(resultCode, data)
|
||||
}
|
||||
if (resultCode == Activity.RESULT_CANCELED) {
|
||||
activity.setResult(Activity.RESULT_CANCELED)
|
||||
}
|
||||
activity.finish()
|
||||
}
|
||||
activityResultLauncher?.launch(intent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,9 +262,13 @@ class KeeAutofillService : AutofillService() {
|
||||
inlinePresentation = InlinePresentation(
|
||||
InlineSuggestionUi.newContentBuilder(
|
||||
PendingIntent.getActivity(this,
|
||||
0,
|
||||
Intent(this, AutofillSettingsActivity::class.java),
|
||||
0)
|
||||
0,
|
||||
Intent(this, AutofillSettingsActivity::class.java),
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
0
|
||||
})
|
||||
).apply {
|
||||
setContentDescription(getString(R.string.autofill_sign_in_prompt))
|
||||
setTitle(getString(R.string.autofill_sign_in_prompt))
|
||||
|
||||
@@ -272,12 +272,12 @@ class StructureParser(private val structure: AssistStructure) {
|
||||
private fun parseNodeByHtmlAttributes(node: AssistStructure.ViewNode): Boolean {
|
||||
val autofillId = node.autofillId
|
||||
val nodHtml = node.htmlInfo
|
||||
when (nodHtml?.tag?.toLowerCase(Locale.ENGLISH)) {
|
||||
when (nodHtml?.tag?.lowercase(Locale.ENGLISH)) {
|
||||
"input" -> {
|
||||
nodHtml.attributes?.forEach { pairAttribute ->
|
||||
when (pairAttribute.first.toLowerCase(Locale.ENGLISH)) {
|
||||
when (pairAttribute.first.lowercase(Locale.ENGLISH)) {
|
||||
"type" -> {
|
||||
when (pairAttribute.second.toLowerCase(Locale.ENGLISH)) {
|
||||
when (pairAttribute.second.lowercase(Locale.ENGLISH)) {
|
||||
"tel", "email" -> {
|
||||
result?.usernameId = autofillId
|
||||
result?.usernameValue = node.autofillValue
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.biometric
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -27,9 +28,11 @@ import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.biometric.BiometricManager
|
||||
import androidx.biometric.BiometricPrompt
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.getkeepsafe.taptargetview.TapTargetView
|
||||
import com.kunzisoft.keepass.R
|
||||
@@ -39,6 +42,7 @@ import com.kunzisoft.keepass.database.exception.IODatabaseException
|
||||
import com.kunzisoft.keepass.education.PasswordActivityEducation
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.view.AdvancedUnlockInfoView
|
||||
import com.kunzisoft.keepass.viewmodels.AdvancedUnlockViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -59,9 +63,12 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
/**
|
||||
* Manage setting to auto open biometric prompt
|
||||
*/
|
||||
private var mAutoOpenPrompt: Boolean = false
|
||||
private var mAutoOpenPrompt: Boolean
|
||||
get() {
|
||||
return field && mAutoOpenPromptEnabled
|
||||
return mAdvancedUnlockViewModel.allowAutoOpenBiometricPrompt && mAutoOpenPromptEnabled
|
||||
}
|
||||
set(value) {
|
||||
mAdvancedUnlockViewModel.allowAutoOpenBiometricPrompt = value
|
||||
}
|
||||
|
||||
// Variable to check if the prompt can be open (if the right activity is currently shown)
|
||||
@@ -72,6 +79,8 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
|
||||
private var cipherDatabaseListener: CipherDatabaseAction.CipherDatabaseListener? = null
|
||||
|
||||
private val mAdvancedUnlockViewModel: AdvancedUnlockViewModel by activityViewModels()
|
||||
|
||||
// Only to fix multiple fingerprint menu #332
|
||||
private var mAllowAdvancedUnlockMenu = false
|
||||
private var mAddBiometricMenuInProgress = false
|
||||
@@ -79,6 +88,15 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
// Only keep connection when we request a device credential activity
|
||||
private var keepConnection = false
|
||||
|
||||
private var mDeviceCredentialResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
mAdvancedUnlockViewModel.allowAutoOpenBiometricPrompt = false
|
||||
// To wait resume
|
||||
if (keepConnection) {
|
||||
mAdvancedUnlockViewModel.deviceCredentialAuthSucceeded = result.resultCode == Activity.RESULT_OK
|
||||
}
|
||||
keepConnection = false
|
||||
}
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
|
||||
@@ -97,10 +115,21 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
retainInstance = true
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
cipherDatabaseAction = CipherDatabaseAction.getInstance(requireContext().applicationContext)
|
||||
|
||||
mAdvancedUnlockViewModel.onInitAdvancedUnlockModeRequested.observe(this) {
|
||||
initAdvancedUnlockMode()
|
||||
}
|
||||
|
||||
mAdvancedUnlockViewModel.onUnlockAvailabilityCheckRequested.observe(this) {
|
||||
checkUnlockAvailability()
|
||||
}
|
||||
|
||||
mAdvancedUnlockViewModel.onDatabaseFileLoaded.observe(this) {
|
||||
onDatabaseLoaded(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
@@ -114,17 +143,6 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
return rootView
|
||||
}
|
||||
|
||||
private data class ActivityResult(var requestCode: Int, var resultCode: Int, var data: Intent?)
|
||||
private var activityResult: ActivityResult? = null
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
// To wait resume
|
||||
if (keepConnection) {
|
||||
activityResult = ActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
keepConnection = false
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
context?.let {
|
||||
@@ -154,32 +172,38 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
fun loadDatabase(databaseUri: Uri?, autoOpenPrompt: Boolean) {
|
||||
private fun onDatabaseLoaded(databaseUri: Uri?) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// To get device credential unlock result, only if same database uri
|
||||
if (databaseUri != null
|
||||
&& mAdvancedUnlockEnabled) {
|
||||
activityResult?.let {
|
||||
val deviceCredentialAuthSucceeded = mAdvancedUnlockViewModel.deviceCredentialAuthSucceeded
|
||||
deviceCredentialAuthSucceeded?.let {
|
||||
if (databaseUri == databaseFileUri) {
|
||||
advancedUnlockManager?.onActivityResult(it.requestCode, it.resultCode)
|
||||
if (deviceCredentialAuthSucceeded == true) {
|
||||
advancedUnlockManager?.advancedUnlockCallback?.onAuthenticationSucceeded()
|
||||
} else {
|
||||
advancedUnlockManager?.advancedUnlockCallback?.onAuthenticationFailed()
|
||||
}
|
||||
} else {
|
||||
disconnect()
|
||||
}
|
||||
} ?: run {
|
||||
this.mAutoOpenPrompt = autoOpenPrompt
|
||||
connect(databaseUri)
|
||||
if (databaseUri != databaseFileUri) {
|
||||
connect(databaseUri)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
disconnect()
|
||||
}
|
||||
activityResult = null
|
||||
mAdvancedUnlockViewModel.deviceCredentialAuthSucceeded = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check unlock availability and change the current mode depending of device's state
|
||||
*/
|
||||
fun checkUnlockAvailability() {
|
||||
private fun checkUnlockAvailability() {
|
||||
context?.let { context ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
allowOpenBiometricPrompt = true
|
||||
@@ -317,7 +341,8 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
if (cryptoPrompt.isDeviceCredentialOperation)
|
||||
keepConnection = true
|
||||
try {
|
||||
advancedUnlockManager?.openAdvancedUnlockPrompt(cryptoPrompt)
|
||||
advancedUnlockManager?.openAdvancedUnlockPrompt(cryptoPrompt,
|
||||
mDeviceCredentialResultLauncher)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to open advanced unlock prompt", e)
|
||||
setAdvancedUnlockedTitleView(R.string.advanced_unlock_prompt_not_initialized)
|
||||
@@ -369,8 +394,7 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
} ?: throw Exception("AdvancedUnlockManager not initialized")
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun initAdvancedUnlockMode() {
|
||||
private fun initAdvancedUnlockMode() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
mAllowAdvancedUnlockMenu = false
|
||||
try {
|
||||
@@ -444,6 +468,7 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
fun deleteEncryptedDatabaseKey() {
|
||||
mAllowAdvancedUnlockMenu = false
|
||||
advancedUnlockManager?.closeBiometricPrompt()
|
||||
databaseFileUri?.let { databaseUri ->
|
||||
cipherDatabaseAction.deleteByDatabaseUri(databaseUri) {
|
||||
@@ -516,6 +541,11 @@ class AdvancedUnlockFragment: StylishFragment(), AdvancedUnlockManager.AdvancedU
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
override fun onUnrecoverableKeyException(e: Exception) {
|
||||
setAdvancedUnlockedMessageView(R.string.advanced_unlock_invalid_key)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
override fun onInvalidKeyException(e: Exception) {
|
||||
setAdvancedUnlockedMessageView(R.string.advanced_unlock_invalid_key)
|
||||
|
||||
@@ -19,15 +19,18 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.biometric
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.security.keystore.KeyGenParameterSpec
|
||||
import android.security.keystore.KeyPermanentlyInvalidatedException
|
||||
import android.security.keystore.KeyProperties
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.biometric.BiometricManager
|
||||
import androidx.biometric.BiometricManager.Authenticators.*
|
||||
@@ -35,6 +38,7 @@ import androidx.biometric.BiometricPrompt
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseAction
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import java.security.KeyStore
|
||||
import java.security.UnrecoverableKeyException
|
||||
@@ -136,18 +140,24 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
// and the constrains (purposes) in the constructor of the Builder
|
||||
keyGenerator?.init(
|
||||
KeyGenParameterSpec.Builder(
|
||||
ADVANCED_UNLOCK_KEYSTORE_KEY,
|
||||
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
|
||||
ADVANCED_UNLOCK_KEYSTORE_KEY,
|
||||
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
|
||||
.apply {
|
||||
// Require the user to authenticate with a fingerprint to authorize every use
|
||||
// of the key, don't use it for device credential because it's the user authentication
|
||||
.apply {
|
||||
if (biometricUnlockEnable) {
|
||||
setUserAuthenticationRequired(true)
|
||||
}
|
||||
if (biometricUnlockEnable) {
|
||||
setUserAuthenticationRequired(true)
|
||||
}
|
||||
.build())
|
||||
// To store in the security chip
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
|
||||
&& retrieveContext().packageManager.hasSystemFeature(
|
||||
PackageManager.FEATURE_STRONGBOX_KEYSTORE)) {
|
||||
setIsStrongBoxBacked(true)
|
||||
}
|
||||
}
|
||||
.build())
|
||||
keyGenerator?.generateKey()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@@ -164,8 +174,12 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
return null
|
||||
}
|
||||
|
||||
fun initEncryptData(actionIfCypherInit
|
||||
: (cryptoPrompt: AdvancedUnlockCryptoPrompt) -> Unit) {
|
||||
fun initEncryptData(actionIfCypherInit: (cryptoPrompt: AdvancedUnlockCryptoPrompt) -> Unit,) {
|
||||
initEncryptData(actionIfCypherInit, true)
|
||||
}
|
||||
|
||||
private fun initEncryptData(actionIfCypherInit: (cryptoPrompt: AdvancedUnlockCryptoPrompt) -> Unit,
|
||||
firstLaunch: Boolean) {
|
||||
if (!isKeyManagerInitialized) {
|
||||
return
|
||||
}
|
||||
@@ -185,10 +199,15 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
}
|
||||
} catch (unrecoverableKeyException: UnrecoverableKeyException) {
|
||||
Log.e(TAG, "Unable to initialize encrypt data", unrecoverableKeyException)
|
||||
advancedUnlockCallback?.onInvalidKeyException(unrecoverableKeyException)
|
||||
advancedUnlockCallback?.onUnrecoverableKeyException(unrecoverableKeyException)
|
||||
} catch (invalidKeyException: KeyPermanentlyInvalidatedException) {
|
||||
Log.e(TAG, "Unable to initialize encrypt data", invalidKeyException)
|
||||
advancedUnlockCallback?.onInvalidKeyException(invalidKeyException)
|
||||
if (firstLaunch) {
|
||||
deleteAllEntryKeysInKeystoreForBiometric(retrieveContext())
|
||||
initEncryptData(actionIfCypherInit, false)
|
||||
} else {
|
||||
advancedUnlockCallback?.onInvalidKeyException(invalidKeyException)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to initialize encrypt data", e)
|
||||
advancedUnlockCallback?.onGenericException(e)
|
||||
@@ -214,8 +233,14 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
}
|
||||
}
|
||||
|
||||
fun initDecryptData(ivSpecValue: String, actionIfCypherInit
|
||||
: (cryptoPrompt: AdvancedUnlockCryptoPrompt) -> Unit) {
|
||||
fun initDecryptData(ivSpecValue: String,
|
||||
actionIfCypherInit: (cryptoPrompt: AdvancedUnlockCryptoPrompt) -> Unit) {
|
||||
initDecryptData(ivSpecValue, actionIfCypherInit, true)
|
||||
}
|
||||
|
||||
private fun initDecryptData(ivSpecValue: String,
|
||||
actionIfCypherInit: (cryptoPrompt: AdvancedUnlockCryptoPrompt) -> Unit,
|
||||
firstLaunch: Boolean = true) {
|
||||
if (!isKeyManagerInitialized) {
|
||||
return
|
||||
}
|
||||
@@ -239,10 +264,20 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
}
|
||||
} catch (unrecoverableKeyException: UnrecoverableKeyException) {
|
||||
Log.e(TAG, "Unable to initialize decrypt data", unrecoverableKeyException)
|
||||
deleteKeystoreKey()
|
||||
if (firstLaunch) {
|
||||
deleteKeystoreKey()
|
||||
initDecryptData(ivSpecValue, actionIfCypherInit, firstLaunch)
|
||||
} else {
|
||||
advancedUnlockCallback?.onUnrecoverableKeyException(unrecoverableKeyException)
|
||||
}
|
||||
} catch (invalidKeyException: KeyPermanentlyInvalidatedException) {
|
||||
Log.e(TAG, "Unable to initialize decrypt data", invalidKeyException)
|
||||
advancedUnlockCallback?.onInvalidKeyException(invalidKeyException)
|
||||
if (firstLaunch) {
|
||||
deleteAllEntryKeysInKeystoreForBiometric(retrieveContext())
|
||||
initDecryptData(ivSpecValue, actionIfCypherInit, firstLaunch)
|
||||
} else {
|
||||
advancedUnlockCallback?.onInvalidKeyException(invalidKeyException)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to initialize decrypt data", e)
|
||||
advancedUnlockCallback?.onGenericException(e)
|
||||
@@ -278,9 +313,9 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@Synchronized
|
||||
fun openAdvancedUnlockPrompt(cryptoPrompt: AdvancedUnlockCryptoPrompt) {
|
||||
fun openAdvancedUnlockPrompt(cryptoPrompt: AdvancedUnlockCryptoPrompt,
|
||||
deviceCredentialResultLauncher: ActivityResultLauncher<Intent>
|
||||
) {
|
||||
// Init advanced unlock prompt
|
||||
if (biometricPrompt == null) {
|
||||
biometricPrompt = BiometricPrompt(retrieveContext(),
|
||||
@@ -311,20 +346,10 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
}
|
||||
else if (cryptoPrompt.isDeviceCredentialOperation) {
|
||||
val keyGuardManager = ContextCompat.getSystemService(retrieveContext(), KeyguardManager::class.java)
|
||||
retrieveContext().startActivityForResult(
|
||||
keyGuardManager?.createConfirmDeviceCredentialIntent(promptTitle, promptDescription),
|
||||
REQUEST_DEVICE_CREDENTIAL)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun onActivityResult(requestCode: Int, resultCode: Int) {
|
||||
if (requestCode == REQUEST_DEVICE_CREDENTIAL) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
advancedUnlockCallback?.onAuthenticationSucceeded()
|
||||
} else {
|
||||
advancedUnlockCallback?.onAuthenticationFailed()
|
||||
}
|
||||
@Suppress("DEPRECATION")
|
||||
deviceCredentialResultLauncher.launch(
|
||||
keyGuardManager?.createConfirmDeviceCredentialIntent(promptTitle, promptDescription)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,6 +358,7 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
}
|
||||
|
||||
interface AdvancedUnlockErrorCallback {
|
||||
fun onUnrecoverableKeyException(e: Exception)
|
||||
fun onInvalidKeyException(e: Exception)
|
||||
fun onGenericException(e: Exception)
|
||||
}
|
||||
@@ -355,8 +381,6 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
private const val ADVANCED_UNLOCK_BLOCKS_MODES = KeyProperties.BLOCK_MODE_CBC
|
||||
private const val ADVANCED_UNLOCK_ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7
|
||||
|
||||
private const val REQUEST_DEVICE_CREDENTIAL = 556
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
fun canAuthenticate(context: Context): Int {
|
||||
return try {
|
||||
@@ -449,6 +473,10 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
|
||||
override fun handleDecryptedResult(decryptedValue: String) {}
|
||||
|
||||
override fun onUnrecoverableKeyException(e: Exception) {
|
||||
advancedCallback.onUnrecoverableKeyException(e)
|
||||
}
|
||||
|
||||
override fun onInvalidKeyException(e: Exception) {
|
||||
advancedCallback.onInvalidKeyException(e)
|
||||
}
|
||||
@@ -460,6 +488,33 @@ class AdvancedUnlockManager(private var retrieveContext: () -> FragmentActivity)
|
||||
deleteKeystoreKey()
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteAllEntryKeysInKeystoreForBiometric(activity: FragmentActivity) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
deleteEntryKeyInKeystoreForBiometric(
|
||||
activity,
|
||||
object : AdvancedUnlockErrorCallback {
|
||||
fun showException(e: Exception) {
|
||||
Toast.makeText(activity,
|
||||
activity.getString(R.string.advanced_unlock_scanning_error, e.localizedMessage),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
override fun onUnrecoverableKeyException(e: Exception) {
|
||||
showException(e)
|
||||
}
|
||||
|
||||
override fun onInvalidKeyException(e: Exception) {
|
||||
showException(e)
|
||||
}
|
||||
|
||||
override fun onGenericException(e: Exception) {
|
||||
showException(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
CipherDatabaseAction.getInstance(activity.applicationContext).deleteAll()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -192,17 +192,17 @@ class Argon2Kdf(private val type: Type) : KdfEngine() {
|
||||
private val MIN_VERSION = UnsignedInt(0x10)
|
||||
private val MAX_VERSION = UnsignedInt(0x13)
|
||||
|
||||
private val DEFAULT_ITERATIONS = UnsignedLong(2L)
|
||||
private val DEFAULT_ITERATIONS = UnsignedLong(3L)
|
||||
private val MIN_ITERATIONS = UnsignedLong(1L)
|
||||
private val MAX_ITERATIONS = UnsignedLong(4294967295L)
|
||||
|
||||
private val DEFAULT_MEMORY = UnsignedLong((1024L * 1024L))
|
||||
private val DEFAULT_MEMORY = UnsignedLong((1024L * 1024L * 16L))
|
||||
private val MIN_MEMORY = UnsignedLong(1024L * 8L)
|
||||
private val MAX_MEMORY = UnsignedInt.MAX_VALUE.toKotlinLong()
|
||||
private const val MEMORY_BLOCK_SIZE: Long = 1024L
|
||||
|
||||
private val DEFAULT_PARALLELISM = UnsignedInt(2)
|
||||
private val DEFAULT_PARALLELISM = UnsignedInt(4)
|
||||
private val MIN_PARALLELISM = UnsignedInt.fromKotlinLong(1L)
|
||||
private val MAX_PARALLELISM = UnsignedInt.fromKotlinLong(((1 shl 24) - 1))
|
||||
private val MAX_PARALLELISM = UnsignedInt.fromKotlinLong(((1 shl 24) - 1).toLong())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ abstract class EntryCursor<EntryId, PwEntryV : EntryVersioned<*, EntryId, *, *>>
|
||||
pwEntry.notes = getString(getColumnIndex(COLUMN_INDEX_NOTES))
|
||||
pwEntry.expiryTime = DateInstant(getString(getColumnIndex(COLUMN_INDEX_EXPIRY_TIME)))
|
||||
pwEntry.expires = getString(getColumnIndex(COLUMN_INDEX_EXPIRES))
|
||||
.toLowerCase(Locale.ENGLISH) != "false"
|
||||
.lowercase(Locale.ENGLISH) != "false"
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -147,6 +147,10 @@ class Database {
|
||||
iconsManager.removeCustomIcon(binaryCache, customIcon.uuid)
|
||||
}
|
||||
|
||||
fun updateCustomIcon(customIcon: IconImageCustom) {
|
||||
iconsManager.getIcon(customIcon.uuid).updateWith(customIcon)
|
||||
}
|
||||
|
||||
fun getTemplates(templateCreation: Boolean): List<Template> {
|
||||
return mDatabaseKDBX?.getTemplates(templateCreation) ?: listOf()
|
||||
}
|
||||
|
||||
@@ -177,16 +177,20 @@ class Group : Node, GroupVersionedInterface<Group, Entry> {
|
||||
fun addChildrenFrom(group: Group) {
|
||||
group.groupKDB?.getChildEntries()?.forEach { entryToAdd ->
|
||||
groupKDB?.addChildEntry(entryToAdd)
|
||||
entryToAdd.parent = groupKDB
|
||||
}
|
||||
group.groupKDB?.getChildGroups()?.forEach { groupToAdd ->
|
||||
groupKDB?.addChildGroup(groupToAdd)
|
||||
groupToAdd.parent = groupKDB
|
||||
}
|
||||
|
||||
group.groupKDBX?.getChildEntries()?.forEach { entryToAdd ->
|
||||
groupKDBX?.addChildEntry(entryToAdd)
|
||||
entryToAdd.parent = groupKDBX
|
||||
}
|
||||
group.groupKDBX?.getChildGroups()?.forEach { groupToAdd ->
|
||||
groupKDBX?.addChildGroup(groupToAdd)
|
||||
groupToAdd.parent = groupKDBX
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ class CustomIconPool(private val binaryCache: BinaryCache) : BinaryPool<UUID>(bi
|
||||
return newUUID
|
||||
}
|
||||
|
||||
fun getCustomIcon(key: UUID): IconImageCustom? {
|
||||
return customIcons[key]
|
||||
}
|
||||
|
||||
fun any(predicate: (IconImageCustom)-> Boolean): Boolean {
|
||||
return customIcons.any { predicate(it.value) }
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class DatabaseKDB : DatabaseVersioned<Int, UUID, GroupKDB, EntryKDB>() {
|
||||
private var kdfListV3: MutableList<KdfEngine> = ArrayList()
|
||||
|
||||
override val version: String
|
||||
get() = "KeePass 1"
|
||||
get() = "V1"
|
||||
|
||||
init {
|
||||
kdfListV3.add(KdfFactory.aesKdf)
|
||||
|
||||
@@ -156,7 +156,7 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
|
||||
FILE_VERSION_41 -> "4.1"
|
||||
else -> "UNKNOWN"
|
||||
}
|
||||
return "KeePass 2 - KDBX$kdbxStringVersion"
|
||||
return "V2 - KDBX$kdbxStringVersion"
|
||||
}
|
||||
|
||||
override val kdfEngine: KdfEngine?
|
||||
|
||||
@@ -124,25 +124,29 @@ abstract class DatabaseVersioned<
|
||||
|
||||
@Throws(IOException::class)
|
||||
protected fun getFileKey(keyInputStream: InputStream): ByteArray {
|
||||
val keyData = keyInputStream.readBytes()
|
||||
try {
|
||||
val keyData = keyInputStream.readBytes()
|
||||
|
||||
// Check XML key file
|
||||
val xmlKeyByteArray = loadXmlKeyFile(ByteArrayInputStream(keyData))
|
||||
if (xmlKeyByteArray != null) {
|
||||
return xmlKeyByteArray
|
||||
}
|
||||
|
||||
// Check 32 bytes key file
|
||||
when (keyData.size) {
|
||||
32 -> return keyData
|
||||
64 -> try {
|
||||
return Hex.decodeHex(String(keyData).toCharArray())
|
||||
} catch (ignoredException: Exception) {
|
||||
// Key is not base 64, treat it as binary data
|
||||
// Check XML key file
|
||||
val xmlKeyByteArray = loadXmlKeyFile(ByteArrayInputStream(keyData))
|
||||
if (xmlKeyByteArray != null) {
|
||||
return xmlKeyByteArray
|
||||
}
|
||||
|
||||
// Check 32 bytes key file
|
||||
when (keyData.size) {
|
||||
32 -> return keyData
|
||||
64 -> try {
|
||||
return Hex.decodeHex(String(keyData).toCharArray())
|
||||
} catch (ignoredException: Exception) {
|
||||
// Key is not base 64, treat it as binary data
|
||||
}
|
||||
}
|
||||
// Hash file as binary data
|
||||
return HashManager.hashSha256(keyData)
|
||||
} catch (outOfMemoryError: OutOfMemoryError) {
|
||||
throw IOException("Keyfile data is too large", outOfMemoryError)
|
||||
}
|
||||
// Hash file as binary data
|
||||
return HashManager.hashSha256(keyData)
|
||||
}
|
||||
|
||||
protected open fun loadXmlKeyFile(keyInputStream: InputStream): ByteArray? {
|
||||
|
||||
@@ -32,6 +32,16 @@ class IconImageCustom : IconImageDraw {
|
||||
var name: String = ""
|
||||
var lastModificationTime: DateInstant? = null
|
||||
|
||||
fun updateWith(icon: IconImageCustom) {
|
||||
this.name = icon.name
|
||||
this.lastModificationTime = icon.lastModificationTime
|
||||
}
|
||||
|
||||
constructor(copy: IconImageCustom) {
|
||||
this.uuid = copy.uuid
|
||||
updateWith(copy)
|
||||
}
|
||||
|
||||
constructor(name: String = "", lastModificationTime: DateInstant? = null) {
|
||||
this.uuid = DatabaseVersioned.UUID_ZERO
|
||||
this.name = name
|
||||
|
||||
@@ -65,7 +65,7 @@ class IconsManager(binaryCache: BinaryCache) {
|
||||
}
|
||||
|
||||
fun getIcon(iconUuid: UUID): IconImageCustom {
|
||||
return IconImageCustom(iconUuid)
|
||||
return customCache.getCustomIcon(iconUuid) ?: IconImageCustom(iconUuid)
|
||||
}
|
||||
|
||||
fun isCustomIconBinaryDuplicate(binaryData: BinaryData): Boolean {
|
||||
|
||||
@@ -208,16 +208,8 @@ class TemplateEngineCompatible(database: DatabaseKDBX): TemplateEngine(database)
|
||||
when (attribute.type) {
|
||||
TemplateAttributeType.TEXT -> {
|
||||
try {
|
||||
when (attribute.options.getNumberLines()) {
|
||||
1 -> {
|
||||
// If one line, default attribute option is number of chars
|
||||
attribute.options.setNumberChars(defaultOption.toInt())
|
||||
}
|
||||
else -> {
|
||||
// else it's number of lines
|
||||
attribute.options.setNumberLines(defaultOption.toInt())
|
||||
}
|
||||
}
|
||||
// It's always a number of lines...
|
||||
attribute.options.setNumberLines(defaultOption.toInt())
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to transform default text option", e)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ object TemplateField {
|
||||
const val LABEL_DATE_OF_ISSUE = "Date of issue"
|
||||
const val LABEL_EMAIL = "Email"
|
||||
const val LABEL_EMAIL_ADDRESS = "Email address"
|
||||
const val LABEL_WIRELESS = "Wifi"
|
||||
const val LABEL_WIRELESS = "Wi-Fi"
|
||||
const val LABEL_SSID = "SSID"
|
||||
const val LABEL_TYPE = "Type"
|
||||
const val LABEL_CRYPTOCURRENCY = "Cryptocurrency wallet"
|
||||
|
||||
@@ -130,6 +130,6 @@ constructor(private val databaseKDBX: DatabaseKDBX,
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val EndHeaderValue = byteArrayOf('\r'.toByte(), '\n'.toByte(), '\r'.toByte(), '\n'.toByte())
|
||||
private val EndHeaderValue = byteArrayOf('\r'.code.toByte(), '\n'.code.toByte(), '\r'.code.toByte(), '\n'.code.toByte())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,7 +765,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
var character: Char
|
||||
for (element in text) {
|
||||
character = element
|
||||
val hexChar = character.toInt()
|
||||
val hexChar = character.code
|
||||
if (
|
||||
hexChar in 0x20..0xD7FF ||
|
||||
hexChar == 0x9 ||
|
||||
|
||||
@@ -272,7 +272,7 @@ class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionL
|
||||
if (entryInfoKey != null) {
|
||||
currentInputConnection.commitText(entryInfoKey!!.url, 1)
|
||||
}
|
||||
actionTabAutomatically()
|
||||
actionGoAutomatically()
|
||||
}
|
||||
KEY_FIELDS -> {
|
||||
if (entryInfoKey != null) {
|
||||
|
||||
@@ -234,7 +234,7 @@ data class OtpElement(var otpModel: OtpModel = OtpModel()) {
|
||||
|
||||
fun replaceBase32Chars(parameter: String): String {
|
||||
// Add padding '=' at end if not Base32 length
|
||||
var parameterNewSize = parameter.toUpperCase(Locale.ENGLISH).removeSpaceChars()
|
||||
var parameterNewSize = parameter.uppercase(Locale.ENGLISH).removeSpaceChars()
|
||||
while (parameterNewSize.length % 8 != 0) {
|
||||
parameterNewSize += '='
|
||||
}
|
||||
@@ -264,7 +264,7 @@ enum class OtpTokenType {
|
||||
|
||||
companion object {
|
||||
fun getFromString(tokenType: String): OtpTokenType {
|
||||
return when (tokenType.toLowerCase(Locale.ENGLISH)) {
|
||||
return when (tokenType.lowercase(Locale.ENGLISH)) {
|
||||
"s", "steam" -> STEAM
|
||||
"hotp" -> RFC4226
|
||||
else -> RFC6238
|
||||
|
||||
@@ -143,7 +143,7 @@ object OtpEntryFields {
|
||||
if (otpPlainText != null && otpPlainText.isNotEmpty() && isOTPUri(otpPlainText)) {
|
||||
val uri = Uri.parse(otpPlainText.removeSpaceChars())
|
||||
|
||||
if (uri.scheme == null || OTP_SCHEME != uri.scheme!!.toLowerCase(Locale.ENGLISH)) {
|
||||
if (uri.scheme == null || OTP_SCHEME != uri.scheme!!.lowercase(Locale.ENGLISH)) {
|
||||
Log.e(TAG, "Invalid or missing scheme in uri")
|
||||
return false
|
||||
}
|
||||
@@ -309,7 +309,7 @@ object OtpEntryFields {
|
||||
}
|
||||
if (algorithmField != null) {
|
||||
otpElement.algorithm =
|
||||
when (algorithmField.toUpperCase(Locale.ENGLISH)) {
|
||||
when (algorithmField.uppercase(Locale.ENGLISH)) {
|
||||
TIMEOTP_ALGORITHM_SHA1_VALUE -> HashAlgorithm.SHA1
|
||||
TIMEOTP_ALGORITHM_SHA256_VALUE -> HashAlgorithm.SHA256
|
||||
TIMEOTP_ALGORITHM_SHA512_VALUE -> HashAlgorithm.SHA512
|
||||
@@ -417,7 +417,7 @@ object OtpEntryFields {
|
||||
val output = HashMap<String, String>()
|
||||
for (element in elements) {
|
||||
val pair = element.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
output[pair[0].toLowerCase(Locale.ENGLISH)] = pair[1]
|
||||
output[pair[0].lowercase(Locale.ENGLISH)] = pair[1]
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.kunzisoft.keepass.receivers
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.magikeyboard.MagikeyboardService
|
||||
import com.kunzisoft.keepass.utils.DexUtil
|
||||
import com.kunzisoft.keepass.utils.MagikeyboardUtil
|
||||
|
||||
class DexModeReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
val enabled = when (intent?.action) {
|
||||
"android.app.action.ENTER_KNOX_DESKTOP_MODE" -> {
|
||||
Log.i(TAG, "Entered DeX mode")
|
||||
false
|
||||
}
|
||||
"android.app.action.EXIT_KNOX_DESKTOP_MODE" -> {
|
||||
Log.i(TAG, "Left DeX mode")
|
||||
true
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
|
||||
MagikeyboardUtil.setEnabled(context!!, enabled)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = DexModeReceiver::class.java.name
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.kunzisoft.keepass.services
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.PendingIntent
|
||||
import android.content.*
|
||||
import android.net.Uri
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
|
||||
@@ -50,11 +52,20 @@ class AdvancedUnlockNotificationService : NotificationService() {
|
||||
mTempCipherDao = ArrayList()
|
||||
}
|
||||
|
||||
// It's simpler to use pendingIntent to perform REMOVE_ADVANCED_UNLOCK_KEY_ACTION
|
||||
// because can be directly broadcast to another module or app
|
||||
@SuppressLint("LaunchActivityFromNotification")
|
||||
override fun onBind(intent: Intent): IBinder {
|
||||
super.onBind(intent)
|
||||
|
||||
val pendingDeleteIntent = PendingIntent.getBroadcast(this,
|
||||
4577, Intent(REMOVE_ADVANCED_UNLOCK_KEY_ACTION), 0)
|
||||
4577,
|
||||
Intent(REMOVE_ADVANCED_UNLOCK_KEY_ACTION),
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
0
|
||||
})
|
||||
val biometricUnlockEnabled = PreferencesUtil.isBiometricUnlockEnable(this)
|
||||
val notificationBuilder = buildNewNotification().apply {
|
||||
setSmallIcon(if (biometricUnlockEnabled) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.ContentResolver
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.R
|
||||
@@ -188,20 +189,30 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
||||
private fun newNotification(attachmentNotification: AttachmentNotification) {
|
||||
|
||||
val pendingContentIntent = PendingIntent.getActivity(this,
|
||||
0,
|
||||
Intent().apply {
|
||||
action = Intent.ACTION_VIEW
|
||||
setDataAndType(attachmentNotification.uri,
|
||||
contentResolver.getType(attachmentNotification.uri))
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}, PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
0,
|
||||
Intent().apply {
|
||||
action = Intent.ACTION_VIEW
|
||||
setDataAndType(attachmentNotification.uri,
|
||||
contentResolver.getType(attachmentNotification.uri))
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
)
|
||||
|
||||
val pendingDeleteIntent = PendingIntent.getService(this,
|
||||
0,
|
||||
Intent(this, AttachmentFileNotificationService::class.java).apply {
|
||||
// No action to delete the service
|
||||
putExtra(FILE_URI_KEY, attachmentNotification.uri)
|
||||
}, PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
}, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
)
|
||||
|
||||
val fileName = UriUtil.getFileData(this, attachmentNotification.uri)?.name
|
||||
?: attachmentNotification.uri.path
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.services
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.model.EntryInfo
|
||||
@@ -112,7 +113,13 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
putParcelableArrayListExtra(EXTRA_CLIPBOARD_FIELDS, fieldsToAdd)
|
||||
}
|
||||
return PendingIntent.getService(
|
||||
this, 0, copyIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
this, 0, copyIntent,
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun newNotification(title: String?, fieldsToAdd: ArrayList<ClipboardEntryNotificationField>) {
|
||||
@@ -162,7 +169,13 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
val cleanIntent = Intent(this, ClipboardEntryNotificationService::class.java)
|
||||
cleanIntent.action = ACTION_CLEAN_CLIPBOARD
|
||||
val cleanPendingIntent = PendingIntent.getService(
|
||||
this, 0, cleanIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
this, 0, cleanIntent,
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
)
|
||||
builder.setDeleteIntent(cleanPendingIntent)
|
||||
|
||||
//Get settings
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.*
|
||||
import android.util.Log
|
||||
import androidx.media.app.NotificationCompat
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.GroupActivity
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
|
||||
@@ -407,11 +408,21 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
this,
|
||||
0,
|
||||
Intent(this, GroupActivity::class.java),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
)
|
||||
val pendingDeleteIntent = PendingIntent.getBroadcast(
|
||||
this,
|
||||
4576, Intent(LOCK_ACTION), 0
|
||||
4576,
|
||||
Intent(LOCK_ACTION),
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
0
|
||||
}
|
||||
)
|
||||
// Add actions in notifications
|
||||
notificationBuilder.apply {
|
||||
@@ -420,9 +431,16 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
// Unfortunately swipe is disabled in lollipop+
|
||||
setDeleteIntent(pendingDeleteIntent)
|
||||
addAction(
|
||||
R.drawable.ic_lock_white_24dp, getString(R.string.lock),
|
||||
R.drawable.ic_lock_database_white_32dp, getString(R.string.lock),
|
||||
pendingDeleteIntent
|
||||
)
|
||||
// Won't work with Xiaomi and Kitkat
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
|
||||
setStyle(
|
||||
NotificationCompat.MediaStyle()
|
||||
.setShowActionsInCompactView(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.services
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.preference.PreferenceManager
|
||||
@@ -93,7 +94,13 @@ class KeyboardEntryNotificationService : LockNotificationService() {
|
||||
val deleteIntent = Intent(this, KeyboardEntryNotificationService::class.java).apply {
|
||||
action = ACTION_CLEAN_KEYBOARD_ENTRY
|
||||
}
|
||||
pendingDeleteIntent = PendingIntent.getService(this, 0, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
pendingDeleteIntent = PendingIntent.getService(this, 0, deleteIntent,
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
)
|
||||
|
||||
val builder = buildNewNotification()
|
||||
.setSmallIcon(R.drawable.notification_ic_keyboard_key_24dp)
|
||||
|
||||
@@ -57,6 +57,7 @@ class AutofillSettingsFragment : PreferenceFragmentCompat() {
|
||||
}
|
||||
|
||||
if (dialogFragment != null) {
|
||||
@Suppress("DEPRECATION")
|
||||
dialogFragment.setTargetFragment(this, 0)
|
||||
dialogFragment.show(parentFragmentManager, TAG_AUTOFILL_PREF_FRAGMENT)
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ class MagikeyboardSettingsFragment : PreferenceFragmentCompat() {
|
||||
}
|
||||
|
||||
if (dialogFragment != null) {
|
||||
@Suppress("DEPRECATION")
|
||||
dialogFragment.setTargetFragment(this, 0)
|
||||
dialogFragment.show(parentFragmentManager, TAG_PREF_FRAGMENT)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.dialogs.ProFeatureDialogFragment
|
||||
import com.kunzisoft.keepass.activities.dialogs.UnavailableFeatureDialogFragment
|
||||
import com.kunzisoft.keepass.activities.stylish.Stylish
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseAction
|
||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||
import com.kunzisoft.keepass.biometric.AdvancedUnlockManager
|
||||
import com.kunzisoft.keepass.education.Education
|
||||
@@ -157,7 +156,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
||||
val intent = Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE)
|
||||
intent.data = Uri.parse("package:com.kunzisoft.keepass.autofill.KeeAutofillService")
|
||||
Log.d(javaClass.name, "Autofill enable service: intent=$intent")
|
||||
startActivityForResult(intent, REQUEST_CODE_AUTOFILL)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
Log.d(javaClass.name, "Autofill service already enabled.")
|
||||
}
|
||||
@@ -366,26 +365,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
||||
) { _, _ ->
|
||||
validate?.invoke()
|
||||
deleteKeysAlertDialog?.setOnDismissListener(null)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
AdvancedUnlockManager.deleteEntryKeyInKeystoreForBiometric(
|
||||
activity,
|
||||
object : AdvancedUnlockManager.AdvancedUnlockErrorCallback {
|
||||
fun showException(e: Exception) {
|
||||
Toast.makeText(context,
|
||||
getString(R.string.advanced_unlock_scanning_error, e.localizedMessage),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
override fun onInvalidKeyException(e: Exception) {
|
||||
showException(e)
|
||||
}
|
||||
|
||||
override fun onGenericException(e: Exception) {
|
||||
showException(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
CipherDatabaseAction.getInstance(activity.applicationContext).deleteAll()
|
||||
AdvancedUnlockManager.deleteAllEntryKeysInKeystoreForBiometric(activity)
|
||||
}
|
||||
.setNegativeButton(resources.getString(android.R.string.cancel)
|
||||
) { _, _ ->}
|
||||
@@ -494,6 +474,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
||||
}
|
||||
|
||||
if (dialogFragment != null) {
|
||||
@Suppress("DEPRECATION")
|
||||
dialogFragment.setTargetFragment(this, 0)
|
||||
dialogFragment.show(parentFragmentManager, TAG_PREF_FRAGMENT)
|
||||
}
|
||||
@@ -533,7 +514,6 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CODE_AUTOFILL = 5201
|
||||
private const val TAG_PREF_FRAGMENT = "TAG_PREF_FRAGMENT"
|
||||
|
||||
var DATABASE_APPEARANCE_PREFERENCE_CHANGED = false
|
||||
|
||||
@@ -57,7 +57,7 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment(), DatabaseRetriev
|
||||
|
||||
private var dbNamePref: InputTextPreference? = null
|
||||
private var dbDescriptionPref: InputTextPreference? = null
|
||||
private var dbDefaultUsername: InputTextPreference? = null
|
||||
private var dbDefaultUsernamePref: InputTextPreference? = null
|
||||
private var dbCustomColorPref: DialogColorPreference? = null
|
||||
private var dbDataCompressionPref: Preference? = null
|
||||
private var recycleBinGroupPref: DialogListExplanationPreference? = null
|
||||
@@ -164,11 +164,11 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment(), DatabaseRetriev
|
||||
}
|
||||
|
||||
// Database default username
|
||||
dbDefaultUsername = findPreference(getString(R.string.database_default_username_key))
|
||||
dbDefaultUsernamePref = findPreference(getString(R.string.database_default_username_key))
|
||||
if (database.allowDefaultUsername) {
|
||||
dbDefaultUsername?.summary = database.defaultUsername
|
||||
dbDefaultUsernamePref?.summary = database.defaultUsername
|
||||
} else {
|
||||
dbDefaultUsername?.isEnabled = false
|
||||
dbDefaultUsernamePref?.isEnabled = false
|
||||
// TODO dbGeneralPrefCategory?.removePreference(dbDefaultUsername)
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment(), DatabaseRetriev
|
||||
mDatabase?.defaultUsername = oldDefaultUsername
|
||||
oldDefaultUsername
|
||||
}
|
||||
dbDefaultUsername?.summary = defaultUsernameToShow
|
||||
dbDefaultUsernamePref?.summary = defaultUsernameToShow
|
||||
}
|
||||
DatabaseTaskNotificationService.ACTION_DATABASE_UPDATE_COLOR_TASK -> {
|
||||
val oldColor = data.getString(DatabaseTaskNotificationService.OLD_ELEMENT_KEY)!!
|
||||
@@ -632,6 +632,7 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment(), DatabaseRetriev
|
||||
}
|
||||
|
||||
if (dialogFragment != null && !mDatabaseReadOnly) {
|
||||
@Suppress("DEPRECATION")
|
||||
dialogFragment.setTargetFragment(this, 0)
|
||||
dialogFragment.show(parentFragmentManager, TAG_PREF_FRAGMENT)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ open class SettingsActivity
|
||||
|
||||
private var backupManager: BackupManager? = null
|
||||
private var mExternalFileHelper: ExternalFileHelper? = null
|
||||
private var appPropertiesFileCreationRequestCode: Int? = null
|
||||
|
||||
private var coordinatorLayout: CoordinatorLayout? = null
|
||||
private var toolbar: Toolbar? = null
|
||||
@@ -64,6 +63,41 @@ open class SettingsActivity
|
||||
toolbar = findViewById(R.id.toolbar)
|
||||
|
||||
mExternalFileHelper = ExternalFileHelper(this)
|
||||
mExternalFileHelper?.buildOpenDocument { selectedFileUri ->
|
||||
// Import app properties result
|
||||
try {
|
||||
selectedFileUri?.let { uri ->
|
||||
val appProperties = Properties()
|
||||
contentResolver?.openInputStream(uri)?.use { inputStream ->
|
||||
appProperties.load(inputStream)
|
||||
}
|
||||
PreferencesUtil.setAppProperties(this, appProperties)
|
||||
|
||||
// Restart the current activity
|
||||
reloadActivity()
|
||||
Toast.makeText(this, R.string.success_import_app_properties, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(this, R.string.error_import_app_properties, Toast.LENGTH_LONG).show()
|
||||
Log.e(TAG, "Unable to import app properties", e)
|
||||
}
|
||||
}
|
||||
mExternalFileHelper?.buildCreateDocument { createdFileUri ->
|
||||
// Export app properties result
|
||||
try {
|
||||
createdFileUri?.let { uri ->
|
||||
contentResolver?.openOutputStream(uri)?.use { outputStream ->
|
||||
PreferencesUtil
|
||||
.getAppProperties(this)
|
||||
.store(outputStream, getString(R.string.description_app_properties))
|
||||
}
|
||||
Toast.makeText(this, R.string.success_export_app_properties, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(this, R.string.error_export_app_properties, Toast.LENGTH_LONG).show()
|
||||
Log.e(DatabaseLockActivity.TAG, "Unable to export app properties", e)
|
||||
}
|
||||
}
|
||||
|
||||
if (savedInstanceState?.getString(TITLE_KEY).isNullOrEmpty())
|
||||
toolbar?.setTitle(R.string.settings)
|
||||
@@ -217,54 +251,10 @@ open class SettingsActivity
|
||||
}
|
||||
|
||||
fun exportAppProperties() {
|
||||
appPropertiesFileCreationRequestCode = mExternalFileHelper?.createDocument(getString(R.string.app_properties_file_name,
|
||||
mExternalFileHelper?.createDocument(getString(R.string.app_properties_file_name,
|
||||
DateTime.now().toLocalDateTime().toString("yyyy-MM-dd'_'HH-mm")))
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
// Import app properties result
|
||||
try {
|
||||
mExternalFileHelper?.onOpenDocumentResult(requestCode, resultCode, data) { selectedFileUri ->
|
||||
selectedFileUri?.let { uri ->
|
||||
val appProperties = Properties()
|
||||
contentResolver?.openInputStream(uri)?.use { inputStream ->
|
||||
appProperties.load(inputStream)
|
||||
}
|
||||
PreferencesUtil.setAppProperties(this, appProperties)
|
||||
|
||||
// Restart the current activity
|
||||
reloadActivity()
|
||||
Toast.makeText(this, R.string.success_import_app_properties, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(this, R.string.error_import_app_properties, Toast.LENGTH_LONG).show()
|
||||
Log.e(TAG, "Unable to import app properties", e)
|
||||
}
|
||||
|
||||
// Export app properties result
|
||||
try {
|
||||
if (requestCode == appPropertiesFileCreationRequestCode) {
|
||||
mExternalFileHelper?.onCreateDocumentResult(requestCode, resultCode, data) { createdFileUri ->
|
||||
createdFileUri?.let { uri ->
|
||||
contentResolver?.openOutputStream(uri)?.use { outputStream ->
|
||||
PreferencesUtil
|
||||
.getAppProperties(this)
|
||||
.store(outputStream, getString(R.string.description_app_properties))
|
||||
}
|
||||
Toast.makeText(this, R.string.success_export_app_properties, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
appPropertiesFileCreationRequestCode = null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(this, R.string.error_export_app_properties, Toast.LENGTH_LONG).show()
|
||||
Log.e(DatabaseLockActivity.TAG, "Unable to export app properties", e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
|
||||
@@ -64,11 +64,13 @@ class DurationDialogFragmentCompat : InputPreferenceDialogFragmentCompat() {
|
||||
|
||||
private fun durationToDaysHoursMinutesSeconds(duration: Long) {
|
||||
if (duration < 0) {
|
||||
mEnabled = false
|
||||
mDays = 0
|
||||
mHours = 0
|
||||
mMinutes = 0
|
||||
mSeconds = 0
|
||||
} else {
|
||||
mEnabled = true
|
||||
mDays = (duration / (24L * 60L * 60L * 1000L)).toInt()
|
||||
val daysMilliseconds = mDays * 24L * 60L * 60L * 1000L
|
||||
mHours = ((duration - daysMilliseconds) / (60L * 60L * 1000L)).toInt()
|
||||
@@ -125,10 +127,9 @@ class DurationDialogFragmentCompat : InputPreferenceDialogFragmentCompat() {
|
||||
}
|
||||
}
|
||||
|
||||
mEnabled = isSwitchActivated()
|
||||
setSwitchAction({ isChecked ->
|
||||
mEnabled = isChecked
|
||||
}, mDays + mHours + mMinutes + mSeconds > 0)
|
||||
}, mEnabled)
|
||||
|
||||
assignValuesInViews()
|
||||
}
|
||||
|
||||
@@ -31,9 +31,13 @@ abstract class ActionRunnable: Runnable {
|
||||
var result: Result = Result()
|
||||
|
||||
override fun run() {
|
||||
onStartRun()
|
||||
onActionRun()
|
||||
onFinishRun()
|
||||
try {
|
||||
onStartRun()
|
||||
onActionRun()
|
||||
onFinishRun()
|
||||
} catch (runException: Exception) {
|
||||
setError(runException)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun onStartRun()
|
||||
|
||||
@@ -43,9 +43,14 @@ object TimeoutHelper {
|
||||
|
||||
private fun getLockPendingIntent(context: Context): PendingIntent {
|
||||
return PendingIntent.getBroadcast(context.applicationContext,
|
||||
REQUEST_ID,
|
||||
Intent(LOCK_ACTION),
|
||||
PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
REQUEST_ID,
|
||||
Intent(LOCK_ACTION),
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,11 +60,16 @@ class LockReceiver(var lockAction: () -> Unit) : BroadcastReceiver() {
|
||||
Intent.ACTION_SCREEN_OFF -> {
|
||||
if (PreferencesUtil.isLockDatabaseWhenScreenShutOffEnable(context)) {
|
||||
mLockPendingIntent = PendingIntent.getBroadcast(context,
|
||||
4575,
|
||||
Intent(intent).apply {
|
||||
action = LOCK_ACTION
|
||||
},
|
||||
0)
|
||||
4575,
|
||||
Intent(intent).apply {
|
||||
action = LOCK_ACTION
|
||||
},
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
} else {
|
||||
0
|
||||
}
|
||||
)
|
||||
// Launch the effective action after a small time
|
||||
val first: Long = System.currentTimeMillis() + context.getString(R.string.timeout_screen_off).toLong()
|
||||
val alarmManager = context.getSystemService(ALARM_SERVICE) as AlarmManager?
|
||||
|
||||
27
app/src/main/java/com/kunzisoft/keepass/utils/DexUtil.kt
Normal file
27
app/src/main/java/com/kunzisoft/keepass/utils/DexUtil.kt
Normal file
@@ -0,0 +1,27 @@
|
||||
package com.kunzisoft.keepass.utils
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.util.Log
|
||||
|
||||
object DexUtil {
|
||||
private val TAG = DexUtil::class.java.name
|
||||
|
||||
// Determine if the current environment is in DeX mode. Always returns false on non-Samsung
|
||||
// devices.
|
||||
fun isDexMode(config: Configuration): Boolean {
|
||||
// This is the documented way to check this: https://developer.samsung.com/samsung-dex/modify-optimizing.html
|
||||
return try {
|
||||
val configClass = config.javaClass
|
||||
val enabledConstant = configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass)
|
||||
val enabledField = configClass.getField("semDesktopModeEnabled").getInt(config)
|
||||
val isEnabled = enabledConstant == enabledField
|
||||
|
||||
Log.d(TAG, "DeX currently enabled: $isEnabled")
|
||||
|
||||
isEnabled
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Failed to check for DeX mode; likely not Samsung device: $e")
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.kunzisoft.keepass.utils
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.magikeyboard.MagikeyboardService
|
||||
|
||||
object MagikeyboardUtil {
|
||||
private val TAG = MagikeyboardUtil::class.java.name
|
||||
|
||||
// Set whether MagikeyboardService is enabled. This change is persistent and survives app
|
||||
// crashes and device restarts. The state is changed immediately and does not require an app
|
||||
// restart.
|
||||
fun setEnabled(context: Context, enabled: Boolean) {
|
||||
val componentState = if (enabled) {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
} else {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
||||
}
|
||||
|
||||
Log.d(TAG, "Setting service state: $enabled")
|
||||
|
||||
val component = ComponentName(context, MagikeyboardService::class.java)
|
||||
context.packageManager.setComponentEnabledSetting(component, componentState, PackageManager.DONT_KILL_APP)
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ object UriUtil {
|
||||
|
||||
private fun isFileScheme(fileUri: Uri): Boolean {
|
||||
val scheme = fileUri.scheme
|
||||
if (scheme == null || scheme.isEmpty() || scheme.toLowerCase(Locale.ENGLISH) == "file") {
|
||||
if (scheme == null || scheme.isEmpty() || scheme.lowercase(Locale.ENGLISH) == "file") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -94,7 +94,7 @@ object UriUtil {
|
||||
|
||||
private fun isContentScheme(fileUri: Uri): Boolean {
|
||||
val scheme = fileUri.scheme
|
||||
if (scheme != null && scheme.toLowerCase(Locale.ENGLISH) == "content") {
|
||||
if (scheme != null && scheme.lowercase(Locale.ENGLISH) == "content") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -104,10 +104,12 @@ class AdvancedUnlockInfoView @JvmOverloads constructor(context: Context,
|
||||
return unlockMessageTextView?.text?.toString() ?: ""
|
||||
}
|
||||
set(value) {
|
||||
if (value == null || value.isEmpty())
|
||||
if (value == null || value.isEmpty()) {
|
||||
unlockMessageTextView?.visibility = GONE
|
||||
else
|
||||
} else {
|
||||
unlockMessageTextView?.visibility = VISIBLE
|
||||
stopIconViewAnimation()
|
||||
}
|
||||
unlockMessageTextView?.text = value ?: ""
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.kunzisoft.keepass.view
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Parcelable
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.TextView
|
||||
@@ -9,6 +10,9 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.utils.UriUtil
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable.Creator
|
||||
|
||||
|
||||
class KeyFileSelectionView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
@@ -54,4 +58,45 @@ class KeyFileSelectionView @JvmOverloads constructor(context: Context,
|
||||
UriUtil.getFileData(context, value)?.name ?: value.path
|
||||
} ?: ""
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(): Parcelable {
|
||||
val superState = super.onSaveInstanceState()
|
||||
val saveState = SavedState(superState)
|
||||
saveState.mUri = this.mUri
|
||||
return saveState
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(state: Parcelable?) {
|
||||
if (state !is SavedState) {
|
||||
super.onRestoreInstanceState(state)
|
||||
return
|
||||
}
|
||||
super.onRestoreInstanceState(state.superState)
|
||||
this.mUri = state.mUri
|
||||
}
|
||||
|
||||
internal class SavedState : BaseSavedState {
|
||||
var mUri: Uri? = null
|
||||
|
||||
constructor(superState: Parcelable?) : super(superState) {}
|
||||
|
||||
private constructor(parcel: Parcel) : super(parcel) {
|
||||
mUri = parcel.readParcelable(Uri::class.java.classLoader)
|
||||
}
|
||||
|
||||
override fun writeToParcel(out: Parcel, flags: Int) {
|
||||
super.writeToParcel(out, flags)
|
||||
out.writeParcelable(mUri, flags)
|
||||
}
|
||||
|
||||
companion object CREATOR : Creator<SavedState> {
|
||||
override fun createFromParcel(parcel: Parcel): SavedState {
|
||||
return SavedState(parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<SavedState?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,8 @@ abstract class TemplateAbstractView<
|
||||
if (mTemplate != template) {
|
||||
mTemplate = template
|
||||
if (mEntryInfo != null) {
|
||||
populateEntryInfoWithViews(true)
|
||||
populateEntryInfoWithViews(templateFieldNotEmpty = true,
|
||||
retrieveDefaultValues = false)
|
||||
}
|
||||
buildTemplateAndPopulateInfo()
|
||||
clearFocus()
|
||||
@@ -203,9 +204,7 @@ abstract class TemplateAbstractView<
|
||||
setNumberLines(20)
|
||||
},
|
||||
TemplateAttributeAction.CUSTOM_EDITION
|
||||
).apply {
|
||||
default = field.protectedValue.stringValue
|
||||
}
|
||||
)
|
||||
return buildViewForTemplateField(customFieldTemplateAttribute, field, FIELD_CUSTOM_TAG)
|
||||
}
|
||||
|
||||
@@ -275,22 +274,26 @@ abstract class TemplateAbstractView<
|
||||
templateAttribute: TemplateAttribute,
|
||||
entryInfoValue: String,
|
||||
showEmptyFields: Boolean) {
|
||||
var fieldView: TEntryFieldView? = findViewWithTag(fieldTag)
|
||||
if (!showEmptyFields && entryInfoValue.isEmpty()) {
|
||||
fieldView?.isFieldVisible = false
|
||||
} else if (fieldView == null && entryInfoValue.isNotEmpty()) {
|
||||
// Add new not referenced view if standard field not in template
|
||||
fieldView = buildViewForNotReferencedField(
|
||||
Field(templateAttribute.label,
|
||||
ProtectedString(templateAttribute.protected, "")),
|
||||
templateAttribute
|
||||
) as? TEntryFieldView?
|
||||
fieldView?.let {
|
||||
addNotReferencedView(it as View)
|
||||
try {
|
||||
var fieldView: TEntryFieldView? = findViewWithTag(fieldTag)
|
||||
if (!showEmptyFields && entryInfoValue.isEmpty()) {
|
||||
fieldView?.isFieldVisible = false
|
||||
} else if (fieldView == null && entryInfoValue.isNotEmpty()) {
|
||||
// Add new not referenced view if standard field not in template
|
||||
fieldView = buildViewForNotReferencedField(
|
||||
Field(templateAttribute.label,
|
||||
ProtectedString(templateAttribute.protected, "")),
|
||||
templateAttribute
|
||||
) as? TEntryFieldView?
|
||||
fieldView?.let {
|
||||
addNotReferencedView(it as View)
|
||||
}
|
||||
}
|
||||
fieldView?.value = entryInfoValue
|
||||
fieldView?.applyFontVisibility(mFontInVisibility)
|
||||
} catch(e: Exception) {
|
||||
Log.e(TAG, "Unable to populate entry field view", e)
|
||||
}
|
||||
fieldView?.value = entryInfoValue
|
||||
fieldView?.applyFontVisibility(mFontInVisibility)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -299,22 +302,25 @@ abstract class TemplateAbstractView<
|
||||
expires: Boolean,
|
||||
expiryTime: DateInstant,
|
||||
showEmptyFields: Boolean) {
|
||||
|
||||
var fieldView: TDateTimeView? = findViewWithTag(fieldTag)
|
||||
if (!showEmptyFields && !expires) {
|
||||
fieldView?.isFieldVisible = false
|
||||
} else if (fieldView == null && expires) {
|
||||
fieldView = buildViewForNotReferencedField(
|
||||
Field(templateAttribute.label,
|
||||
ProtectedString(templateAttribute.protected, "")),
|
||||
templateAttribute
|
||||
) as? TDateTimeView?
|
||||
fieldView?.let {
|
||||
addNotReferencedView(it as View)
|
||||
try {
|
||||
var fieldView: TDateTimeView? = findViewWithTag(fieldTag)
|
||||
if (!showEmptyFields && !expires) {
|
||||
fieldView?.isFieldVisible = false
|
||||
} else if (fieldView == null && expires) {
|
||||
fieldView = buildViewForNotReferencedField(
|
||||
Field(templateAttribute.label,
|
||||
ProtectedString(templateAttribute.protected, "")),
|
||||
templateAttribute
|
||||
) as? TDateTimeView?
|
||||
fieldView?.let {
|
||||
addNotReferencedView(it as View)
|
||||
}
|
||||
}
|
||||
fieldView?.activation = expires
|
||||
fieldView?.dateTime = expiryTime
|
||||
} catch(e: Exception) {
|
||||
Log.e(TAG, "Unable to populate date time view", e)
|
||||
}
|
||||
fieldView?.activation = expires
|
||||
fieldView?.dateTime = expiryTime
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,7 +389,8 @@ abstract class TemplateAbstractView<
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
protected open fun populateEntryInfoWithViews(templateFieldNotEmpty: Boolean) {
|
||||
protected open fun populateEntryInfoWithViews(templateFieldNotEmpty: Boolean,
|
||||
retrieveDefaultValues: Boolean) {
|
||||
if (mEntryInfo == null)
|
||||
mEntryInfo = EntryInfo()
|
||||
|
||||
@@ -422,11 +429,12 @@ abstract class TemplateAbstractView<
|
||||
mEntryInfo?.notes = it
|
||||
}
|
||||
|
||||
retrieveCustomFieldsFromView(templateFieldNotEmpty)
|
||||
retrieveCustomFieldsFromView(templateFieldNotEmpty, retrieveDefaultValues)
|
||||
}
|
||||
|
||||
fun getEntryInfo(): EntryInfo {
|
||||
populateEntryInfoWithViews(true)
|
||||
populateEntryInfoWithViews(templateFieldNotEmpty = true,
|
||||
retrieveDefaultValues = true)
|
||||
return mEntryInfo ?: EntryInfo()
|
||||
}
|
||||
|
||||
@@ -472,23 +480,31 @@ abstract class TemplateAbstractView<
|
||||
return mViewFields.indexOfFirst { it.field.name.equals(name, true) }
|
||||
}
|
||||
|
||||
private fun retrieveCustomFieldsFromView(templateFieldNotEmpty: Boolean = false) {
|
||||
private fun retrieveCustomFieldsFromView(templateFieldNotEmpty: Boolean = false,
|
||||
retrieveDefaultValues: Boolean = false) {
|
||||
mEntryInfo?.customFields = mViewFields.mapNotNull {
|
||||
getCustomField(it.field.name, templateFieldNotEmpty)
|
||||
getCustomField(it.field.name, templateFieldNotEmpty, retrieveDefaultValues)
|
||||
}.toMutableList()
|
||||
}
|
||||
|
||||
protected fun getCustomField(fieldName: String): Field {
|
||||
return getCustomField(fieldName, false)
|
||||
?: Field(fieldName, ProtectedString(false))
|
||||
return getCustomField(fieldName,
|
||||
templateFieldNotEmpty = false,
|
||||
retrieveDefaultValues = false
|
||||
) ?: Field(fieldName, ProtectedString(false))
|
||||
}
|
||||
|
||||
private fun getCustomField(fieldName: String, templateFieldNotEmpty: Boolean): Field? {
|
||||
private fun getCustomField(fieldName: String,
|
||||
templateFieldNotEmpty: Boolean,
|
||||
retrieveDefaultValues: Boolean): Field? {
|
||||
getViewFieldByName(fieldName)?.let { fieldId ->
|
||||
val editView: View? = fieldId.view
|
||||
val editView: View = fieldId.view
|
||||
if (editView is GenericFieldView) {
|
||||
// Do not return field with a default value
|
||||
val defaultViewValue = if (editView.value == editView.default) "" else editView.value
|
||||
val defaultViewValue =
|
||||
if (retrieveDefaultValues || editView.value != editView.default) {
|
||||
editView.value
|
||||
} else ""
|
||||
if (!templateFieldNotEmpty
|
||||
|| (editView.tag == FIELD_CUSTOM_TAG && defaultViewValue.isNotEmpty())) {
|
||||
return Field(
|
||||
@@ -634,7 +650,8 @@ abstract class TemplateAbstractView<
|
||||
override fun onSaveInstanceState(): Parcelable {
|
||||
val superSave = super.onSaveInstanceState()
|
||||
val saveState = SavedState(superSave)
|
||||
populateEntryInfoWithViews(false)
|
||||
populateEntryInfoWithViews(templateFieldNotEmpty = false,
|
||||
retrieveDefaultValues = false)
|
||||
saveState.template = this.mTemplate
|
||||
saveState.entryInfo = this.mEntryInfo
|
||||
onSaveEntryInstanceState(saveState)
|
||||
|
||||
@@ -64,6 +64,7 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
||||
TextEditFieldView(it).apply {
|
||||
// hiddenProtectedValue (mHideProtectedValue) don't work with TextInputLayout
|
||||
setProtection(field.protectedValue.isProtected)
|
||||
default = templateAttribute.default
|
||||
setMaxChars(templateAttribute.options.getNumberChars())
|
||||
setMaxLines(templateAttribute.options.getNumberLines())
|
||||
setActionClick(templateAttribute, field, this)
|
||||
@@ -79,7 +80,7 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
||||
return context?.let {
|
||||
TextSelectFieldView(it).apply {
|
||||
setItems(templateAttribute.options.getListItems())
|
||||
default = field.protectedValue.stringValue
|
||||
default = templateAttribute.default
|
||||
setActionClick(templateAttribute, field, this)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_NO
|
||||
@@ -198,8 +199,9 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
||||
return super.populateViewsWithEntryInfo(showEmptyFields)
|
||||
}
|
||||
|
||||
override fun populateEntryInfoWithViews(templateFieldNotEmpty: Boolean) {
|
||||
super.populateEntryInfoWithViews(templateFieldNotEmpty)
|
||||
override fun populateEntryInfoWithViews(templateFieldNotEmpty: Boolean,
|
||||
retrieveDefaultValues: Boolean) {
|
||||
super.populateEntryInfoWithViews(templateFieldNotEmpty, retrieveDefaultValues)
|
||||
mEntryInfo?.otpModel = OtpEntryFields.parseFields { key ->
|
||||
getCustomField(key).protectedValue.toString()
|
||||
}?.otpModel
|
||||
|
||||
@@ -187,6 +187,6 @@ class TextEditFieldView @JvmOverloads constructor(context: Context,
|
||||
|
||||
companion object {
|
||||
const val MAX_CHARS_LIMIT = Integer.MAX_VALUE
|
||||
const val MAX_LINES_LIMIT = 40
|
||||
const val MAX_LINES_LIMIT = Integer.MAX_VALUE
|
||||
}
|
||||
}
|
||||
@@ -194,6 +194,7 @@ class TextSelectFieldView @JvmOverloads constructor(context: Context,
|
||||
get() = valueSpinnerAdapter.getItem(mDefaultPosition)
|
||||
set(value) {
|
||||
mDefaultPosition = valueSpinnerAdapter.getPosition(value)
|
||||
valueSpinnerAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun setOnActionClickListener(onActionClickListener: OnClickListener?,
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.kunzisoft.keepass.viewmodels
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class AdvancedUnlockViewModel : ViewModel() {
|
||||
|
||||
var allowAutoOpenBiometricPrompt : Boolean = true
|
||||
var deviceCredentialAuthSucceeded: Boolean? = null
|
||||
|
||||
val onInitAdvancedUnlockModeRequested : LiveData<Void?> get() = _onInitAdvancedUnlockModeRequested
|
||||
private val _onInitAdvancedUnlockModeRequested = SingleLiveEvent<Void?>()
|
||||
|
||||
val onUnlockAvailabilityCheckRequested : LiveData<Void?> get() = _onUnlockAvailabilityCheckRequested
|
||||
private val _onUnlockAvailabilityCheckRequested = SingleLiveEvent<Void?>()
|
||||
|
||||
val onDatabaseFileLoaded : LiveData<Uri?> get() = _onDatabaseFileLoaded
|
||||
private val _onDatabaseFileLoaded = SingleLiveEvent<Uri?>()
|
||||
|
||||
fun initAdvancedUnlockMode() {
|
||||
_onInitAdvancedUnlockModeRequested.call()
|
||||
}
|
||||
|
||||
fun checkUnlockAvailability() {
|
||||
_onUnlockAvailabilityCheckRequested.call()
|
||||
}
|
||||
|
||||
fun databaseFileLoaded(databaseUri: Uri?) {
|
||||
_onDatabaseFileLoaded.value = databaseUri
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.kunzisoft.keepass.viewmodels
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
|
||||
@@ -30,6 +31,10 @@ class IconPickerViewModel: ViewModel() {
|
||||
MutableLiveData<IconCustomState>()
|
||||
}
|
||||
|
||||
val customIconUpdated : MutableLiveData<IconCustomState> by lazy {
|
||||
MutableLiveData<IconCustomState>()
|
||||
}
|
||||
|
||||
fun pickStandardIcon(icon: IconImageStandard) {
|
||||
standardIconPicked.value = icon
|
||||
}
|
||||
@@ -54,6 +59,10 @@ class IconPickerViewModel: ViewModel() {
|
||||
customIconRemoved.value = customIcon
|
||||
}
|
||||
|
||||
fun updateCustomIcon(customIcon: IconCustomState) {
|
||||
customIconUpdated.value = customIcon
|
||||
}
|
||||
|
||||
data class IconCustomState(var iconCustom: IconImageCustom? = null,
|
||||
var error: Boolean = true,
|
||||
var errorStringId: Int = -1,
|
||||
|
||||
@@ -144,7 +144,7 @@ internal class PublicSuffixListData(
|
||||
}
|
||||
|
||||
companion object {
|
||||
val WILDCARD_LABEL = byteArrayOf('*'.toByte())
|
||||
val WILDCARD_LABEL = byteArrayOf('*'.code.toByte())
|
||||
val PREVAILING_RULE = listOf("*")
|
||||
val EMPTY_RULE = listOf<String>()
|
||||
const val EXCEPTION_MARKER = '!'
|
||||
|
||||
@@ -36,7 +36,7 @@ internal fun ByteArray.binarySearch(labels: List<ByteArray>, labelIndex: Int): S
|
||||
while (true) {
|
||||
val byte0 = if (expectDot) {
|
||||
expectDot = false
|
||||
'.'.toByte()
|
||||
'.'.code.toByte()
|
||||
} else {
|
||||
labels[currentLabelIndex][currentLabelByteIndex] and BITMASK
|
||||
}
|
||||
@@ -103,7 +103,7 @@ internal fun ByteArray.binarySearch(labels: List<ByteArray>, labelIndex: Int): S
|
||||
*/
|
||||
private fun ByteArray.findStartOfLineFromIndex(start: Int): Int {
|
||||
var index = start
|
||||
while (index > -1 && this[index] != '\n'.toByte()) {
|
||||
while (index > -1 && this[index] != '\n'.code.toByte()) {
|
||||
index--
|
||||
}
|
||||
index++
|
||||
@@ -115,7 +115,7 @@ private fun ByteArray.findStartOfLineFromIndex(start: Int): Int {
|
||||
*/
|
||||
private fun ByteArray.findEndOfLineFromIndex(start: Int): Int {
|
||||
var end = 1
|
||||
while (this[start + end] != '\n'.toByte()) {
|
||||
while (this[start + end] != '\n'.code.toByte()) {
|
||||
end++
|
||||
}
|
||||
return end
|
||||
|
||||
10
app/src/main/res/drawable/ic_lock_database_white_32dp.xml
Normal file
10
app/src/main/res/drawable/ic_lock_database_white_32dp.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 11 2.0566406 C 6.762335 2.4220229 3.0067094 5.7987155 2.203125 9.9785156 C 1.3601753 13.960549 3.1781148 18.394742 6.7089844 20.480469 C 9.6237318 22.368157 13.514425 22.492178 16.582031 20.892578 C 17.959775 20.180473 19.316015 19.099467 20.087891 17.808594 L 18.402344 16.791016 C 16.277892 19.724364 12.039121 20.844605 8.7519531 19.306641 C 5.481064 17.911182 3.4461934 14.150571 4.109375 10.648438 C 4.6649664 7.2806969 7.5784749 4.4226117 11 4.0839844 L 11 2.0566406 z M 13 2.0644531 L 13 4.09375 C 16.367309 4.4801387 19.308002 7.2166099 19.861328 10.574219 C 20.123352 12.069186 19.935398 13.632674 19.367188 15.037109 C 19.94644 15.387646 20.527063 15.73602 21.105469 16.087891 C 22.671737 12.714066 22.120988 8.4920871 19.708984 5.6542969 C 18.063396 3.6246553 15.604973 2.2995704 13 2.0644531 z M 12 6.7148438 C 10.737143 6.7148437 9.7148438 7.737143 9.7148438 9 L 9.7148438 10.142578 L 9.1425781 10.142578 C 8.5140068 10.142578 8 10.656585 8 11.285156 L 8 15.857422 C 8 16.491709 8.5140068 17 9.1425781 17 L 14.857422 17 C 15.491709 17 16 16.491709 16 15.857422 L 16 11.285156 C 16 10.656585 15.491709 10.142578 14.857422 10.142578 L 14.285156 10.142578 L 14.285156 9 C 14.285156 7.737143 13.262857 6.7148438 12 6.7148438 z M 12 7.8574219 C 12.634286 7.8574219 13.142578 8.3714294 13.142578 9 L 13.142578 10.142578 L 10.857422 10.142578 L 10.857422 9 C 10.857422 8.3714294 11.371429 7.8574219 12 7.8574219 z M 12 12.427734 C 12.634286 12.427734 13.142578 12.943693 13.142578 13.572266 C 13.142578 14.20655 12.634286 14.714844 12 14.714844 C 11.371429 14.714844 10.857422 14.20655 10.857422 13.572266 C 10.857422 12.943693 11.371429 12.427734 12 12.427734 z" />
|
||||
</vector>
|
||||
@@ -52,8 +52,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/biometric_message"
|
||||
tools:text="@string/advanced_unlock_prompt_store_credential_title"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Default.TextOnPrimary"
|
||||
android:textSize="14sp"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Secondary.TextOnPrimary"
|
||||
android:gravity="center" />
|
||||
|
||||
<TextView
|
||||
@@ -67,7 +66,6 @@
|
||||
app:layout_constraintTop_toBottomOf="@+id/biometric_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:text="Sample error"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Secondary.TextOnPrimary"
|
||||
android:textSize="12sp"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Warning.TextOnPrimary"
|
||||
android:gravity="center" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:attr/windowBackground"
|
||||
tools:targetApi="o">
|
||||
|
||||
<com.kunzisoft.keepass.view.SpecialModeView
|
||||
|
||||
56
app/src/main/res/layout/fragment_icon_edit.xml
Normal file
56
app/src/main/res/layout/fragment_icon_edit.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2021 Jeremy Jamet / Kunzisoft.
|
||||
|
||||
This file is part of KeePassDX.
|
||||
|
||||
KeePassDX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
KeePassDX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/default_margin"
|
||||
android:importantForAutofill="noExcludeDescendants"
|
||||
tools:targetApi="o">
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/icon_edit_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:layout_marginEnd="@dimen/default_margin"
|
||||
android:src="@drawable/ic_blank_32dp"/>
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/icon_edit_name_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/icon_edit_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:hint="@string/hint_icon_name"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
@@ -56,7 +56,7 @@
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
style="@style/KeepassDXStyle.TextAppearance.WarningTextStyle"/>
|
||||
style="@style/KeepassDXStyle.TextAppearance.Warning"/>
|
||||
|
||||
<com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
android:id="@+id/progress_dialog_bar"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
android:layout_marginEnd="@dimen/card_view_margin_horizontal"
|
||||
android:layout_marginRight="@dimen/card_view_margin_horizontal"
|
||||
android:text="@string/error_otp_type"
|
||||
style="@style/KeepassDXStyle.TextAppearance.WarningTextStyle"/>
|
||||
style="@style/KeepassDXStyle.TextAppearance.Warning"/>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_view_otp_selection"
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:minHeight="56dp"
|
||||
android:maxHeight="72dp"
|
||||
android:minHeight="48dp"
|
||||
app:layout_constraintWidth_percent="@dimen/content_percent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
@@ -104,10 +103,12 @@
|
||||
tools:text="7543A7EAB2EA7CFD1394F1615EBEB08C" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/node_options"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="end"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginLeft="12dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
@@ -164,7 +165,7 @@
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/node_otp_container" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:minHeight="56dp"
|
||||
android:maxHeight="72dp"
|
||||
android:minHeight="48dp"
|
||||
app:layout_constraintWidth_percent="@dimen/content_percent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
@@ -89,18 +88,6 @@
|
||||
android:maxLines="2"
|
||||
tools:text="Node Title" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/node_subtext"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Group.SubTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:visibility="gone"
|
||||
tools:text="Node SubTitle" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/node_meta"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Group.Meta"
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
-->
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item android:id="@+id/menu_edit"
|
||||
android:icon="@drawable/ic_mode_edit_white_24dp"
|
||||
android:title="@string/menu_edit"
|
||||
android:orderInCategory="5"
|
||||
app:iconTint="?attr/colorControlNormal"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item android:id="@+id/menu_delete"
|
||||
android:icon="@drawable/ic_delete_forever_white_24dp"
|
||||
android:title="@string/menu_delete"
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
<string name="no_url_handler">ثبت متصفح لزيارة هذا الرابط.</string>
|
||||
<string name="progress_create">إنشاء قاعدة بيانات جديدة …</string>
|
||||
<string name="protection">الحماية</string>
|
||||
<string name="read_only">للقراءة فقط</string>
|
||||
<string name="read_only">محمي من التعديل</string>
|
||||
<string name="content_description_remove_from_list">حذف</string>
|
||||
<string name="root">الجذر</string>
|
||||
<string name="memory_usage">استخدام الذاكرة</string>
|
||||
@@ -99,10 +99,10 @@
|
||||
<string name="underline">تسطير</string>
|
||||
<string name="uppercase">حروف كبيرة</string>
|
||||
<string name="warning">تحذير</string>
|
||||
<string name="warning_empty_password">هل تريد حقاً استخدام سلسلة فارغة ككلمة سرية ؟</string>
|
||||
<string name="warning_no_encryption_key">هل أنت متأكد من أنك لا تريد استخدام أي مفتاح تشفير ؟</string>
|
||||
<string name="warning_empty_password">هل تريد المتابعة دون حماية قاعدة البيانات بكلمة سر ؟</string>
|
||||
<string name="warning_no_encryption_key">أمتأكد أنك لا تريد استخدام أي مفتاح لتشفير ؟</string>
|
||||
<string name="version_label">الإصدار %1$s</string>
|
||||
<string name="education_new_node_title">أضف عناصر جديدة إلى قاعدتك</string>
|
||||
<string name="education_new_node_title">أضف عناصر إلى قاعدة البيانات</string>
|
||||
<string name="education_entry_new_field_title">إضافة حقول مخصصة</string>
|
||||
<string name="education_field_copy_title">نسخ حقل</string>
|
||||
<string name="education_lock_title">تأمين قاعدة البيانات</string>
|
||||
@@ -111,7 +111,7 @@
|
||||
<string name="add_entry">إضافة مدخلة</string>
|
||||
<string name="edit_entry">تحرير مدخلة</string>
|
||||
<string name="key_derivation_function">وظيفة اشتقاق المفتاح</string>
|
||||
<string name="app_timeout">مهلة التطبيق</string>
|
||||
<string name="app_timeout">انتهت المهلة</string>
|
||||
<string name="app_timeout_summary">مدة الانتظار قبل إقفال قاعدة البيانات</string>
|
||||
<string name="file_manager_install_description">المحرر الذي يمتلك صلاحتي ACTION_CREATE_DOCUMENT و ACTION_OPEN_DOCUMENT ضروري لانشاء, وفتح وحفض قواعد البيانات.</string>
|
||||
<string name="clipboard_error">بعض الأجهزة لا تسمح للتطبيقات باستعمال الحافظة.</string>
|
||||
@@ -120,8 +120,8 @@
|
||||
<string name="select_to_copy">اختر لنسخ %1$s إلى الحافظة</string>
|
||||
<string name="retrieving_db_key">يجلب مفتاح قاعدة البيانات…</string>
|
||||
<string name="default_checkbox">استخدامها كقاعدة بيانات افتراضية</string>
|
||||
<string name="html_about_licence">KeePassDX © %1$d كونزيسوفت <strong>مفتوح المصدر</strong> و <strong>بدون اعلانات</strong>.
|
||||
\n يوزع كما هو، بدون ضمان, تحت ترخيص <strong>GPLv3</strong></string>
|
||||
<string name="html_about_licence">KeePassDX © %1$d كونزيسوفت <strong>مفتوح المصدر</strong> و <strong>بدون اعلانات</strong>.
|
||||
\n يوزع كما هو، بدون ضمان, تحت ترخيص <strong>GPLv3</strong>.</string>
|
||||
<string name="entry_accessed">نُفذ إليه</string>
|
||||
<string name="entry_expires">تنتهي صلاحيته في</string>
|
||||
<string name="entry_keyfile">ملف المفتاح</string>
|
||||
@@ -133,7 +133,7 @@
|
||||
<string name="error_load_database">تعذر تحميل قاعدة البيانات.</string>
|
||||
<string name="error_load_database_KDF_memory">لا يمكن تحميل المفتاح، حاول تقليل \"الذاكرة المستخدمة\" من قبل KDF.</string>
|
||||
<string name="error_pass_gen_type">يجب تحديد نوع واحد على الأقل لتوليد كلمة السر.</string>
|
||||
<string name="error_rounds_too_large">\"جولات\" كبيرة جداً. الإعداد إلى 2147483648.</string>
|
||||
<string name="error_rounds_too_large">\"جولات التحويل\" كثيرة جداً. الإعداد إلى 2147483648.</string>
|
||||
<string name="error_string_key">يجب أن يكون لكل سلسلة اسم حقل.</string>
|
||||
<string name="error_wrong_length">أدخل عددًا صحيحًا موجبًا في حقل «الطول».</string>
|
||||
<string name="error_autofill_enable_service">تعذر تمكين خدمة الملء التلقائي.</string>
|
||||
@@ -147,7 +147,7 @@
|
||||
<string name="hint_generated_password">كلمة السر الموَلدة</string>
|
||||
<string name="hint_keyfile">الملف المفتاحي</string>
|
||||
<string name="hide_password_title">اخفاء كلمات السر</string>
|
||||
<string name="copy_field">نُسخ %1$s</string>
|
||||
<string name="copy_field">نُسخة من %1$s</string>
|
||||
<string name="menu_copy">نسخ</string>
|
||||
<string name="menu_move">نقل</string>
|
||||
<string name="menu_paste">لصق</string>
|
||||
@@ -166,8 +166,8 @@
|
||||
<string name="unsupported_db_version">قاعدة بيانات غير مدعومة.</string>
|
||||
<string name="build_label">بناء %1$s</string>
|
||||
<string name="encrypted_value_stored">تم حفظ كلمة السر المشفرة</string>
|
||||
<string name="no_credentials_stored">قاعدة البيانات لا تمتلك كلمة سر.</string>
|
||||
<string name="menu_appearance_settings">مظهر</string>
|
||||
<string name="no_credentials_stored">قاعدة البيانات لا تمتلك بيانات اعتماد.</string>
|
||||
<string name="menu_appearance_settings">المظهر</string>
|
||||
<string name="general">عام</string>
|
||||
<string name="autofill">ملأ تلقائي</string>
|
||||
<string name="autofill_sign_in_prompt">سجل باستخدام KeePassDX</string>
|
||||
@@ -187,7 +187,7 @@
|
||||
<string name="file_name">اسم الملف</string>
|
||||
<string name="path">مسار</string>
|
||||
<string name="database_history">تأريخ</string>
|
||||
<string name="clipboard_notifications_summary">مكن اشعارات الحافظة لنسخ الحقول</string>
|
||||
<string name="clipboard_notifications_summary">أظهر اشعارات الحافظة لنسخ الحقول عند عرض مدخل</string>
|
||||
<string name="advanced_unlock">البصمة</string>
|
||||
<string name="biometric_unlock_enable_title">فحص البصمة</string>
|
||||
<string name="biometric_unlock_enable_summary">يسمح بفحص البصمة لفتح قاعدة البيانات</string>
|
||||
@@ -210,23 +210,23 @@
|
||||
<string name="keyboard_notification_entry_summary">أظهر إشعار عند توفر مدخل</string>
|
||||
<string name="keyboard_notification_entry_content_title_text">مدخل</string>
|
||||
<string name="keyboard_notification_entry_clear_close_title">إمسح عند الخروج</string>
|
||||
<string name="keyboard_notification_entry_clear_close_summary">إمسح مدخل الحافظة عند إغلاق الإشعار</string>
|
||||
<string name="keyboard_notification_entry_clear_close_summary">أغلق قاعدة البيانات عند إغلاق الإشعار</string>
|
||||
<string name="keyboard_appearance_category">مظهر</string>
|
||||
<string name="keyboard_theme_title">سمة لوحة المفاتيح</string>
|
||||
<string name="keyboard_keys_category">مفاتيح</string>
|
||||
<string name="keyboard_key_vibrate_title">إهتز عند اللمس</string>
|
||||
<string name="keyboard_key_vibrate_title">إهتزاز عند اللمس</string>
|
||||
<string name="keyboard_key_sound_title">صوت عند اللمس</string>
|
||||
<string name="allow_no_password_title">"إسمح بالفتح دون كلمة سر "</string>
|
||||
<string name="enable_read_only_title">محمي من التعديل</string>
|
||||
<string name="enable_read_only_summary">افتح قاعدة البيانات للقراءة فقط افتراضيا</string>
|
||||
<string name="enable_education_screens_title">شاشات تعليمية</string>
|
||||
<string name="reset_education_screens_summary">أعد عرض كل العناصر التعليمية</string>
|
||||
<string name="reset_education_screens_text">إعادة تعيين الشاشات التعليمية</string>
|
||||
<string name="reset_education_screens_summary">أعد عرض كل المعلومات التعليمية</string>
|
||||
<string name="reset_education_screens_text">إعادة تعيين الشاشات التلميحات</string>
|
||||
<string name="education_create_database_title">أنشئ قاعدة بيانات</string>
|
||||
<string name="education_create_database_summary">أنشئ ملف إدارة كلمات السر.</string>
|
||||
<string name="education_select_database_title">إفتح قاعدة بيانات</string>
|
||||
<string name="sort_recycle_bin_bottom">سلة المحذوفات في الأسفل</string>
|
||||
<string name="sort_db">قاعده بيانات طبيعية</string>
|
||||
<string name="sort_db">ترتيب طبيعي</string>
|
||||
<string name="sort_last_access_time">الوصول</string>
|
||||
<string name="lock">إقفال</string>
|
||||
<string name="assign_master_key">تعيين مفتاح رئيسي</string>
|
||||
@@ -246,9 +246,9 @@
|
||||
<string name="content_description_background">الخلفية</string>
|
||||
<string name="rounds">دورات التحويل</string>
|
||||
<string name="rounds_explanation">توفر الدورات الاضافية ضد هجوم توليد التركيبات ،لكنها تبطئ التحميل والحفظ.</string>
|
||||
<string name="memory_usage_explanation">مقدار الذاكرة لاستخدامها في دالة اشتقاق المفتاح.</string>
|
||||
<string name="memory_usage_explanation">مقدار الذاكرة المستخدمة في دالة اشتقاق المفتاح.</string>
|
||||
<string name="parallelism_explanation">درجة التوازي (عدد العمليات) لدالة اشتقاق المفتاح.</string>
|
||||
<string name="sort_groups_before">مجموعات قبل</string>
|
||||
<string name="sort_groups_before">المجموعات أولًا</string>
|
||||
<string name="selection_mode">نمط التحديد</string>
|
||||
<string name="do_not_kill_app">لا تقتل التطبيق…</string>
|
||||
<string name="content_description_node_children">العقد الفرعية</string>
|
||||
@@ -264,7 +264,7 @@
|
||||
<string name="content_description_update_from_list">تحديث</string>
|
||||
<string name="content_description_keyboard_close_fields">أغلق الحقول</string>
|
||||
<string name="error_create_database_file">لا يمكن انشاء قاعدة بيانات بكلمة السر وملف المفتاح الحاليين.</string>
|
||||
<string name="menu_advanced_unlock_settings">إلغاء القفل المتقدم</string>
|
||||
<string name="menu_advanced_unlock_settings">فك القفل المتقدم</string>
|
||||
<string name="entry_attachments">مرفقات</string>
|
||||
<string name="entry_history">السجل</string>
|
||||
<string name="entry_add_attachment">أضف مرفقا</string>
|
||||
@@ -283,7 +283,7 @@
|
||||
<string name="otp_algorithm">الخوارزمية</string>
|
||||
<string name="otp_digits">أرقام</string>
|
||||
<string name="otp_counter">العداد</string>
|
||||
<string name="entry_setup_otp">كلمة المرور للمرة الواحدة</string>
|
||||
<string name="entry_setup_otp">عيّن كلمة مرور لمرة واحدة</string>
|
||||
<string name="entry_UUID">UUID</string>
|
||||
<string name="html_about_contribution">من أجل <strong>حماية خصوصيتا</strong>٫<strong> إصلاح العلل</strong>٫ <strong>إضافة مميزات</strong> <strong>وجعلنا نشطاء دائما</strong>٫ نحن نعتمد على <strong>مساهمتك</strong>.</string>
|
||||
<string name="content_description_keyfile_checkbox">خانة تأشير الملف المفتاحي</string>
|
||||
@@ -295,10 +295,10 @@
|
||||
<string name="hide_broken_locations_title">اِخفي روابط قواعد البيانات المعطلة</string>
|
||||
<string name="show_recent_files_summary">أظهر موقع قواعد البيانات الأخيرة</string>
|
||||
<string name="show_recent_files_title">أظهر الملفات الأخيرة</string>
|
||||
<string name="remember_keyfile_locations_summary">تذكر موقع الملفات المفتاحية لقاعدة البيانات</string>
|
||||
<string name="remember_keyfile_locations_title">احفظ موقع الملف المفتاحي</string>
|
||||
<string name="remember_database_locations_summary">تذكر موقع قاعدة البيانات</string>
|
||||
<string name="remember_database_locations_title">موقع تخزين قاعدة البيانات</string>
|
||||
<string name="remember_keyfile_locations_summary">تعقب موقع الملفات المفتاحية لقاعدة البيانات</string>
|
||||
<string name="remember_keyfile_locations_title">تذكر موقع الملف المفتاحي</string>
|
||||
<string name="remember_database_locations_summary">تعقب موقع قاعدة البيانات</string>
|
||||
<string name="remember_database_locations_title">تذكر موقع تخزين قاعدة البيانات</string>
|
||||
<string name="contains_duplicate_uuid_procedure">للمتابعة هل تريد حل المشكلة بتوليد UUID للعناصر المكررة ؟</string>
|
||||
<string name="contains_duplicate_uuid">تحتوي قاعدة البيانات على UUID مكرر.</string>
|
||||
<string name="auto_focus_search_title">البحث السريع</string>
|
||||
@@ -379,8 +379,8 @@
|
||||
<string name="keyboard_selection_entry_title">اختيار المدخلة</string>
|
||||
<string name="device_keyboard_setting_title">إعدادات لوحة مفاتيح الجهاز</string>
|
||||
<string name="magic_keyboard_explanation_summary">نشِّط لوحة مفاتيح مخصصة لملأ كلمة السر وحقول معرّفك</string>
|
||||
<string name="biometric_auto_open_prompt_summary">اطلب فحص البصمة ان كانت قاعدة البيانات معدّة لذلك</string>
|
||||
<string name="biometric_auto_open_prompt_title">افتح محث البصمة تلقائيا</string>
|
||||
<string name="biometric_auto_open_prompt_summary">اطلب فك القفل المتقدم ان كانت قاعدة البيانات معدّة لذلك</string>
|
||||
<string name="biometric_auto_open_prompt_title">افتح المحث تلقائيا</string>
|
||||
<string name="keystore_not_accessible">لم يُهيأ مخزن المفاتيح بشكل صحيح.</string>
|
||||
<string name="warning_remove_unlinked_attachment">حذف البيانات سيقلل من حجم قاعدة البيانات لكن احذر أن تكون إحدى هذه البيانات ملحقة لكي-باس.</string>
|
||||
<string name="subdomain_search_summary">البحث في نطاقات الويب التي فيها قيود النطاقات الفرعية</string>
|
||||
@@ -408,4 +408,79 @@
|
||||
<string name="education_generate_password_title">أنشئ كلمة سر قوية</string>
|
||||
<string name="save_mode">وضع الحفظ</string>
|
||||
<string name="search_mode">وضع البحث</string>
|
||||
<string name="version">النسخة</string>
|
||||
<string name="template_group_name">النماذج</string>
|
||||
<string name="holder">الحامل</string>
|
||||
<string name="number">الرقم</string>
|
||||
<string name="card_verification_value">CVV</string>
|
||||
<string name="personal_identification_number">PIN</string>
|
||||
<string name="id_card">بطاقة الهوية</string>
|
||||
<string name="type">النوع</string>
|
||||
<string name="cryptocurrency">محفظة عملات مشفرة</string>
|
||||
<string name="public_key">المفتاح العمومي</string>
|
||||
<string name="private_key">المفتاح الخاص</string>
|
||||
<string name="account">الحساب</string>
|
||||
<string name="bank">مصرف</string>
|
||||
<string name="bank_name">اسم المصرف</string>
|
||||
<string name="secure_note">ملاحظة آمنة</string>
|
||||
<string name="error_word_reserved">هذه الكلمة محجوزة ولا يمكن استخدامها.</string>
|
||||
<string name="error_field_name_already_exists">اسم الحقل موجود سلفًا.</string>
|
||||
<string name="error_file_to_big">الملف الذي ترفعه كبير.</string>
|
||||
<string name="error_upload_file">حدث خطأ أثناء رفع الملف.</string>
|
||||
<string name="error_duplicate_file">بيانات الملف موجودة سلفًا.</string>
|
||||
<string name="error_remove_file">حدث خطأ أثناء إزالة بيانات الملف.</string>
|
||||
<string name="error_start_database_action">حدث خطأ أثناء تنفيذ إجراء على قاعدة البيانات.</string>
|
||||
<string name="content_description_otp_information">معلومات السر لمرة واحدة</string>
|
||||
<string name="membership">العضوية</string>
|
||||
<string name="name">الاسم</string>
|
||||
<string name="email">البريد الإلكتروني</string>
|
||||
<string name="email_address">البريد الإلكتروني</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="debit_credit_card">بطاقة السحب الفوري / الإئتمان</string>
|
||||
<string name="error_registration_read_only">لا يمكن حفظ عنصر في قاعدة بيانات مفتوحة للقراءة فقط</string>
|
||||
<string name="otp_secret">الرمز السري</string>
|
||||
<string name="place_of_issue">مكان المشكلة</string>
|
||||
<string name="date_of_issue">تاريخ المشكلة</string>
|
||||
<string name="standard">المعيار</string>
|
||||
<string name="template">النموذج</string>
|
||||
<string name="error_invalid_OTP">الرمز السري لـ OTP غير صالح.</string>
|
||||
<string name="error_otp_digits">يجب أن الرمز محتوًا بين %1$d و %2$d رقمًا.</string>
|
||||
<string name="autofill_select_entry">اختر مُدخلًا…</string>
|
||||
<string name="content">المحتوى</string>
|
||||
<string name="keyboard_save_search_info_title">احفظ المعلومات المشاركة</string>
|
||||
<string name="custom_fields">حقول مخصصة</string>
|
||||
<string name="back_to_previous_keyboard">عُد للوحة المفاتيح السابقة</string>
|
||||
<string name="select_entry">اختر مدخلًا</string>
|
||||
<string name="autofill_close_database_title">أغلق قاعدة البيانات</string>
|
||||
<string name="success_import_app_properties">أّستوردت خصائص التطبيق</string>
|
||||
<string name="success_export_app_properties">صُدرت خصائص التطبيق</string>
|
||||
<string name="warning_database_revoked">أُجهض الوصول إلى الملف بواسطة مدير الملفات ، أغلق قاعدة البيانات ثم أعد فتحها.</string>
|
||||
<string name="properties">الخصائص</string>
|
||||
<string name="token">الرمز</string>
|
||||
<string name="seed">البذرة</string>
|
||||
<string name="error_database_uri_null">يتعذر استرداد مسار قاعدة البيانات.</string>
|
||||
<string name="error_rebuild_list">يتعذر إعادة بناء القائمة بشكل صحيح.</string>
|
||||
<string name="menu_keystore_remove_key">احذف رمز فك القفل المتقدم</string>
|
||||
<string name="menu_form_filling_settings">تعبئة الحقول</string>
|
||||
<string name="menu_reload_database">أعد تحميل قاعدة البيانات</string>
|
||||
<string name="menu_external_icon">أيقونة خارجية</string>
|
||||
<string name="registration_mode">وضع التسجيل</string>
|
||||
<string name="import_app_properties_title">استورد خصائص التطبيق</string>
|
||||
<string name="import_app_properties_summary">اختر ملفًا لاستيراد خصائص التطبيق</string>
|
||||
<string name="export_app_properties_title">صدّر خصائص التطبيق</string>
|
||||
<string name="export_app_properties_summary">أنشئ ملفًا لتصدير خصائص التطبيق</string>
|
||||
<string name="error_import_app_properties">خطأ أثناء استيراد خصائص التطبيق</string>
|
||||
<string name="error_export_app_properties">خطأ أثناء تصدير خصائص التطبيق</string>
|
||||
<string name="warning_database_info_changed">غُيِّرت معلومات قاعدة البيانات من خارج هذا التطبيق.</string>
|
||||
<string name="warning_database_info_changed_options">اكتب فوق التعديلات الخارجية عن طريق حفظ قاعدة البيانات أو أعد تحميلها لتضمين هذه التغييرات.</string>
|
||||
<string name="open_advanced_unlock_prompt_store_credential">افتح محث فك القفل المتقدم لتخزين بيانات الاعتماد</string>
|
||||
<string name="open_advanced_unlock_prompt_unlock_database">افتح محث فك القفل المتقدم لفتح قاعدة البيانات</string>
|
||||
<string name="credential_before_click_advanced_unlock_button">اكتب كلمة السر، وأنقر هذا الزر.</string>
|
||||
<string name="device_credential">بيانات الاعتماد للجهاز</string>
|
||||
<string name="advanced_unlock_tap_delete">انفر لحذف مفاتيح فك القفل المتقدم</string>
|
||||
<string name="keyboard_search_share_title">ابحث في المعلومات المشاركة</string>
|
||||
<string name="keyboard_auto_go_action_title">إجراء اللمس التلقائي</string>
|
||||
<string name="keyboard_previous_fill_in_title">إجراء لمس تلقائي</string>
|
||||
<string name="keyboard_previous_lock_title">اقفل قاعدة البيانات</string>
|
||||
<string name="education_advanced_unlock_title">فك القفل المتقدم لقاعدة البيانات</string>
|
||||
</resources>
|
||||
@@ -197,7 +197,7 @@
|
||||
<string name="clipboard_warning">Vymazat historii schránky manuálně, pokud automatické vymazání schránky selže.</string>
|
||||
<string name="lock">Zamknout</string>
|
||||
<string name="lock_database_screen_off_title">Zámek obrazovky</string>
|
||||
<string name="lock_database_screen_off_summary">Při zhasnutí obrazovky uzamknout databázi</string>
|
||||
<string name="lock_database_screen_off_summary">Několik vteřin po zhasnutí obrazovky uzamknout databázi</string>
|
||||
<string name="advanced_unlock">Rozšířené odemknutí</string>
|
||||
<string name="biometric_unlock_enable_title">Biometrické odemknutí</string>
|
||||
<string name="biometric_unlock_enable_summary">Nechá otevřít databázi snímáním biometrického údaje</string>
|
||||
@@ -224,7 +224,7 @@
|
||||
<string name="application_appearance">Rozhraní</string>
|
||||
<string name="other">Ostatní</string>
|
||||
<string name="keyboard">Klávesnice</string>
|
||||
<string name="magic_keyboard_title">Magikeyboard</string>
|
||||
<string name="magic_keyboard_title">Klávesnice Magikeyboard</string>
|
||||
<string name="magic_keyboard_explanation_summary">Aktivovat vlastní klávesnici, která snadno vyplní hesla a další položky identity</string>
|
||||
<string name="allow_no_password_title">Umožnit bez hlavního klíče</string>
|
||||
<string name="allow_no_password_summary">Povolit klepnutí na \"Otevřít\", i když není vybráno žádné heslo</string>
|
||||
@@ -236,7 +236,7 @@
|
||||
<string name="reset_education_screens_summary">Opět zobrazit všechny vzdělávací informace</string>
|
||||
<string name="reset_education_screens_text">Nastavit vzdělávací nápovědy do výchozího stavu</string>
|
||||
<string name="education_create_database_title">Vytvořit databázový soubor</string>
|
||||
<string name="education_create_database_summary">Založte svůj první soubor pro správu hesel.</string>
|
||||
<string name="education_create_database_summary">Vytvořte svůj první soubor pro správu hesel.</string>
|
||||
<string name="education_select_database_title">Otevřít existující databázi</string>
|
||||
<string name="education_select_database_summary">Otevřete svou dříve používanou databázi ze správce souborů a pokračujte v jejím používání.</string>
|
||||
<string name="education_new_node_title">Přidejte záznamy do databáze</string>
|
||||
@@ -267,7 +267,7 @@
|
||||
<string name="education_sort_summary">Vyberte řazení položek a skupin.</string>
|
||||
<string name="education_donation_title">Zapojit se</string>
|
||||
<string name="education_donation_summary">Zapojte se a pomozte zvýšit stabilitu, bezpečnost a doplnění dalších funkcí.</string>
|
||||
<string name="html_text_ad_free">Na rozdíl od mnoha aplikací pro správu hesel je tato <strong>bez reklam</strong>, je \u0020<strong>svobodný software pod copyleft licencí</strong> a nesbírá žádné osobní údaje na svých serverech bez ohledu na to, jakou verzi používáte.</string>
|
||||
<string name="html_text_ad_free">Na rozdíl od mnoha aplikací pro správu hesel je tato <strong>bez reklam</strong>, je <strong>svobodný software pod copyleft licencí</strong> a nesbírá žádné osobní údaje na svých serverech bez ohledu na to, jakou verzi používáte.</string>
|
||||
<string name="html_text_buy_pro">Zakoupením varianty \"pro\" získáte přístup k tomuto <strong>vizuálnímu stylu</strong> a hlavně pomůžete <strong>uskutečnění komunitních projektů.</strong></string>
|
||||
<string name="html_text_feature_generosity">Tento <strong>vizuální styl</strong> je k dispozici díky vaší štědrosti.</string>
|
||||
<string name="html_text_donation">Pro zajištění svobody nás všech a pokračování aktivity počítáme s Vaším <strong>přispěním.</strong></string>
|
||||
@@ -285,8 +285,8 @@
|
||||
<string name="icon_pack_choose_title">Sada ikon</string>
|
||||
<string name="icon_pack_choose_summary">Sada ikon používaných v aplikaci</string>
|
||||
<string name="build_label">Sestavení %1$s</string>
|
||||
<string name="keyboard_name">Magikeyboard</string>
|
||||
<string name="keyboard_label">Magikeyboard (KeePassDX)</string>
|
||||
<string name="keyboard_name">Klávesnice Magikeyboard</string>
|
||||
<string name="keyboard_label">Klávesnice Magikeyboard (KeePassDX)</string>
|
||||
<string name="keyboard_setting_label">Magikeyboard nastavení</string>
|
||||
<string name="keyboard_entry_category">Záznam</string>
|
||||
<string name="keyboard_entry_timeout_title">Časový limit</string>
|
||||
@@ -315,7 +315,7 @@
|
||||
<string name="delete_entered_password_title">Smazat heslo</string>
|
||||
<string name="delete_entered_password_summary">Smaže heslo zadané po pokusu o připojení k databázi</string>
|
||||
<string name="content_description_open_file">Otevřít soubor</string>
|
||||
<string name="content_description_node_children">Podřazené prvky uzlu</string>
|
||||
<string name="content_description_node_children">Podřazení uzlu</string>
|
||||
<string name="content_description_add_node">Přidat uzel</string>
|
||||
<string name="content_description_add_entry">Přidat záznam</string>
|
||||
<string name="content_description_add_group">Přidat skupinu</string>
|
||||
@@ -411,7 +411,7 @@
|
||||
<string name="hide_expired_entries_summary">Propadlé záznamy nebudou ukázány</string>
|
||||
<string name="contact">Kontakt</string>
|
||||
<string name="contribution">Příspěvky</string>
|
||||
<string name="feedback">Feedback</string>
|
||||
<string name="feedback">Zpětná vazba</string>
|
||||
<string name="auto_focus_search_title">Snadné hledání</string>
|
||||
<string name="auto_focus_search_summary">Při otevření databáze žádat hledání</string>
|
||||
<string name="remember_database_locations_title">Pamatovat si umístění databází</string>
|
||||
@@ -474,13 +474,13 @@
|
||||
<string name="database_data_remove_unlinked_attachments_summary">Odstraní přílohy obsažené v databázi, ale nikoli přílohy propojené se záznamem</string>
|
||||
<string name="education_add_attachment_title">Přidat přílohu</string>
|
||||
<string name="education_add_attachment_summary">Nahrát přílohu k záznamu pro uložení důležitých externích dat.</string>
|
||||
<string name="show_uuid_summary">Ukáže UUID propojené se záznamem</string>
|
||||
<string name="show_uuid_summary">Ukáže UUID propojené se záznamem nebo skupinou</string>
|
||||
<string name="show_uuid_title">Ukázat UUID</string>
|
||||
<string name="autofill_read_only_save">Uložení dat není povoleno, je-li databáze v režimu pouze pro čtení.</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Zeptat se na uložení dat, jakmile byl formulář přezkoušen</string>
|
||||
<string name="autofill_ask_to_save_data_title">Zeptat se před uložením</string>
|
||||
<string name="autofill_save_search_info_summary">Pokuste se uložit údaje hledání, když manuálně vybíráte položku</string>
|
||||
<string name="autofill_save_search_info_title">Uložit info hledání</string>
|
||||
<string name="autofill_save_search_info_title">Uložit výsledky vyhledávání</string>
|
||||
<string name="autofill_close_database_summary">Zavřít databázi po samovyplnění polí</string>
|
||||
<string name="autofill_close_database_title">Zavřít databázi</string>
|
||||
<string name="keyboard_previous_lock_summary">Po uzamknutí databáze automaticky přepnout zpět na předchozí klávesnici</string>
|
||||
@@ -491,9 +491,9 @@
|
||||
<string name="biometric_security_update_required">Vyžadována aktualizace biometrického zabezpečení.</string>
|
||||
<string name="configure_biometric">Žádné přihlašovací ani biometrické údaje nejsou registrovány.</string>
|
||||
<string name="warning_empty_recycle_bin">Trvale odstranit všechny uzly z koše\?</string>
|
||||
<string name="registration_mode">Režim registrace</string>
|
||||
<string name="save_mode">Režim ukládání</string>
|
||||
<string name="search_mode">Režim vyhledávání</string>
|
||||
<string name="registration_mode">Registrace</string>
|
||||
<string name="save_mode">Uložit</string>
|
||||
<string name="search_mode">Vyhledávání</string>
|
||||
<string name="error_field_name_already_exists">Jméno kolonky již existuje.</string>
|
||||
<string name="error_registration_read_only">Uložení nové položky v režimu databáze pouze pro čtení není povoleno</string>
|
||||
<string name="enter">Enter</string>
|
||||
@@ -596,4 +596,10 @@
|
||||
<string name="holder">Majitel</string>
|
||||
<string name="debit_credit_card">Debitní / Kreditní karta</string>
|
||||
<string name="template_group_name">Předlohy</string>
|
||||
<string name="show_otp_token_summary">Ukáže OTP tokeny v seznamu záznamů</string>
|
||||
<string name="show_otp_token_title">Ukázat OTP token</string>
|
||||
<string name="menu_external_icon">Externí ikona</string>
|
||||
<string name="autofill_select_entry">Vyberte položku…</string>
|
||||
<string name="autofill_manual_selection_summary">Zobrazit možnosti umožňující uživateli si vybrat položku z databáze</string>
|
||||
<string name="autofill_manual_selection_title">Ruční výběr</string>
|
||||
</resources>
|
||||
@@ -75,7 +75,7 @@
|
||||
<string name="error_out_of_memory">Zu wenig Speicherplatz, um die ganze Datenbank zu laden.</string>
|
||||
<string name="error_pass_gen_type">Mindestens eine Art der Passwortgenerierung muss ausgewählt sein.</string>
|
||||
<string name="error_pass_match">Die Passwörter stimmen nicht überein.</string>
|
||||
<string name="error_rounds_too_large">„Transformationsrunden“ zu hoch. Wird auf 2147483648 eingestellt.</string>
|
||||
<string name="error_rounds_too_large">„Schlüsseltransformationen“ zu hoch. Wird auf 2147483648 eingestellt.</string>
|
||||
<string name="error_string_key">Für jede Zeichenfolge ist ein Feldname notwendig.</string>
|
||||
<string name="error_wrong_length">Eine positive ganze Zahl in das Feld „Länge“ eingeben.</string>
|
||||
<string name="field_name">Feldname</string>
|
||||
@@ -160,7 +160,7 @@
|
||||
<string name="clipboard_notifications_title">Zwischenablage-Benachrichtigung</string>
|
||||
<string name="clipboard_notifications_summary">Benachrichtigungen zur Zwischenablage anzeigen, um beim Betrachten eines Eintrags Felder kopieren zu können</string>
|
||||
<string name="lock_database_screen_off_title">Bildschirmsperre</string>
|
||||
<string name="lock_database_screen_off_summary">Datenbank sperren, wenn der Bildschirm ausgeschaltet wird</string>
|
||||
<string name="lock_database_screen_off_summary">Datenbank sperren, einige Sekunden nachdem der Bildschirm ausgeschaltet wird</string>
|
||||
<string name="create_keepass_file">Neue Datenbank erstellen</string>
|
||||
<string name="assign_master_key">Hauptschlüssel zuweisen</string>
|
||||
<string name="path">Pfad</string>
|
||||
@@ -490,7 +490,7 @@
|
||||
<string name="education_add_attachment_title">Anhang hinzufügen</string>
|
||||
<string name="database_data_remove_unlinked_attachments_summary">Entfernt Anhänge die in der Datenbank enthalten, aber keinem Eintrag zugeordnet sind</string>
|
||||
<string name="warning_sure_add_file">Soll die Datei trotzdem hinzugefügt werden\?</string>
|
||||
<string name="show_uuid_summary">Zeigt die mit einem Eintrag verknüpfte UUID an</string>
|
||||
<string name="show_uuid_summary">Zeigt die mit einem Eintrag oder einer Gruppe verknüpfte UUID an</string>
|
||||
<string name="show_uuid_title">UUID anzeigen</string>
|
||||
<string name="autofill_read_only_save">Das Speichern von Daten ist für eine als schreibgeschützt geöffnete Datenbank nicht zulässig.</string>
|
||||
<string name="autofill_close_database_title">Datenbank schließen</string>
|
||||
@@ -610,4 +610,7 @@
|
||||
<string name="wireless">WLAN</string>
|
||||
<string name="email_address">E-Mail-Adresse</string>
|
||||
<string name="email">E-Mail</string>
|
||||
<string name="menu_external_icon">Externes Symbol</string>
|
||||
<string name="show_otp_token_summary">Zeigt OTP-Tokens in der Liste der Einträge an</string>
|
||||
<string name="show_otp_token_title">OTP-Token anzeigen</string>
|
||||
</resources>
|
||||
@@ -182,7 +182,7 @@
|
||||
<string name="clipboard_notifications_summary">Εμφάνιση ειδοποιήσεων πρόχειρου για αντιγραφή πεδίων κατά την προβολή μιας καταχώρησης</string>
|
||||
<string name="lock">Κλείδωμα</string>
|
||||
<string name="lock_database_screen_off_title">Κλείδωμα Οθόνης</string>
|
||||
<string name="lock_database_screen_off_summary">Κλείδωμα της βάσης δεδομένων όταν η οθόνη είναι απενεργοποιημένη</string>
|
||||
<string name="lock_database_screen_off_summary">Κλείδωμα της βάση δεδομένων μετά από μερικά δευτερόλεπτα μόλις η οθόνη είναι απενεργοποιηθεί</string>
|
||||
<string name="unavailable_feature_text">Δεν ήταν δυνατή η εκκίνηση αυτής της λειτουργίας.</string>
|
||||
<string name="unavailable_feature_version">Η συσκευή τρέχει Android %1$s, αλλά χρειάζεται %2$s ή μεταγενέστερη έκδοση.</string>
|
||||
<string name="unavailable_feature_hardware">Δεν ήταν δυνατή η εύρεση του αντίστοιχου υλικού.</string>
|
||||
@@ -473,7 +473,7 @@
|
||||
<string name="error_string_type">Αυτό το κείμενο δεν ταιριάζει με το ζητούμενο στοιχείο.</string>
|
||||
<string name="content_description_credentials_information">Πληροφορίες Διαπιστευτηρίων</string>
|
||||
<string name="content_description_add_item">Προσθήκη είδους</string>
|
||||
<string name="show_uuid_summary">Εμφανίζει το UUID που είναι συνδεδεμένο σε μια καταχώριση</string>
|
||||
<string name="show_uuid_summary">Εμφανίζει το UUID που είναι συνδεδεμένο σε μια καταχώρηση ή σε μια ομάδα</string>
|
||||
<string name="show_uuid_title">Εμφάνιση UUID</string>
|
||||
<string name="autofill_read_only_save">Δεν επιτρέπεται η αποθήκευση δεδομένων για μια βάση δεδομένων που ανοίγει ως μόνο για ανάγνωση.</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Ζητήστε να αποθηκεύσετε δεδομένα όταν επικυρώνεται μια φόρμα</string>
|
||||
@@ -583,7 +583,7 @@
|
||||
<string name="cryptocurrency">Πορτοφόλι κρυπτονομισμάτων</string>
|
||||
<string name="type">Τύπος</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="wireless">Wifi</string>
|
||||
<string name="wireless">Wi-Fi</string>
|
||||
<string name="email_address">Διεύθυνση ηλεκτρονικού ταχυδρομείου</string>
|
||||
<string name="email">Email</string>
|
||||
<string name="date_of_issue">Ημερομηνία έκδοσης</string>
|
||||
@@ -596,4 +596,10 @@
|
||||
<string name="holder">Κάτοχος</string>
|
||||
<string name="debit_credit_card">Χρεωστική / Πιστωτική Κάρτα</string>
|
||||
<string name="template_group_name">Πρότυπα</string>
|
||||
<string name="show_otp_token_summary">Εμφανίζει OTP tokens στη λίστα καταχωρήσεων</string>
|
||||
<string name="show_otp_token_title">Εμφάνιση OTP Token</string>
|
||||
<string name="menu_external_icon">Εξωτερικό εικονίδιο</string>
|
||||
<string name="autofill_manual_selection_summary">Εμφάνισης επιλογής για να επιτρέψει στον χρήστη να επιλέξει την καταχώρηση βάσης δεδομένων</string>
|
||||
<string name="autofill_manual_selection_title">Χειροκίνητη επιλογή</string>
|
||||
<string name="autofill_select_entry">Επιλογή καταχώρησης…</string>
|
||||
</resources>
|
||||
@@ -189,7 +189,7 @@
|
||||
<string name="clipboard_notifications_summary">Mostrar las notificaciones del portapapeles para copiar campos al examinar una entrada</string>
|
||||
<string name="lock">Bloquear</string>
|
||||
<string name="lock_database_screen_off_title">Bloqueo de pantalla</string>
|
||||
<string name="lock_database_screen_off_summary">Bloquear la base de datos cuando la pantalla esté apagada</string>
|
||||
<string name="lock_database_screen_off_summary">Bloquear la base de datos después de unos segundos cuando la pantalla esté apagada</string>
|
||||
<string name="advanced_unlock">Desbloqueo avanzado</string>
|
||||
<string name="biometric_unlock_enable_title">Desbloqueo biométrico</string>
|
||||
<string name="biometric_unlock_enable_summary">Le permite escanear sus datos biométricos para abrir la base de datos</string>
|
||||
@@ -525,7 +525,7 @@
|
||||
<string name="keyboard_save_search_info_summary">Luego de compartir un URL con KeePassDX, cuando se selecciona una entrada, intentar recordarla para futuros usos</string>
|
||||
<string name="keyboard_save_search_info_title">Guardar información compartida</string>
|
||||
<string name="keyboard_search_share_summary">Al compartir un URL con KeePassDX, filtrar las entradas utilizando el dominio de ese URL</string>
|
||||
<string name="show_uuid_summary">Muestra el UUID vinculado a una entrada</string>
|
||||
<string name="show_uuid_summary">Muestra el UUID vinculado a una entrada o a un grupo</string>
|
||||
<string name="show_uuid_title">Mostrar UUID</string>
|
||||
<string name="error_rebuild_list">No es posible reconstruir adecuadamente la lista.</string>
|
||||
<string name="error_database_uri_null">La URI de la base de datos no puede ser recuperada.</string>
|
||||
@@ -598,4 +598,10 @@
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="personal_identification_number">Número de Identificación Personal</string>
|
||||
<string name="card_verification_value">CVV</string>
|
||||
<string name="show_otp_token_summary">Muestra los tokens OTP en la lista de entradas</string>
|
||||
<string name="show_otp_token_title">Mostrar token OTP</string>
|
||||
<string name="menu_external_icon">Icono externo</string>
|
||||
<string name="autofill_manual_selection_summary">Mostrar opción para permitir al usuario seleccionar la entrada de la base de datos</string>
|
||||
<string name="autofill_manual_selection_title">Selección manual</string>
|
||||
<string name="autofill_select_entry">Seleccionar entrada…</string>
|
||||
</resources>
|
||||
@@ -2,7 +2,7 @@
|
||||
<resources>
|
||||
<string name="menu_appearance_settings">ظاهر</string>
|
||||
<string name="database_history">تاریخچه</string>
|
||||
<string name="no_credentials_stored">این پایگاه داده هنوز اطلاعات کاربری ذخیره نشده است.</string>
|
||||
<string name="no_credentials_stored">در این پایگاه داده هنوز اعتبار نامه ذخیره نشده است.</string>
|
||||
<string name="encrypted_value_stored">رمز رمزگذاری شده ذخیره شده است</string>
|
||||
<string name="keystore_not_accessible">فروشگاه اصلی به درستی تنظیم نشده است.</string>
|
||||
<string name="build_label">%1$s را بسازید</string>
|
||||
@@ -117,7 +117,7 @@
|
||||
<string name="invalid_db_sig">نمی توانست فرمت پایگاه داده را تشخیص دهد.</string>
|
||||
<string name="invalid_db_same_uuid">%1$s با همان UUID %2$s در حال حاضر وجود دارد.</string>
|
||||
<string name="invalid_algorithm">الگوریتم اشتباه</string>
|
||||
<string name="invalid_credentials">نمی توانست اعتبارنامه ها را بخواند.</string>
|
||||
<string name="invalid_credentials">نمی توان اعتبار نامه را خواند.</string>
|
||||
<string name="password">رمز عبور</string>
|
||||
<string name="hint_pass">رمز عبور</string>
|
||||
<string name="hint_length">طول</string>
|
||||
@@ -138,11 +138,11 @@
|
||||
<string name="error_save_database">نمی توانست پایگاه داده را ذخیره کند.</string>
|
||||
<string name="error_create_database_file">قادر به ایجاد پایگاه داده با این رمز عبور و keyfile نیست.</string>
|
||||
<string name="error_create_database">قادر به ایجاد فایل پایگاه داده نیست.</string>
|
||||
<string name="error_copy_group_here">شما نمی توانید یک گروه را در اینجا کپی کنید.</string>
|
||||
<string name="error_copy_group_here">در اینجا نمی توانید گروهی را کپی کنید.</string>
|
||||
<string name="error_copy_entry_here">شما نمی توانید یک ورودی را در اینجا کپی کنید.</string>
|
||||
<string name="error_move_entry_here">شما نمی توانید یک ورودی را به اینجا منتقل کنید.</string>
|
||||
<string name="error_autofill_enable_service">قادر به فعال کردن سرویس پر کردن خودکار نبود.</string>
|
||||
<string name="error_wrong_length">یک عدد کامل مثبت را در زمینه \"طول\" وارد کنید.</string>
|
||||
<string name="error_wrong_length">در قسمت \"طول\" یک عدد صحیح مثبت وارد کنید.</string>
|
||||
<string name="error_label_exists">این برچسب در حال حاضر وجود دارد.</string>
|
||||
<string name="error_string_key">هر رشته باید یک نام فیلد داشته باشد.</string>
|
||||
<string name="error_rounds_too_large">\"دور تحول\" بیش از حد بالا است. تنظیم به 2147483648.</string>
|
||||
@@ -157,7 +157,7 @@
|
||||
<string name="error_invalid_OTP">راز OTP نامعتبر.</string>
|
||||
<string name="error_invalid_path">مطمئن شوید که مسیر درست است</string>
|
||||
<string name="error_invalid_db">نمی توانست پایگاه داده را بخواند.</string>
|
||||
<string name="error_file_not_create">نمی تواند پرونده ایجاد کند:</string>
|
||||
<string name="error_file_not_create">نمی تواند پرونده ایجاد کند</string>
|
||||
<string name="error_can_not_handle_uri">نمی تواند این URI در KeePassDX رسیدگی کند.</string>
|
||||
<string name="error_arc4">رمز جریان Arcfour پشتیبانی نمی شود</string>
|
||||
<string name="entry_user_name">نام کاربری</string>
|
||||
@@ -194,12 +194,12 @@
|
||||
<string name="database">پایگاه داده</string>
|
||||
<string name="retrieving_db_key">بازیابی کلید پایگاه داده…</string>
|
||||
<string name="select_to_copy">انتخاب برای کپی %1$s به کلیپ بورد</string>
|
||||
<string name="content_description_keyboard_close_fields">زمینه های نزدیک</string>
|
||||
<string name="content_description_keyboard_close_fields">بستن فیلد</string>
|
||||
<string name="content_description_remove_from_list">حذف</string>
|
||||
<string name="content_description_update_from_list">روز رسانی</string>
|
||||
<string name="content_description_update_from_list">به روز رسانی</string>
|
||||
<string name="content_description_remove_field">حذف فیلد</string>
|
||||
<string name="entry_add_attachment">افزودن پیوست</string>
|
||||
<string name="entry_add_field">اضافه کردن زمینه</string>
|
||||
<string name="entry_add_field">اضافه کردن فیلد</string>
|
||||
<string name="content_description_password_length">طول رمز عبور</string>
|
||||
<string name="entry_password_generator">ژنراتور رمز عبور</string>
|
||||
<string name="discard">دور انداختن</string>
|
||||
@@ -224,12 +224,12 @@
|
||||
<string name="clipboard_error_title">خطای کلیپ بورد</string>
|
||||
<string name="clipboard_cleared">کلیپ بورد پاک شد</string>
|
||||
<string name="allow">اجازه</string>
|
||||
<string name="file_manager_install_description">یک مدیر پرونده که عمل Intent را می پذیرد ACTION_CREATE_DOCUMENT و ACTION_OPEN_DOCUMENT برای ایجاد، باز کردن و ذخیره فایل های پایگاه داده مورد نیاز است.</string>
|
||||
<string name="file_manager_install_description">برای ایجاد ، بازکردن و ذخیره فایل های پایگاه داده ، یک مدیر فایل که عملیات ACTION_CREATE_DOCUMENT و ACTION_OPEN_DOCUMENT را می پذیرد ، مورد نیاز است.</string>
|
||||
<string name="extended_ASCII">گسترش ASCII</string>
|
||||
<string name="brackets">براکت</string>
|
||||
<string name="application">برنامه</string>
|
||||
<string name="app_timeout_summary">زمان بیکار قبل از قفل کردن پایگاه داده</string>
|
||||
<string name="app_timeout">تایم آوت برنامه</string>
|
||||
<string name="app_timeout">اتمام زمان</string>
|
||||
<string name="key_derivation_function">تابع مشتق کلید</string>
|
||||
<string name="encryption_algorithm">الگوریتم رمزنگاری</string>
|
||||
<string name="encryption">رمزگذاری</string>
|
||||
@@ -245,4 +245,83 @@
|
||||
<string name="contribution">سهم</string>
|
||||
<string name="contact">مخاطب</string>
|
||||
<string name="filter">فیلتر</string>
|
||||
<string name="allow_no_password_summary">در صورت عدم انتخاب اعتبار نامه ، ضربه زدن روی دکمه \"باز کردن\" امکان پذیر است</string>
|
||||
<string name="keyboard_previous_database_credentials_summary">به طور خودکار به صفحه کلید قبلی در صفحه اعتبار نامه پایگاه داده برگردید</string>
|
||||
<string name="keyboard_previous_database_credentials_title">صفحه اعتبار نامه پایگاه داده</string>
|
||||
<string name="open_advanced_unlock_prompt_store_credential">برای ذخیره اعتبار نامه ، قفل پیشرفته را باز کنید</string>
|
||||
<string name="open_advanced_unlock_prompt_unlock_database">برای باز کردن قفل پایگاه داده قفل پیشرفته را باز کنید</string>
|
||||
<string name="biometric_security_update_required">به روز رسانی امنیتی بیومتریک مورد نیاز است.</string>
|
||||
<string name="configure_biometric">هیچ بیومتریک یا اعتبار دستگاه ثبت نشده است.</string>
|
||||
<string name="advanced_unlock_tap_delete">برای حذف کلیدهای پیشرفته باز کردن قفل ضربه بزنید</string>
|
||||
<string name="advanced_unlock">باز کردن قفل پیشرفته</string>
|
||||
<string name="content">محتوا</string>
|
||||
<string name="warning_database_revoked">دسترسی به پرونده توسط مدیر فایل لغو شده ، پایگاه داده را ببندید و مجدداً از محل آن باز کنید.</string>
|
||||
<string name="warning_database_info_changed_options">با ذخیره کردن پایگاه داده ، تغییرات خارجی را بازنویسی کنید یا با جدیدترین تغییرات آن را بارگیری کنید.</string>
|
||||
<string name="warning_database_info_changed">اطلاعات موجود در فایل پایگاه داده شما خارج از برنامه دستکاری شده است.</string>
|
||||
<string name="warning_empty_keyfile_explanation">محتوای فایل کلید هرگز نباید تغییر کند و در بهترین حالت باید حاوی داده های تصادفی تولید شده باشد.</string>
|
||||
<string name="warning_empty_keyfile">توصیه نمی شود یک فایل کلید خالی اضافه کنید.</string>
|
||||
<string name="warning_sure_remove_data">به هر حال این داده ها حذف شود؟</string>
|
||||
<string name="warning_remove_unlinked_attachment">حذف داده های پیوند نشده ممکن است حجم پایگاه داده شما را کاهش دهد اما همچنین ممکن است داده های مورد استفاده برای افزونه های KeePass را حذف کند.</string>
|
||||
<string name="warning_sure_add_file">به هر حال فایل اضافه شود؟</string>
|
||||
<string name="warning_replace_file">بارگذاری این فایل جایگزین فایل موجود می شود.</string>
|
||||
<string name="warning_file_too_big">قرار است پایگاه داده KeePass فقط حاوی فایلهای مفید کوچک (مانند فایلهای کلیدی PGP) باشد.
|
||||
\n
|
||||
\nممکن است پایگاه داده شما بسیار بزرگ شود و با این بارگذاری عملکرد را کاهش دهید.</string>
|
||||
<string name="warning_empty_recycle_bin">آیا همه کلید ها از سطل بازیافت به طور دائم حذف می شوند؟</string>
|
||||
<string name="error_export_app_properties">خطا در هنگام صادرات ویژگی های برنامه</string>
|
||||
<string name="success_export_app_properties">ویژگی های برنامه صادر شد</string>
|
||||
<string name="error_import_app_properties">خطا در هنگام وارد کردن ویژگی های برنامه</string>
|
||||
<string name="success_import_app_properties">ویژگی های برنامه وارد شد</string>
|
||||
<string name="description_app_properties">ویژگی های KeePassDX برای مدیریت تنظیمات برنامه</string>
|
||||
<string name="export_app_properties_summary">یک فایل برای صادر کردن ویژگی های برنامه ایجاد کنید</string>
|
||||
<string name="import_app_properties_summary">یک فایل برای وارد کردن ویژگی های برنامه انتخاب کنید</string>
|
||||
<string name="import_app_properties_title">وارد کردن ویژگی های برنامه</string>
|
||||
<string name="export_app_properties_title">صادر کردن ویژگی های برنامه</string>
|
||||
<string name="registration_mode">حالت ثبت</string>
|
||||
<string name="save_mode">حالت ذخیره</string>
|
||||
<string name="search_mode">حالت جستجو</string>
|
||||
<string name="menu_external_icon">نماد خارجی</string>
|
||||
<string name="menu_keystore_remove_key">حذف کلید باز کردن پیشرفته</string>
|
||||
<string name="menu_reload_database">بارگیری مجدد پایگاه داده</string>
|
||||
<string name="error_start_database_action">هنگام انجام عملیات در پایگاه داده خطایی روی داد.</string>
|
||||
<string name="error_remove_file">هنگام حذف داده های فایل خطایی روی داد.</string>
|
||||
<string name="error_duplicate_file">داده های فایل قبلاً وجود دارد.</string>
|
||||
<string name="error_upload_file">هنگام بارگذاری داده های فایل خطایی روی داد.</string>
|
||||
<string name="error_file_to_big">فایلی که می خواهید بارگذاری کنید بسیار بزرگ است.</string>
|
||||
<string name="error_rebuild_list">نمی توان لیست را به درستی بازسازی کرد.</string>
|
||||
<string name="error_database_uri_null">URI پایگاه داده بازیابی نمی شود.</string>
|
||||
<string name="error_field_name_already_exists">نام فیلد از قبل موجود است.</string>
|
||||
<string name="error_registration_read_only">ذخیره یک مورد جدید در پایگاه داده \"فقط خواندنی\" مجاز نیست</string>
|
||||
<string name="error_otp_type">نوع OTP موجود توسط این فرم شناخته نمی شود ، اعتبار آن ممکن است دیگر توکن را به درستی تولید نکند.</string>
|
||||
<string name="id_card">ID Card</string>
|
||||
<string name="card_verification_value">CVV</string>
|
||||
<string name="error_word_reserved">این کلمه رزرو است و نمی توان از آن استفاده کرد.</string>
|
||||
<string name="version">نسخه</string>
|
||||
<string name="template">الگو</string>
|
||||
<string name="standard">استاندارد</string>
|
||||
<string name="membership">اعضا</string>
|
||||
<string name="secure_note">یادداشت امن</string>
|
||||
<string name="ssid">نام وای فای(SSID)</string>
|
||||
<string name="bank_identifier_code">SWIFT / BIC</string>
|
||||
<string name="international_bank_account_number">IBAN (شبا)</string>
|
||||
<string name="bank_name">نام بانک</string>
|
||||
<string name="bank">بانک</string>
|
||||
<string name="account">حساب کاربری</string>
|
||||
<string name="seed">بذر</string>
|
||||
<string name="private_key">کلید خصوصی</string>
|
||||
<string name="public_key">کلید عمومی</string>
|
||||
<string name="token">توکن</string>
|
||||
<string name="cryptocurrency">کیف پول ارز دیجیتال</string>
|
||||
<string name="type">نوع</string>
|
||||
<string name="email_address">آدرس ایمیل</string>
|
||||
<string name="email">ایمیل</string>
|
||||
<string name="date_of_issue">تاریخ صدور</string>
|
||||
<string name="place_of_issue">محل صدور</string>
|
||||
<string name="name">نام</string>
|
||||
<string name="personal_identification_number">پین(رمز)</string>
|
||||
<string name="number">عدد</string>
|
||||
<string name="holder">صاحب</string>
|
||||
<string name="template_group_name">الگو ها</string>
|
||||
<string name="content_description_otp_information">اطلاعات رمز یکبار مصرف</string>
|
||||
<string name="content_description_credentials_information">اطلاعات اعتبار نامه</string>
|
||||
</resources>
|
||||
@@ -182,7 +182,7 @@
|
||||
<string name="clipboard_warning">Si la suppression automatique du presse-papier échoue, supprimer son historique manuellement.</string>
|
||||
<string name="lock">Verrouiller</string>
|
||||
<string name="lock_database_screen_off_title">Verrouillage d’écran</string>
|
||||
<string name="lock_database_screen_off_summary">Verrouille la base de données lorsque l’écran est éteint</string>
|
||||
<string name="lock_database_screen_off_summary">Verrouille la base de données après quelques secondes une fois l’écran éteint</string>
|
||||
<string name="advanced_unlock">Déverrouillage avancé</string>
|
||||
<string name="biometric_unlock_enable_title">Déverrouillage biométrique</string>
|
||||
<string name="biometric_unlock_enable_summary">Permet de numériser votre empreinte biométrique pour ouvrir la base de données</string>
|
||||
@@ -487,7 +487,7 @@
|
||||
<string name="database_data_remove_unlinked_attachments_title">Supprimer les données non-liées</string>
|
||||
<string name="database_data_remove_unlinked_attachments_summary">Supprimer les pièces jointes contenues dans la base de données mais non-liées à une entrée</string>
|
||||
<string name="data">Données</string>
|
||||
<string name="show_uuid_summary">Affiche l’UUID lié à une entrée</string>
|
||||
<string name="show_uuid_summary">Affiche l’UUID lié à une entrée ou un groupe</string>
|
||||
<string name="show_uuid_title">Afficher l’UUID</string>
|
||||
<string name="autofill_read_only_save">L’enregistrement des données n’est pas autorisé pour une base de données ouverte en lecture seule.</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Demande à enregistrer des données quand un formulaire est validé</string>
|
||||
@@ -575,12 +575,12 @@
|
||||
<string name="error_start_database_action">Une erreur s\'est produite lors de l\'exécution d\'une action sur la base de données.</string>
|
||||
<string name="error_move_group_here">Vous ne pouvez pas déplacer un groupe ici.</string>
|
||||
<string name="error_word_reserved">Ce mot est réservé et ne peut pas être utilisé.</string>
|
||||
<string name="templates">Modèles</string>
|
||||
<string name="templates_group_uuid_title">Groupe de modèles</string>
|
||||
<string name="templates">Gabarits</string>
|
||||
<string name="templates_group_uuid_title">Groupe de gabarits</string>
|
||||
<string name="templates_group_enable_summary">Utiliser les modèles dynamiques pour remplir les champs d\'une entrée</string>
|
||||
<string name="templates_group_enable_title">Utilisation des modèles</string>
|
||||
<string name="templates_group_enable_title">Utilisation des gabarits</string>
|
||||
<string name="version">Version</string>
|
||||
<string name="template">Modèle</string>
|
||||
<string name="template">Gabarit</string>
|
||||
<string name="standard">Standard</string>
|
||||
<string name="membership">Adhésion</string>
|
||||
<string name="international_bank_account_number">IBAN</string>
|
||||
@@ -602,6 +602,11 @@
|
||||
<string name="name">Nom</string>
|
||||
<string name="id_card">Carte d\'identité</string>
|
||||
<string name="debit_credit_card">Carte de crédit</string>
|
||||
<string name="template_group_name">Modèles</string>
|
||||
<string name="template_group_name">Gabarits</string>
|
||||
<string name="secure_note">Note sécurisée</string>
|
||||
<string name="show_otp_token_summary">Affiche les jetons OTP dans la liste des entrées</string>
|
||||
<string name="show_otp_token_title">Afficher le jeton OTP</string>
|
||||
<string name="menu_external_icon">Icône externe</string>
|
||||
<string name="autofill_manual_selection_summary">Afficher l\'option permettant à l\'utilisateur de sélectionner l\'entrée de la base de données</string>
|
||||
<string name="autofill_manual_selection_title">Sélection manuelle</string>
|
||||
</resources>
|
||||
@@ -188,7 +188,7 @@
|
||||
<string name="clipboard">Međuspremnik</string>
|
||||
<string name="clipboard_notifications_title">Obavijesti međuspremnika</string>
|
||||
<string name="clipboard_warning">Ako automatsko brisanje međuspremnika ne uspije, izbriši njegovu povijest ručno.</string>
|
||||
<string name="lock_database_screen_off_summary">Zaključaj bazu podataka kada je ekran ugašen</string>
|
||||
<string name="lock_database_screen_off_summary">Zaključaj bazu podataka nakon par sekundi kad se ekran ugasi</string>
|
||||
<string name="lock_database_back_root_title">Pritisni \'Natrag\' za zaključavanje</string>
|
||||
<string name="advanced_unlock">Napredno otključavanje</string>
|
||||
<string name="advanced_unlock_explanation_summary">Koristi napredno otključavanje za jednostavnije otvaranje baze podataka</string>
|
||||
@@ -473,7 +473,7 @@
|
||||
<string name="notification">Obavijest</string>
|
||||
<string name="error_registration_read_only">Nije dopušteno spremati novi element u zaštićenoj bazi podataka</string>
|
||||
<string name="autofill_read_only_save">Spremanje podataka nije dopušteno za bazu podataka koja je otvorena u zaštićenom stanju.</string>
|
||||
<string name="show_uuid_summary">Prikazuje UUID povezan s unosom</string>
|
||||
<string name="show_uuid_summary">Prikazuje UUID povezan s unosom ili grupom</string>
|
||||
<string name="show_uuid_title">Prikaži UUID</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Zatraži spremanje podataka kad se obrazac provjeri</string>
|
||||
<string name="autofill_ask_to_save_data_title">Zatraži spremanje podataka</string>
|
||||
@@ -577,7 +577,7 @@
|
||||
<string name="cryptocurrency">Novčanik za kriptovalute</string>
|
||||
<string name="type">Vrsta</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="wireless">Wifi</string>
|
||||
<string name="wireless">Wi-Fi</string>
|
||||
<string name="email_address">E-mail adresa</string>
|
||||
<string name="email">E-mail</string>
|
||||
<string name="date_of_issue">Datum izdavanja</string>
|
||||
@@ -590,4 +590,11 @@
|
||||
<string name="holder">Vlasnik</string>
|
||||
<string name="debit_credit_card">Debitna / kreditna kartica</string>
|
||||
<string name="template_group_name">Predlošci</string>
|
||||
<string name="autofill_manual_selection_summary">Opcija prikaza koja omogućuje korisniku biranje unosa baze podataka</string>
|
||||
<string name="show_otp_token_summary">Prikazuje OTP tokene u popisu unosa</string>
|
||||
<string name="show_otp_token_title">Prikaži OTP token</string>
|
||||
<string name="autofill_manual_selection_title">Ručni odabir</string>
|
||||
<string name="autofill_select_entry">Odaberi unos …</string>
|
||||
<string name="menu_external_icon">Vanjska ikona</string>
|
||||
<string name="seed">Tajna fraza</string>
|
||||
</resources>
|
||||
@@ -24,12 +24,12 @@
|
||||
<string name="add_entry">Bejegyzés hozzáadása</string>
|
||||
<string name="add_group">Csoport hozzáadása</string>
|
||||
<string name="encryption_algorithm">Titkosítási algoritmus</string>
|
||||
<string name="app_timeout">Alkalmazás időkorlátja</string>
|
||||
<string name="app_timeout">Időtúllépés</string>
|
||||
<string name="app_timeout_summary">Tétlenség az adatbázis feloldása előtt</string>
|
||||
<string name="application">Alkalmazás</string>
|
||||
<string name="menu_app_settings">Alkalmazásbeállítások</string>
|
||||
<string name="brackets">Zárójelek</string>
|
||||
<string name="file_manager_install_description">Egy fájlkezelő, amely fogadja az ACTION_CREATE_DOCUMENT és ACTION_OPEN_DOCUMENT Intenteket, melyek az adatbázisfájlok létrehozásához, megnyitásához és mentéséhez szükségesek.</string>
|
||||
<string name="file_manager_install_description">Az adatbázisfájlok létrehozásához, megnyitásához és mentéséhez szükség van egy fájlkezelőre, amely képes fogadni az ACTION_CREATE_DOCUMENT és ACTION_OPEN_DOCUMENT Intenteket.</string>
|
||||
<string name="clipboard_cleared">Vágólap törölve</string>
|
||||
<string name="clipboard_error_title">Vágólap hiba</string>
|
||||
<string name="clipboard_error">Egyes eszközök nem engedik, hogy az alkalmazások használják a vágólapot.</string>
|
||||
@@ -401,7 +401,7 @@
|
||||
<string name="error_otp_period">Az időtartamnak %1$d és %2$d másodperc között kell lennie.</string>
|
||||
<string name="error_otp_counter">A számlálónak %1$d és %2$d között kell lennie.</string>
|
||||
<string name="error_otp_secret_key">A titkos kulcsnak Base32 formátumban kell lennie.</string>
|
||||
<string name="error_copy_group_here">Csoport ide nem másolható.</string>
|
||||
<string name="error_copy_group_here">Ide nem másolhat csoportot.</string>
|
||||
<string name="error_disallow_no_credentials">Legalább egy hitelesíti módot be kell állítani.</string>
|
||||
<string name="error_invalid_OTP">Érvénytelen OTP titok.</string>
|
||||
<string name="entry_otp">OTP</string>
|
||||
@@ -470,4 +470,51 @@
|
||||
<string name="error_string_type">A szöveg nem egyezik a kért elemmel.</string>
|
||||
<string name="content_description_credentials_information">Hitelesítő adatok információi</string>
|
||||
<string name="content_description_add_item">Elem hozzáadása</string>
|
||||
<string name="export_app_properties_summary">Fájl létrehozása az alkalmazástulajdonságok exportálásához</string>
|
||||
<string name="export_app_properties_title">Alkalmazástulajdonságok exportálása</string>
|
||||
<string name="import_app_properties_summary">Válasszon fájlt az alkalmazástulajdonságok importálásához</string>
|
||||
<string name="import_app_properties_title">Alkalmazástulajdonságok importálása</string>
|
||||
<string name="menu_external_icon">Külső ikon</string>
|
||||
<string name="menu_keystore_remove_key">Speciális feloldási kulcs törlése</string>
|
||||
<string name="menu_reload_database">Adatbázis újratöltése</string>
|
||||
<string name="error_start_database_action">Hiba történt az adatbázison végzett művelet során.</string>
|
||||
<string name="error_remove_file">Hiba történt a fájladatok eltávolítása során.</string>
|
||||
<string name="error_duplicate_file">A fájladatok már léteznek.</string>
|
||||
<string name="error_file_to_big">A feltöltendő fájl túl nagy.</string>
|
||||
<string name="error_upload_file">Hiba történt a fájladatok feltöltése során.</string>
|
||||
<string name="error_rebuild_list">A lista újbóli összeállítása sikertelen.</string>
|
||||
<string name="error_database_uri_null">Az adatbázis URI nem kérhető le.</string>
|
||||
<string name="error_field_name_already_exists">A mezőnév már létezik.</string>
|
||||
<string name="error_otp_type">A meglévő OTP típus nem ismert ebben a formában, a kiértékelése nem biztos, hogy helyes tokent fog előállítani.</string>
|
||||
<string name="error_word_reserved">Ez egy foglalt szó, és nem használható.</string>
|
||||
<string name="version">Verzió</string>
|
||||
<string name="template">Sablon</string>
|
||||
<string name="standard">Szabványos</string>
|
||||
<string name="membership">Tagság</string>
|
||||
<string name="secure_note">Biztonságos jegyzet</string>
|
||||
<string name="debit_credit_card">Bank- / hitelkártya</string>
|
||||
<string name="seed">Kezdőérték</string>
|
||||
<string name="international_bank_account_number">IBAN</string>
|
||||
<string name="bank_identifier_code">SWIFT / BIC</string>
|
||||
<string name="bank_name">Bank neve</string>
|
||||
<string name="bank">Bank</string>
|
||||
<string name="account">Fiók</string>
|
||||
<string name="private_key">Privát kulcs</string>
|
||||
<string name="public_key">Nyilvános kulcs</string>
|
||||
<string name="token">Token</string>
|
||||
<string name="cryptocurrency">Kriptopénztárca</string>
|
||||
<string name="type">Típus</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="email_address">E-mail-cím</string>
|
||||
<string name="email">E-mail</string>
|
||||
<string name="date_of_issue">Kiállítás ideje</string>
|
||||
<string name="place_of_issue">Kiállítás helye</string>
|
||||
<string name="name">Név</string>
|
||||
<string name="id_card">Személyigazolvány</string>
|
||||
<string name="personal_identification_number">PIN-kód</string>
|
||||
<string name="card_verification_value">Ellenőrzőszám</string>
|
||||
<string name="number">Szám</string>
|
||||
<string name="holder">Tulajdonos</string>
|
||||
<string name="template_group_name">Sablonok</string>
|
||||
<string name="content_description_otp_information">Egyszer használatos jelszó információ</string>
|
||||
</resources>
|
||||
@@ -420,14 +420,14 @@
|
||||
<string name="error_start_database_action">Timbul galat ketika melaksanakan sebuah aksi di basisdata.</string>
|
||||
<string name="error_move_group_here">Anda tidak bisa memindahkan sebuah grup ke sini.</string>
|
||||
<string name="device_credential_unlock_enable_title">Membuka kredensial perangkat</string>
|
||||
<string name="biometric_unlock_enable_summary">Memperbolehkan pengguna memindai biometrik pengguna untuk membuka database”</string>
|
||||
<string name="biometric_unlock_enable_summary">Memperbolehkan Anda memindai biometrik Anda untuk membuka basis data</string>
|
||||
<string name="biometric_unlock_enable_title">Membuka kunci biometrik</string>
|
||||
<string name="advanced_unlock_explanation_summary">Gunakan buka kunci lanjutan untuk membuka database dengan lebih mudah</string>
|
||||
<string name="no_credentials_stored">Basis data ini belum menyimpan kredensial.</string>
|
||||
<string name="advanced_unlock_not_recognized">Tidak dapat mengenali cetakan buka kunci lanjutan</string>
|
||||
<string name="advanced_unlock_invalid_key">Tidak dapat membaca kunci pembuka lanjutan. Harap hapus dan ulangi prosedur pengenalan buka kunci.</string>
|
||||
<string name="advanced_unlock_prompt_extract_credential_message">Ekstrak kredensial basis data dengan membuka data lanjutan</string>
|
||||
<string name="error_word_reserved">Kata ini telah dipakai dan tidak bisa digunakan</string>
|
||||
<string name="advanced_unlock_prompt_extract_credential_message">Ekstrak kredensial basis data dengan pembuka kunci data lanjutan</string>
|
||||
<string name="error_word_reserved">Kata ini telah dipakai dan tidak bisa digunakan.</string>
|
||||
<string name="credential_before_click_advanced_unlock_button">Ketik kata sandi, lalu klik tombol ini.</string>
|
||||
<string name="autofill_service_name">Isi formulir KeePassDX otomatis</string>
|
||||
<string name="autofill_preference_title">Pengaturan isi otomatis</string>
|
||||
@@ -440,5 +440,19 @@
|
||||
<string name="biometric">Biometrik</string>
|
||||
<string name="menu_appearance_settings">Tampilan</string>
|
||||
<string name="database_history">Riwayat</string>
|
||||
<string name="encrypted_value_stored">Enkripsi password telah disimpan.</string>
|
||||
<string name="encrypted_value_stored">Enkripsi kata sandi disimpan</string>
|
||||
<string name="international_bank_account_number">NRBI (IBAN)</string>
|
||||
<string name="bank_name">Nama bank</string>
|
||||
<string name="name">Nama</string>
|
||||
<string name="debit_credit_card">Kartu Debit/Kredit</string>
|
||||
<string name="type">Tipe</string>
|
||||
<string name="version">Versi</string>
|
||||
<string name="standard">Standar</string>
|
||||
<string name="bank">Bank</string>
|
||||
<string name="account">Akun</string>
|
||||
<string name="cryptocurrency">Dompet kripto</string>
|
||||
<string name="number">Nomor</string>
|
||||
<string name="public_key">Kunci publik</string>
|
||||
<string name="private_key">Kunci pribadi</string>
|
||||
<string name="membership">Keanggotaan</string>
|
||||
</resources>
|
||||
@@ -195,7 +195,7 @@
|
||||
<string name="clipboard_warning">Se l\'eliminazione automatica degli appunti fallisce, cancellali manualmente.</string>
|
||||
<string name="lock">Blocca</string>
|
||||
<string name="lock_database_screen_off_title">Blocco schermo</string>
|
||||
<string name="lock_database_screen_off_summary">Blocca il database quando lo schermo è spento</string>
|
||||
<string name="lock_database_screen_off_summary">Blocca il database dopo alcuni secondi quando lo schermo è spento</string>
|
||||
<string name="advanced_unlock">Impronta digitale</string>
|
||||
<string name="biometric_unlock_enable_title">Scansione di impronte</string>
|
||||
<string name="biometric_unlock_enable_summary">Consente la scansione biometrica per aprire il database</string>
|
||||
@@ -289,7 +289,7 @@
|
||||
<string name="list_entries_show_username_title">Mostra nomi utente</string>
|
||||
<string name="list_entries_show_username_summary">Mostra i nomi utente negli elenchi</string>
|
||||
<string name="clipboard">Appunti</string>
|
||||
<string name="build_label">Costruzione %1$s</string>
|
||||
<string name="build_label">Build %1$s</string>
|
||||
<string name="keyboard_name">Magitastiera</string>
|
||||
<string name="keyboard_label">Magitastiera (KeePassDX)</string>
|
||||
<string name="keyboard_setting_label">Impostazioni Magitastiera</string>
|
||||
@@ -346,7 +346,7 @@
|
||||
<string name="menu_advanced_unlock_settings">Sblocco avanzato</string>
|
||||
<string name="entry_history">Cronologia</string>
|
||||
<string name="entry_setup_otp">Imposta password usa e getta</string>
|
||||
<string name="otp_type">Tipo di password OTP</string>
|
||||
<string name="otp_type">Tipo di OTP</string>
|
||||
<string name="otp_secret">Segreto</string>
|
||||
<string name="otp_period">Periodo (secondi)</string>
|
||||
<string name="otp_counter">Contatore</string>
|
||||
@@ -374,7 +374,7 @@
|
||||
<string name="auto_focus_search_title">Ricerca rapida</string>
|
||||
<string name="menu_delete_entry_history">Cancella cronologia</string>
|
||||
<string name="menu_restore_entry_history">Ripristina cronologia</string>
|
||||
<string name="html_about_contribution">Per poter <strong>mantenere la nostra libertà</strong>, <strong>risolvere bug</strong>, <strong>aggiungere funzionalità</strong> ed <strong>essere sempre attivi</strong>, facciamo affidamento sul tuo <strong>contributo</strong>.</string>
|
||||
<string name="html_about_contribution">Per poter <strong>mantenere la nostra libertà</strong>, <strong>correggere errori</strong>, <strong>aggiungere funzionalità</strong> ed <strong>essere sempre attivi</strong>, facciamo affidamento sul tuo <strong>contributo</strong>.</string>
|
||||
<string name="contact">Contatto</string>
|
||||
<string name="keystore_not_accessible">Il keystore non è inizializzato correttamente.</string>
|
||||
<string name="menu_master_key_settings">Impostazioni della chiave principale</string>
|
||||
@@ -476,7 +476,7 @@
|
||||
\n
|
||||
\nIl tuo database può diventare molto grande e ridurre le prestazioni con questo caricamento.</string>
|
||||
<string name="content_description_credentials_information">Info credenziali</string>
|
||||
<string name="show_uuid_summary">Visualizza l\'UUID collegato a una voce</string>
|
||||
<string name="show_uuid_summary">Visualizza l\'UUID collegato a una voce o a un gruppo</string>
|
||||
<string name="show_uuid_title">Mostra UUID</string>
|
||||
<string name="autofill_read_only_save">Il salvataggio dei dati non è consentito per un database aperto in sola lettura.</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Chiedi di salvare i dati quando un modulo viene convalidato</string>
|
||||
@@ -586,7 +586,7 @@
|
||||
<string name="cryptocurrency">Portafoglio di criptovaluta</string>
|
||||
<string name="type">Tipo</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="wireless">Wifi</string>
|
||||
<string name="wireless">Wi-Fi</string>
|
||||
<string name="email_address">Indirizzo email</string>
|
||||
<string name="email">Email</string>
|
||||
<string name="date_of_issue">Data di emissione</string>
|
||||
@@ -599,4 +599,10 @@
|
||||
<string name="holder">Titolare</string>
|
||||
<string name="debit_credit_card">Carta di debito / credito</string>
|
||||
<string name="template_group_name">Modelli</string>
|
||||
<string name="menu_external_icon">Icona esterna</string>
|
||||
<string name="show_otp_token_summary">Mostra i token OTP nella lista delle voci</string>
|
||||
<string name="show_otp_token_title">Mostra token OTP</string>
|
||||
<string name="autofill_manual_selection_summary">Mostra l\'opzione che permette all\'utente di scegliere la voce nel database</string>
|
||||
<string name="autofill_manual_selection_title">Selezione manuale</string>
|
||||
<string name="autofill_select_entry">Seleziona voce…</string>
|
||||
</resources>
|
||||
@@ -78,7 +78,7 @@
|
||||
<string name="html_about_contribution"><strong>自由を維持し</strong>、<strong>バグを修正し</strong>、<strong>機能を追加し</strong>、そして<strong>活発に開発し続ける</strong>ために、私たちはあなたの<strong>貢献</strong>に期待しています。</string>
|
||||
<string name="entry_accessed">最終アクセス</string>
|
||||
<string name="entry_cancel">キャンセル</string>
|
||||
<string name="entry_notes">備考</string>
|
||||
<string name="entry_notes">メモ</string>
|
||||
<string name="entry_confpassword">パスワードを確認</string>
|
||||
<string name="entry_created">作成日時</string>
|
||||
<string name="entry_expires">有効期限</string>
|
||||
@@ -120,9 +120,9 @@
|
||||
<string name="error_label_exists">このラベルはすでに存在します。</string>
|
||||
<string name="error_wrong_length">[長さ] フィールドには正の整数を入力してください。</string>
|
||||
<string name="error_autofill_enable_service">自動入力サービスを有効にできませんでした。</string>
|
||||
<string name="error_move_entry_here">ここではエントリーを移動することはできません。</string>
|
||||
<string name="error_copy_entry_here">ここではエントリーをコピーすることはできません。</string>
|
||||
<string name="error_copy_group_here">ここではグループをコピーすることはできません。</string>
|
||||
<string name="error_move_entry_here">エントリーをここに移動できません。</string>
|
||||
<string name="error_copy_entry_here">エントリーをここにコピーできません。</string>
|
||||
<string name="error_copy_group_here">グループをここにコピーできません。</string>
|
||||
<string name="error_create_database">データベース ファイルを作成できません。</string>
|
||||
<string name="error_create_database_file">このパスワードとキーファイルではデータベースを作成できません。</string>
|
||||
<string name="error_save_database">データベースを保存できませんでした。</string>
|
||||
@@ -180,7 +180,7 @@
|
||||
<string name="menu_cancel">キャンセル</string>
|
||||
<string name="menu_hide_password">パスワードを非表示にする</string>
|
||||
<string name="menu_lock">データベースをロック</string>
|
||||
<string name="menu_save_database">データベースを保存</string>
|
||||
<string name="menu_save_database">保存する</string>
|
||||
<string name="menu_open">開く</string>
|
||||
<string name="menu_search">検索</string>
|
||||
<string name="menu_showpass">パスワードを表示</string>
|
||||
@@ -223,7 +223,7 @@
|
||||
<string name="encryption_explanation">すべてのデータで使用するデータベース暗号化アルゴリズムです。</string>
|
||||
<string name="kdf_explanation">暗号化アルゴリズム用の鍵を生成するために、マスターキーはランダムなソルト付き鍵導出関数を使用して変換されます。</string>
|
||||
<string name="rounds">変換ラウンド</string>
|
||||
<string name="rounds_explanation">変換ラウンドを増やすことでブルート フォース攻撃に対する保護が強化されますが、読み込みと保存が本当に遅くなる可能性があります。</string>
|
||||
<string name="rounds_explanation">変換ラウンドを増やすことでブルートフォース攻撃に対する保護が強化されますが、読み込みと保存がとても遅くなる可能性があります。</string>
|
||||
<string name="memory_usage">メモリ使用量</string>
|
||||
<string name="memory_usage_explanation">鍵導出関数が使用するメモリの量です。</string>
|
||||
<string name="parallelism">並列処理</string>
|
||||
@@ -241,7 +241,7 @@
|
||||
<string name="sort_db">並べ替えなし</string>
|
||||
<string name="sort_title">タイトル</string>
|
||||
<string name="sort_username">ユーザー名</string>
|
||||
<string name="sort_creation_time">作成日</string>
|
||||
<string name="sort_creation_time">作成日時</string>
|
||||
<string name="sort_last_modify_time">変更日時</string>
|
||||
<string name="sort_last_access_time">最終アクセス</string>
|
||||
<string name="special">特殊文字</string>
|
||||
@@ -294,7 +294,7 @@
|
||||
<string name="clipboard_warning">クリップボードの自動削除に失敗した場合は、手動でその履歴を削除してください。</string>
|
||||
<string name="lock">ロック</string>
|
||||
<string name="lock_database_screen_off_title">画面ロック</string>
|
||||
<string name="lock_database_screen_off_summary">画面がオフのとき、データベースをロックします</string>
|
||||
<string name="lock_database_screen_off_summary">画面がオフになった数秒後に、データベースをロックします</string>
|
||||
<string name="lock_database_back_root_title">[戻る] を押してロック</string>
|
||||
<string name="lock_database_back_root_summary">ユーザーがルート画面上で戻るボタンをタップしたとき、データベースをロックします</string>
|
||||
<string name="lock_database_show_button_title">ロックボタンを表示</string>
|
||||
@@ -362,13 +362,13 @@
|
||||
<string name="keyboard_setting_label">Magikeyboard の設定</string>
|
||||
<string name="keyboard_entry_category">エントリー</string>
|
||||
<string name="keyboard_selection_entry_title">エントリーの選択</string>
|
||||
<string name="keyboard_selection_entry_summary">エントリーを開いているとき、Magikeyboard に入力フィールドを表示します</string>
|
||||
<string name="keyboard_selection_entry_summary">KeePassDX のエントリーを開いているとき、Magikeyboard にそのエントリーを格納します</string>
|
||||
<string name="keyboard_notification_entry_title">通知情報</string>
|
||||
<string name="keyboard_notification_entry_summary">エントリーが利用可能なとき、通知を表示します</string>
|
||||
<string name="keyboard_search_share_title">共有情報の検索</string>
|
||||
<string name="keyboard_search_share_summary">共有情報を自動的に検索して、結果をキーボードに格納します</string>
|
||||
<string name="keyboard_search_share_summary">URL を KeePassDX に共有するとそのドメインを使ってエントリーを検索します</string>
|
||||
<string name="keyboard_save_search_info_title">共有情報の保存</string>
|
||||
<string name="keyboard_save_search_info_summary">手動でエントリーを選択したとき、共有情報の保存を試みます</string>
|
||||
<string name="keyboard_save_search_info_summary">KeePassDX に URL を共有して、エントリーが選択されたとき、さらなる使用のためそのエントリーを記憶しておきます</string>
|
||||
<string name="keyboard_notification_entry_clear_close_title">データベースを閉じて消去</string>
|
||||
<string name="keyboard_notification_entry_clear_close_summary">通知を閉じるとき、データベースも閉じます</string>
|
||||
<string name="keyboard_entry_timeout_title">タイムアウト</string>
|
||||
@@ -489,7 +489,7 @@
|
||||
<string name="hide_expired_entries_title">有効期限切れのエントリーを非表示にする</string>
|
||||
<string name="hide_expired_entries_summary">有効期限切れのエントリーは非表示になります</string>
|
||||
<string name="show_uuid_title">UUID を表示</string>
|
||||
<string name="show_uuid_summary">エントリーにリンクされた UUID を表示します</string>
|
||||
<string name="show_uuid_summary">エントリーやグループにリンクされた UUID を表示します</string>
|
||||
<string name="autofill_read_only_save">データの保存は読み取り専用として開かれたデータベースでは許可されていません。</string>
|
||||
<string name="save_mode">保存モード</string>
|
||||
<string name="search_mode">検索モード</string>
|
||||
@@ -531,7 +531,7 @@
|
||||
<string name="warning_database_revoked">ファイルへのアクセス権がファイル マネージャーによって取り消されました。データベースを閉じて、ファイルの場所から再度開いてください。</string>
|
||||
<string name="warning_database_info_changed_options">データベースを保存して外部の変更を上書きするか、再度読み込んで最新の変更を反映させてください。</string>
|
||||
<string name="warning_database_info_changed">データベース ファイルに含まれる情報は、アプリの外部で変更されています。</string>
|
||||
<string name="menu_reload_database">データベースを再度読み込む</string>
|
||||
<string name="menu_reload_database">再度読み込む</string>
|
||||
<string name="error_rebuild_list">リストを正しく再構築できません。</string>
|
||||
<string name="unit_gibibyte">GiB</string>
|
||||
<string name="unit_mebibyte">MiB</string>
|
||||
@@ -561,13 +561,13 @@
|
||||
<string name="error_start_database_action">データベースに対するアクションの実行中にエラーが発生しました。</string>
|
||||
<string name="error_word_reserved">この単語は予約語のため使用できません。</string>
|
||||
<string name="error_move_group_here">グループをここに移動できません。</string>
|
||||
<string name="templates_group_enable_title">テンプレートの使用方法</string>
|
||||
<string name="templates_group_enable_summary">エントリのフィールドの記入にダイナミックテンプレートを用います</string>
|
||||
<string name="templates_group_enable_title">テンプレートの使用</string>
|
||||
<string name="templates_group_enable_summary">エントリーのフィールドへの入力に動的テンプレートを使用します</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="templates">Templates</string>
|
||||
<string name="templates">テンプレート</string>
|
||||
<string name="secure_note">セキュアメモ</string>
|
||||
<string name="bank_identifier_code">SWIFTコード</string>
|
||||
<string name="international_bank_account_number"></string>
|
||||
<string name="bank_identifier_code">SWIFT / BIC</string>
|
||||
<string name="international_bank_account_number">IBAN</string>
|
||||
<string name="bank_name">銀行名</string>
|
||||
<string name="bank">銀行</string>
|
||||
<string name="account">口座</string>
|
||||
@@ -581,11 +581,23 @@
|
||||
<string name="date_of_issue">発行日</string>
|
||||
<string name="place_of_issue">発行地</string>
|
||||
<string name="name">名前</string>
|
||||
<string name="id_card">IDカード</string>
|
||||
<string name="id_card">ID カード</string>
|
||||
<string name="personal_identification_number">PIN</string>
|
||||
<string name="card_verification_value">CVV</string>
|
||||
<string name="number">カード番号</string>
|
||||
<string name="holder">所有者</string>
|
||||
<string name="template_group_name">Templates</string>
|
||||
<string name="debit_credit_card">クレジットカード/デビットカード</string>
|
||||
<string name="number">番号</string>
|
||||
<string name="holder">名義人</string>
|
||||
<string name="template_group_name">テンプレート</string>
|
||||
<string name="debit_credit_card">デビット / クレジットカード</string>
|
||||
<string name="show_otp_token_summary">エントリーの一覧に OTP トークンを表示します</string>
|
||||
<string name="show_otp_token_title">OTP トークンを表示</string>
|
||||
<string name="version">バージョン</string>
|
||||
<string name="standard">標準</string>
|
||||
<string name="membership">メンバーシップ</string>
|
||||
<string name="type">種類</string>
|
||||
<string name="autofill_select_entry">エントリーを選択する…</string>
|
||||
<string name="autofill_manual_selection_title">手動選択</string>
|
||||
<string name="autofill_manual_selection_summary">ユーザーがデータベースのエントリーを選択できるようにオプションを表示します</string>
|
||||
<string name="templates_group_uuid_title">テンプレート グループ</string>
|
||||
<string name="menu_external_icon">外部アイコン</string>
|
||||
<string name="template">テンプレート</string>
|
||||
</resources>
|
||||
@@ -392,4 +392,23 @@
|
||||
<string name="content">ഉള്ളടക്കം</string>
|
||||
<string name="device_credential">ഉപകരണ ക്രെഡൻഷ്യൽ</string>
|
||||
<string name="error_field_name_already_exists">ഈ ഫീൽഡ് നാമം ഇതിനകം ഉണ്ട്.</string>
|
||||
<string name="version">പതിപ്പ്</string>
|
||||
<string name="membership">അംഗത്വം</string>
|
||||
<string name="secure_note">സുരക്ഷിത കുറിപ്പ്</string>
|
||||
<string name="bank_name">ബാങ്കിന്റെ പേര്</string>
|
||||
<string name="bank">ബാങ്ക്</string>
|
||||
<string name="account">അക്കൗണ്ട്</string>
|
||||
<string name="seed">സീഡ്</string>
|
||||
<string name="token">ടോക്കൺ</string>
|
||||
<string name="cryptocurrency">ക്രിപ്റ്റോകറൻസി വാലറ്റ്</string>
|
||||
<string name="type">തരം</string>
|
||||
<string name="ssid">എസ്എസ്ഐഡി</string>
|
||||
<string name="email_address">ഇമെയിൽ വിലാസം</string>
|
||||
<string name="email">ഇമെയിൽ</string>
|
||||
<string name="name">പേര്</string>
|
||||
<string name="id_card">ഐഡി കാർഡ്</string>
|
||||
<string name="personal_identification_number">പിൻ</string>
|
||||
<string name="card_verification_value">സിവിവി</string>
|
||||
<string name="number">നമ്പർ</string>
|
||||
<string name="debit_credit_card">ടെബിറ്റ്/ ക്രെഡിറ്റ് കാർഡ്</string>
|
||||
</resources>
|
||||
@@ -467,4 +467,36 @@
|
||||
<string name="autofill_preference_title">Autofyllings-innstillinger</string>
|
||||
<string name="warning_sure_remove_data">Fjern denne dataen uansett\?</string>
|
||||
<string name="warning_permanently_delete_nodes">Slett valgte noder for godt\?</string>
|
||||
<string name="templates_group_uuid_title">Malgruppe</string>
|
||||
<string name="advanced_unlock_prompt_store_credential_title">Avansert opplåsingsgjenkjennelse</string>
|
||||
<string name="warning_empty_recycle_bin">Slett alle noder fra papirkurven for godt\?</string>
|
||||
<string name="export_app_properties_title">Eksporter programegenskaper</string>
|
||||
<string name="import_app_properties_title">Importer programegenskaper</string>
|
||||
<string name="error_duplicate_file">Fildataen finnes allerede.</string>
|
||||
<string name="error_file_to_big">Filen du prøver å laste opp er for stor.</string>
|
||||
<string name="error_move_group_here">Du kan ikke flytte en gruppe hit.</string>
|
||||
<string name="version">Versjon</string>
|
||||
<string name="template">Mal</string>
|
||||
<string name="membership">Medlemskap</string>
|
||||
<string name="international_bank_account_number">IBAN</string>
|
||||
<string name="bank_name">Banknavn</string>
|
||||
<string name="bank">Bank</string>
|
||||
<string name="account">Konto</string>
|
||||
<string name="private_key">Privat nøkkel</string>
|
||||
<string name="public_key">Offentlig nøkkel</string>
|
||||
<string name="token">Symbol</string>
|
||||
<string name="type">Type</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="email_address">E-postadresse</string>
|
||||
<string name="email">E-post</string>
|
||||
<string name="date_of_issue">Utstedsdato</string>
|
||||
<string name="name">Navn</string>
|
||||
<string name="id_card">ID-kort</string>
|
||||
<string name="personal_identification_number">PIN</string>
|
||||
<string name="card_verification_value">CVV</string>
|
||||
<string name="number">Nummer</string>
|
||||
<string name="holder">Innehaver</string>
|
||||
<string name="content_description_otp_information">Éngangspassordsinfo</string>
|
||||
<string name="template_group_name">Maler</string>
|
||||
<string name="content_description_credentials_information">Identitetdetaljsinfo</string>
|
||||
</resources>
|
||||
@@ -20,12 +20,12 @@
|
||||
Dutch translation by Erik Devriendt, corrected by Erik Jan Meijer
|
||||
--><resources>
|
||||
<string name="feedback">Reacties</string>
|
||||
<string name="homepage">Website</string>
|
||||
<string name="homepage">Startpagina</string>
|
||||
<string name="about_description">Android-implementatie van KeePass-wachtwoordbeheer</string>
|
||||
<string name="accept">Accepteren</string>
|
||||
<string name="add_entry">Item toevoegen</string>
|
||||
<string name="add_group">Groep toevoegen</string>
|
||||
<string name="encryption_algorithm">Algoritme</string>
|
||||
<string name="encryption_algorithm">Versleutelingsalgoritme</string>
|
||||
<string name="app_timeout">Time-out</string>
|
||||
<string name="app_timeout_summary">Tijd tot vergrendeling bij inactiviteit</string>
|
||||
<string name="application">App</string>
|
||||
@@ -33,8 +33,8 @@
|
||||
<string name="brackets">Haakjes</string>
|
||||
<string name="file_manager_install_description">Bestandsbeheer dat de Intent-actie ACTION_CREATE_DOCUMENT en ACTION_OPEN_DOCUMENT accepteert, is nodig om databasebestanden aan te maken, te openen en op te slaan.</string>
|
||||
<string name="clipboard_cleared">Klembord gewist</string>
|
||||
<string name="clipboard_timeout">Klembordtime-out</string>
|
||||
<string name="clipboard_timeout_summary">Tijd van opslag op het klembord (voor zover ondersteund op dit apparaat)</string>
|
||||
<string name="clipboard_timeout">Time-out van het klembord</string>
|
||||
<string name="clipboard_timeout_summary">Tijd van opslag op het klembord (indien ondersteund op dit apparaat)</string>
|
||||
<string name="select_to_copy">Selecteer om %1$s naar klembord te kopiëren</string>
|
||||
<string name="retrieving_db_key">Databasesleutel ophalen…</string>
|
||||
<string name="database">Database</string>
|
||||
@@ -203,7 +203,7 @@
|
||||
<string name="clipboard_warning">Als automatisch wissen van het klembord mislukt, doe dit dan handmatig.</string>
|
||||
<string name="lock">Vergrendelen</string>
|
||||
<string name="lock_database_screen_off_title">Schermvergrendeling</string>
|
||||
<string name="lock_database_screen_off_summary">Database vergrendelen wanneer het scherm is uitgeschakeld</string>
|
||||
<string name="lock_database_screen_off_summary">Vergrendel de database een paar seconden nadat het scherm is uitgeschakeld</string>
|
||||
<string name="advanced_unlock">Geavanceerd ontgrendelen</string>
|
||||
<string name="biometric_unlock_enable_title">Ontgrendelen met biometrie</string>
|
||||
<string name="biometric_unlock_enable_summary">Gebruik biometrische herkenning om de database te openen</string>
|
||||
@@ -475,7 +475,7 @@
|
||||
<string name="data">Gegevens</string>
|
||||
<string name="database_data_remove_unlinked_attachments_title">Niet-gekoppelde gegevens verwijderen</string>
|
||||
<string name="database_data_remove_unlinked_attachments_summary">Verwijdert bijlagen die in de database staan, maar niet aan een item zijn gekoppeld</string>
|
||||
<string name="show_uuid_summary">Geeft de UUID weer die aan een item is gekoppeld</string>
|
||||
<string name="show_uuid_summary">Geeft de UUID weer die is gekoppeld aan een item of een groep</string>
|
||||
<string name="show_uuid_title">UUID tonen</string>
|
||||
<string name="autofill_read_only_save">Het opslaan van gegevens is niet toegestaan voor een database die is geopend als alleen-lezen.</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Vraag om gegevens op te slaan wanneer een formulier is gevalideerd</string>
|
||||
@@ -564,4 +564,43 @@
|
||||
<string name="error_start_database_action">Er is een fout opgetreden bij het uitvoeren van een actie op de database.</string>
|
||||
<string name="error_move_group_here">Je kunt hier geen groep verplaatsen.</string>
|
||||
<string name="error_word_reserved">Dit woord is gereserveerd en kan niet worden gebruikt.</string>
|
||||
<string name="id_card">Identiteitskaart</string>
|
||||
<string name="personal_identification_number">Pincode</string>
|
||||
<string name="holder">Kaarthouder</string>
|
||||
<string name="show_otp_token_summary">Geeft OTP-tokens weer in de lijst met items</string>
|
||||
<string name="show_otp_token_title">OTP-token weergeven</string>
|
||||
<string name="autofill_manual_selection_summary">Toon optie om de gebruiker database-invoer te laten selecteren</string>
|
||||
<string name="autofill_manual_selection_title">Handmatige selectie</string>
|
||||
<string name="templates">Sjablonen</string>
|
||||
<string name="templates_group_uuid_title">Sjabloongroep</string>
|
||||
<string name="templates_group_enable_summary">Gebruik dynamische sjablonen om de velden van een item in te vullen</string>
|
||||
<string name="templates_group_enable_title">Sjabloongebruik</string>
|
||||
<string name="autofill_select_entry">Selecteer invoer…</string>
|
||||
<string name="menu_external_icon">Extern pictogram</string>
|
||||
<string name="version">Versie</string>
|
||||
<string name="template">Sjabloon</string>
|
||||
<string name="standard">Standaard</string>
|
||||
<string name="membership">Lidmaatschap</string>
|
||||
<string name="secure_note">Veilige notitie</string>
|
||||
<string name="international_bank_account_number">IBAN</string>
|
||||
<string name="bank_identifier_code">SWIFT / BIC</string>
|
||||
<string name="bank_name">Banknaam</string>
|
||||
<string name="bank">Bank</string>
|
||||
<string name="account">Rekening</string>
|
||||
<string name="seed">Seed</string>
|
||||
<string name="private_key">Privésleutel</string>
|
||||
<string name="public_key">Publieke sleutel</string>
|
||||
<string name="token">Token</string>
|
||||
<string name="cryptocurrency">Portemonnee voor cryptovaluta</string>
|
||||
<string name="type">Type</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="email_address">E-mailadres</string>
|
||||
<string name="email">E-mail</string>
|
||||
<string name="date_of_issue">Datum van afgifte</string>
|
||||
<string name="place_of_issue">Plaats van afgifte</string>
|
||||
<string name="name">Naam</string>
|
||||
<string name="card_verification_value">CVV</string>
|
||||
<string name="number">Nummer</string>
|
||||
<string name="debit_credit_card">Betaalkaart</string>
|
||||
<string name="template_group_name">Sjablonen</string>
|
||||
</resources>
|
||||
@@ -199,7 +199,7 @@
|
||||
<string name="clipboard_warning">Jeśli automatyczne usuwanie schowka nie powiedzie się, ręcznie usuń jego historię.</string>
|
||||
<string name="lock">Blokada</string>
|
||||
<string name="lock_database_screen_off_title">Blokada ekranu</string>
|
||||
<string name="lock_database_screen_off_summary">Zablokuj bazę danych, gdy ekran jest wyłączony</string>
|
||||
<string name="lock_database_screen_off_summary">Zablokuj bazę danych po kilku sekundach od wyłączenia ekranu</string>
|
||||
<string name="advanced_unlock">Odcisk palca</string>
|
||||
<string name="biometric_unlock_enable_title">Skanowanie odcisków palców</string>
|
||||
<string name="biometric_unlock_enable_summary">Umożliwia zeskanowanie danych biometrycznych w celu otwarcia bazy danych</string>
|
||||
@@ -473,7 +473,7 @@
|
||||
<string name="warning_sure_remove_data">Czy mimo to usunąć te dane\?</string>
|
||||
<string name="warning_remove_unlinked_attachment">Usunięcie niepowiązanych danych może zmniejszyć rozmiar bazy danych, ale może również spowodować usunięcie danych używanych przez wtyczki KeePass.</string>
|
||||
<string name="content_description_credentials_information">Informacje o poświadczeniach</string>
|
||||
<string name="show_uuid_summary">Wyświetla identyfikator UUID powiązany z wpisem</string>
|
||||
<string name="show_uuid_summary">Wyświetla identyfikator UUID powiązany z wpisem lub grupą</string>
|
||||
<string name="show_uuid_title">Pokaż UUID</string>
|
||||
<string name="autofill_read_only_save">Zapisywanie danych nie jest dozwolone dla bazy danych otwartej jako tylko do odczytu.</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Poproś o zapisanie danych po zatwierdzeniu formularza</string>
|
||||
@@ -596,4 +596,10 @@
|
||||
<string name="holder">Posiadacz</string>
|
||||
<string name="debit_credit_card">Karta debetowa / kredytowa</string>
|
||||
<string name="template_group_name">Szablony</string>
|
||||
<string name="show_otp_token_summary">Wyświetla tokeny OTP na liście wpisów</string>
|
||||
<string name="show_otp_token_title">Pokaż token OTP</string>
|
||||
<string name="menu_external_icon">Ikona zewnętrzna</string>
|
||||
<string name="autofill_manual_selection_summary">Wyświetl opcję pozwalającą użytkownikowi wybrać wpis bazy danych</string>
|
||||
<string name="autofill_manual_selection_title">Wybór ręczny</string>
|
||||
<string name="autofill_select_entry">Wybierz wpis…</string>
|
||||
</resources>
|
||||
@@ -23,19 +23,19 @@
|
||||
<string name="accept">Aceitar</string>
|
||||
<string name="add_entry">Adicionar entrada</string>
|
||||
<string name="add_group">Adicionar grupo</string>
|
||||
<string name="encryption_algorithm">Algoritmo de Encriptação</string>
|
||||
<string name="app_timeout">Tempo limite para o aplicativo</string>
|
||||
<string name="app_timeout_summary">Inativo até que o aplicativo seja bloqueado</string>
|
||||
<string name="encryption_algorithm">Algoritmo de cifragem</string>
|
||||
<string name="app_timeout">Tempo de espera</string>
|
||||
<string name="app_timeout_summary">Inatividade até que o aplicativo seja bloqueado</string>
|
||||
<string name="application">Aplicativo</string>
|
||||
<string name="menu_app_settings">Configurações do aplicativo</string>
|
||||
<string name="brackets">Parênteses</string>
|
||||
<string name="file_manager_install_description">É necessário um gerenciador de arquivos que aceite as ações ACTION_CREATE_DOCUMENT e ACTION_OPEN_DOCUMENT para criar, abrir e salvar arquivos de banco de dados.</string>
|
||||
<string name="file_manager_install_description">Um gerenciador de arquivos que aceita a ação Intenção ACTION_CREATE_DOCUMENT e ACTION_OPEN_DOCUMENT é necessário para criar, abrir e salvar arquivos de banco de dados.</string>
|
||||
<string name="clipboard_cleared">Área de transferência limpa</string>
|
||||
<string name="clipboard_timeout">Tempo limite para o clipboard</string>
|
||||
<string name="clipboard_timeout_summary">Duração do armazenamento na área de transferência (se suportada pelo dispositivo)</string>
|
||||
<string name="select_to_copy">Copiar %1$s para o clipboard</string>
|
||||
<string name="clipboard_timeout">Tempo limite para a área de transferência</string>
|
||||
<string name="clipboard_timeout_summary">Duração do armazenamento na área de transferência (se suportado pelo seu dispositivo)</string>
|
||||
<string name="select_to_copy">Selecione para copiar %1$s para área de transferência</string>
|
||||
<string name="retrieving_db_key">Criando a chave do banco de dados…</string>
|
||||
<string name="database">Banco de Dados</string>
|
||||
<string name="database">Banco de dados</string>
|
||||
<string name="decrypting_db">Descriptografando conteúdo do banco de dados…</string>
|
||||
<string name="default_checkbox">Usar como banco de dados padrão</string>
|
||||
<string name="digits">Digitos</string>
|
||||
@@ -52,7 +52,7 @@
|
||||
<string name="entry_modified">Modificado</string>
|
||||
<string name="entry_password">Senha</string>
|
||||
<string name="save">Salvar</string>
|
||||
<string name="entry_title">Nome</string>
|
||||
<string name="entry_title">Titulo</string>
|
||||
<string name="entry_url">URL</string>
|
||||
<string name="entry_user_name">Nome de usuário</string>
|
||||
<string name="error_arc4">A cifra de fluxo Arcfour não é suportada.</string>
|
||||
@@ -62,23 +62,23 @@
|
||||
<string name="error_invalid_path">Certifique-se de que o caminho está correto.</string>
|
||||
<string name="error_no_name">Digite um nome.</string>
|
||||
<string name="error_nokeyfile">Selecione um arquivo-chave.</string>
|
||||
<string name="error_out_of_memory">Falta de memória para abrir todo o banco.</string>
|
||||
<string name="error_out_of_memory">Falta de memória para abrir todo o banco de dados.</string>
|
||||
<string name="error_pass_gen_type">Pelo menos um tipo de geração de senhas deve ser selecionado.</string>
|
||||
<string name="error_pass_match">As senhas não combinam.</string>
|
||||
<string name="error_rounds_too_large">\"Número de rodadas\" é muito grande. Modificado para 2147483648.</string>
|
||||
<string name="error_wrong_length">Digite um número inteiro positivo no campo \"Tamanho\".</string>
|
||||
<string name="file_browser">Localizador de arquivos</string>
|
||||
<string name="error_rounds_too_large">\"Rodadas de transformação\" é muito grande. Modificado para 2147483648.</string>
|
||||
<string name="error_wrong_length">Digite um número inteiro positivo no campo \"Comprimento\".</string>
|
||||
<string name="file_browser">Explorador de arquivos</string>
|
||||
<string name="generate_password">Gerar senha</string>
|
||||
<string name="hint_conf_pass">Confirmar senha</string>
|
||||
<string name="hint_generated_password">Senha gerada</string>
|
||||
<string name="hint_group_name">Nome do Grupo</string>
|
||||
<string name="hint_group_name">Nome do grupo</string>
|
||||
<string name="hint_keyfile">Arquivo-chave</string>
|
||||
<string name="hint_length">Tamanho</string>
|
||||
<string name="hint_length">Comprimento</string>
|
||||
<string name="password">Senha</string>
|
||||
<string name="hint_pass">Senha</string>
|
||||
<string name="invalid_credentials">Não foi possível ler credenciais.</string>
|
||||
<string name="invalid_db_sig">Não pôde reconhecer formato do banco de dados.</string>
|
||||
<string name="length">Tamanho</string>
|
||||
<string name="invalid_db_sig">Não pôde reconhecer formato da base de dados.</string>
|
||||
<string name="length">Comprimento</string>
|
||||
<string name="list_size_title">Tamanho da lista de grupos</string>
|
||||
<string name="list_size_summary">Tamanho do texto na lista de grupos</string>
|
||||
<string name="loading_database">Carregando banco de dados…</string>
|
||||
@@ -90,32 +90,32 @@
|
||||
<string name="settings">Configurações</string>
|
||||
<string name="menu_database_settings">Configurações do banco de dados</string>
|
||||
<string name="menu_delete">Deletar</string>
|
||||
<string name="menu_donate">Doaçoes</string>
|
||||
<string name="menu_donate">Doar</string>
|
||||
<string name="menu_edit">Editar</string>
|
||||
<string name="menu_hide_password">Esconder senha</string>
|
||||
<string name="menu_lock">Trancar base de dados</string>
|
||||
<string name="menu_lock">Bloquear base de dados</string>
|
||||
<string name="menu_open">Abrir</string>
|
||||
<string name="menu_search">Procurar</string>
|
||||
<string name="menu_search">Buscar</string>
|
||||
<string name="menu_showpass">Mostrar senha</string>
|
||||
<string name="menu_url">Ir para URL</string>
|
||||
<string name="minus">Menos</string>
|
||||
<string name="never">Nunca</string>
|
||||
<string name="no_results">Sem resultados na busca</string>
|
||||
<string name="no_url_handler">Instale um navegador para abrir esta URL.</string>
|
||||
<string name="omit_backup_search_title">Não procurar por entradas no backup ou na lixeira</string>
|
||||
<string name="omit_backup_search_title">Não buscar por entradas no backup ou na lixeira</string>
|
||||
<string name="omit_backup_search_summary">Omite os grupos \"Backup\" e \"Lixeira\" dos resultados da busca</string>
|
||||
<string name="progress_create">Criando novo banco de dados…</string>
|
||||
<string name="progress_title">Trabalhando…</string>
|
||||
<string name="content_description_remove_from_list">Remover</string>
|
||||
<string name="root">Raiz</string>
|
||||
<string name="rounds">Rodadas de criptografia</string>
|
||||
<string name="rounds_explanation">Rodadas adicionais de criptografia adicionam mais proteção contra ataques de força bruta, mas podem tornar o processo de carregar e salvar mais lentos.</string>
|
||||
<string name="rounds">Rodadas de transformação</string>
|
||||
<string name="rounds_explanation">Rodadas adicionais de cifragem adicionam mais proteção contra ataques de força bruta, mas podem tornar o processo de carregar e salvar mais lentos.</string>
|
||||
<string name="saving_database">Salvando banco de dados…</string>
|
||||
<string name="space">Spaço</string>
|
||||
<string name="space">Espaço</string>
|
||||
<string name="search_label">Busca</string>
|
||||
<string name="sort_db">Ordenação natural</string>
|
||||
<string name="special">Caracteres Especiais</string>
|
||||
<string name="search">Título/Descrição da entrada</string>
|
||||
<string name="special">Especial</string>
|
||||
<string name="search">Buscar</string>
|
||||
<string name="underline">Sublinhado</string>
|
||||
<string name="unsupported_db_version">Versão de banco de dados não suportada.</string>
|
||||
<string name="uppercase">Letras maiúsculas</string>
|
||||
@@ -128,36 +128,36 @@
|
||||
<item>Médio</item>
|
||||
<item>Grande</item>
|
||||
</string-array>
|
||||
<string name="encryption">Encriptação</string>
|
||||
<string name="encryption">Cifragem</string>
|
||||
<string name="key_derivation_function">Função de derivação de chave</string>
|
||||
<string name="extended_ASCII">ASCII Extendido</string>
|
||||
<string name="extended_ASCII">ASCII estendido</string>
|
||||
<string name="allow">Permitir</string>
|
||||
<string name="clipboard_error_title">Erro na área de transferência</string>
|
||||
<string name="clipboard_error">Alguns dispositivos não permitem que aplicativos usem a área de transferência.</string>
|
||||
<string name="clipboard_error_clear">Não foi possível limpar a área de transferência</string>
|
||||
<string name="entry_not_found">Não pôde encontrar dado de entrada.</string>
|
||||
<string name="entry_not_found">Não pôde encontrar dados de entrada.</string>
|
||||
<string name="error_string_key">Um nome do campo é necessário para cada string.</string>
|
||||
<string name="error_autofill_enable_service">Não pôde ser habilitado o serviço de preenchimento automático.</string>
|
||||
<string name="field_name">Nome do campo</string>
|
||||
<string name="field_value">Valor do campo</string>
|
||||
<string name="file_not_found_content">Arquivo não encontrado. Tente reabri-lo de seu buscador de arquivos.</string>
|
||||
<string name="file_not_found_content">Não pôde encontrar o arquivo. Tente reabri-lo de seu explorador de arquivos.</string>
|
||||
<string name="invalid_algorithm">Algoritmo errado.</string>
|
||||
<string name="keyfile_is_empty">O arquivo-chave está vazio.</string>
|
||||
<string name="copy_field">Cópia de %1$s</string>
|
||||
<string name="menu_form_filling_settings">Preenchimento de formulário</string>
|
||||
<string name="menu_copy">Cópia</string>
|
||||
<string name="menu_copy">Copiar</string>
|
||||
<string name="menu_move">Mover</string>
|
||||
<string name="menu_paste">Colar</string>
|
||||
<string name="menu_cancel">Cancelar</string>
|
||||
<string name="menu_file_selection_read_only">Somente leitura</string>
|
||||
<string name="menu_open_file_read_and_write">Gravação</string>
|
||||
<string name="menu_open_file_read_and_write">Modificável</string>
|
||||
<string name="protection">Proteção</string>
|
||||
<string name="read_only">Somente leitura</string>
|
||||
<string name="read_only_warning">KeePassDX precisa de permissões de escrita para poder mudar qualquer coisa no seu banco.</string>
|
||||
<string name="show_recent_files_title">Histórico de arquivos recentes</string>
|
||||
<string name="show_recent_files_summary">Lembrar nomes recentes de arquivos</string>
|
||||
<string name="encryption_explanation">Algoritmo de encriptação usado para todos os dados.</string>
|
||||
<string name="kdf_explanation">Para gerar a chave para o algoritmo de criptografia, a chave mestra é transformada usando uma função de derivação de chave com sal aleatoriamente.</string>
|
||||
<string name="show_recent_files_title">Exibir arquivos recentes</string>
|
||||
<string name="show_recent_files_summary">Exibir locais de bancos de dados recentes</string>
|
||||
<string name="encryption_explanation">Algoritmo de cifragem usado para todos os dados.</string>
|
||||
<string name="kdf_explanation">Para gerar uma chave para o algoritmo de cifragem, a chave mestra é transformada usando uma função de derivação de chave salgada aleatoriamente.</string>
|
||||
<string name="memory_usage">Uso de memória</string>
|
||||
<string name="memory_usage_explanation">Quantidade de memória a ser usada pela função de derivação de chave.</string>
|
||||
<string name="parallelism">Paralelismo</string>
|
||||
@@ -171,36 +171,36 @@
|
||||
<string name="sort_creation_time">Data de criação</string>
|
||||
<string name="sort_last_modify_time">Última modificação</string>
|
||||
<string name="sort_last_access_time">Último acesso</string>
|
||||
<string name="search_results">Resultados da pesquisa</string>
|
||||
<string name="search_results">Resultados da busca</string>
|
||||
<string name="warning">Aviso</string>
|
||||
<string name="warning_password_encoding">Evite caracteres fora do formato de codificação do arquivo do banco (todos os caracteres não reconhecidos são convertidos para a mesma letra).</string>
|
||||
<string name="warning_empty_password">Continuar sem proteção de desbloqueio de senha\?</string>
|
||||
<string name="warning_no_encryption_key">Continuar sem chave de criptografia\?</string>
|
||||
<string name="encrypted_value_stored">Senha encriptada armazenada</string>
|
||||
<string name="warning_no_encryption_key">Continuar sem chave de cifragem\?</string>
|
||||
<string name="encrypted_value_stored">Senha cifrada armazenada</string>
|
||||
<string name="no_credentials_stored">Ainda não há nenhuma senha armazenada nesse banco de dados.</string>
|
||||
<string name="database_history">Histórico</string>
|
||||
<string name="menu_appearance_settings">Aparência</string>
|
||||
<string name="general">Geral</string>
|
||||
<string name="autofill">Preenchimento automático</string>
|
||||
<string name="autofill_service_name">Preenchimento Automático KeePassDX</string>
|
||||
<string name="autofill_service_name">Preenchimento automático do KeePassDX</string>
|
||||
<string name="autofill_sign_in_prompt">Entre com o KeePassDX</string>
|
||||
<string name="set_autofill_service_title">Definir serviço padrão de preenchimento automático</string>
|
||||
<string name="autofill_explanation_summary">Habilite o serviço para rapidamente preencher formulários em outros aplicativos</string>
|
||||
<string name="password_size_title">Comprimento da senha gerada</string>
|
||||
<string name="password_size_summary">Define o tamanho padrão para senhas geradas</string>
|
||||
<string name="list_password_generator_options_title">Caracteres da senha</string>
|
||||
<string name="list_password_generator_options_summary">Definir os caracteres padrão do gerador de senha</string>
|
||||
<string name="list_password_generator_options_summary">Definir os caracteres padrão do gerador de senhas</string>
|
||||
<string name="clipboard_notifications_title">Notificações da área de transferência</string>
|
||||
<string name="clipboard_notifications_summary">Mostrar notificações da área de transferência para campos copiáveis quando estiver visualizando uma entrada</string>
|
||||
<string name="clipboard_warning">Se a limpeza da área de transferência falhar, limpe seu histórico manualmente.</string>
|
||||
<string name="lock">Bloquear</string>
|
||||
<string name="lock_database_screen_off_title">Bloqueio de tela</string>
|
||||
<string name="lock_database_screen_off_summary">Bloqueie o banco de dados quando a tela estiver desligada</string>
|
||||
<string name="advanced_unlock">Impressão Digital</string>
|
||||
<string name="biometric_unlock_enable_title">Escaneamento de impressão digital</string>
|
||||
<string name="lock_database_screen_off_summary">Bloqueie o banco de dados após alguns segundos quando a tela for desligada</string>
|
||||
<string name="advanced_unlock">Desbloqueio avançado</string>
|
||||
<string name="biometric_unlock_enable_title">Desbloqueio biométrico</string>
|
||||
<string name="biometric_unlock_enable_summary">Permite que você escaneie sua biometria para a abertura do banco de dados</string>
|
||||
<string name="biometric_delete_all_key_title">Apague chaves de encriptação</string>
|
||||
<string name="biometric_delete_all_key_summary">Apague todas as chaves de encriptação relacionadas ao reconhecimento de Impressões digitais</string>
|
||||
<string name="biometric_delete_all_key_title">Apague chaves de cifragem</string>
|
||||
<string name="biometric_delete_all_key_summary">Apagar todas as chaves de cifragem relacionadas ao reconhecimento de desbloqueio avançado</string>
|
||||
<string name="unavailable_feature_text">Não foi possível iniciar esse recurso.</string>
|
||||
<string name="unavailable_feature_version">O dispositivo está utilizando Android %1$s, mas precisa %2$s ou posterior.</string>
|
||||
<string name="unavailable_feature_hardware">Não foi possível encontrar o hardware correspondente.</string>
|
||||
@@ -210,16 +210,16 @@
|
||||
<string name="create_keepass_file">Criar novo banco</string>
|
||||
<string name="recycle_bin_title">Usar lixeira</string>
|
||||
<string name="recycle_bin_summary">Mover grupos e entradas para o grupo \"Lixeira\" antes de apagar</string>
|
||||
<string name="monospace_font_fields_enable_title">Fonte do Campo</string>
|
||||
<string name="monospace_font_fields_enable_title">Tipo de letra nos campos</string>
|
||||
<string name="monospace_font_fields_enable_summary">Muda a fonte usada nos campos para melhor visibilidade dos caracteres</string>
|
||||
<string name="allow_copy_password_title">Confiança da área de transferência</string>
|
||||
<string name="allow_copy_password_title">Confiança na área de transferência</string>
|
||||
<string name="allow_copy_password_summary">Permitir a cópia da senha e de campos protegidos para a área de transferência</string>
|
||||
<string name="allow_copy_password_warning">AVISO: A área de transferência é compartilhada por todos os aplicativos. Se dados sensíveis forem copiados, outros programas podem recuperá-los.</string>
|
||||
<string name="database_name_title">Nome do banco de dados</string>
|
||||
<string name="database_description_title">Descrição do banco de dados</string>
|
||||
<string name="database_version_title">Versão do banco de dados</string>
|
||||
<string name="text_appearance">Texto</string>
|
||||
<string name="application_appearance">Aplicativo</string>
|
||||
<string name="application_appearance">Interface</string>
|
||||
<string name="other">Outros</string>
|
||||
<string name="keyboard">Teclado</string>
|
||||
<string name="magic_keyboard_title">Magikeyboard</string>
|
||||
@@ -228,11 +228,11 @@
|
||||
<string name="allow_no_password_summary">Permitir tocar no botão \"Abrir\" se nenhuma credencial for selecionada</string>
|
||||
<string name="enable_read_only_title">Somente leitura</string>
|
||||
<string name="enable_read_only_summary">Por padrão, abrir seu banco de dados no modo somente leitura</string>
|
||||
<string name="enable_education_screens_title">Telas educacionais</string>
|
||||
<string name="enable_education_screens_summary">Destaque os elementos para aprender como o app funciona</string>
|
||||
<string name="enable_education_screens_title">Dicas educacionais</string>
|
||||
<string name="enable_education_screens_summary">Destaque os elementos para aprender como o aplicativo funciona</string>
|
||||
<string name="reset_education_screens_title">Reiniciar telas educacionais</string>
|
||||
<string name="reset_education_screens_summary">Exibir todos os itens educacionais novamente</string>
|
||||
<string name="reset_education_screens_text">Telas educacionais redefinidas</string>
|
||||
<string name="reset_education_screens_summary">Mostrar todas as informações educacionais novamente</string>
|
||||
<string name="reset_education_screens_text">Dicas educacionais redefinidas</string>
|
||||
<string name="education_create_database_title">Crie um arquivo de banco de dados</string>
|
||||
<string name="education_create_database_summary">Crie seu primeiro arquivo de gerenciamento de senhas.</string>
|
||||
<string name="education_select_database_title">Abra um banco de dados existente</string>
|
||||
@@ -246,7 +246,7 @@
|
||||
<string name="education_entry_edit_title">Modifique a entrada</string>
|
||||
<string name="education_entry_edit_summary">Edite a sua entrada com campos personalizados. Os conjuntos de dados podem ser referenciados entre campos de entradas diferentes.</string>
|
||||
<string name="education_generate_password_title">Criar uma senha forte</string>
|
||||
<string name="education_generate_password_summary">Gere uma senha forte para associar a sua entrada, defina-a facilmente de acordo com os critérios do formulário e não se esqueça de torná-la segura.</string>
|
||||
<string name="education_generate_password_summary">Gere uma senha forte para associar a sua entrada, defina-a facilmente de acordo com os critérios do formulário e lembre-se de torná-la segura.</string>
|
||||
<string name="education_entry_new_field_title">Adicione campos customizados</string>
|
||||
<string name="education_entry_new_field_summary">Registrar um campo adicional, adicionar um valor e, opcionalmente, protegê-lo.</string>
|
||||
<string name="education_unlock_title">Desbloqueie seu banco de dados</string>
|
||||
@@ -254,7 +254,7 @@
|
||||
<string name="education_read_only_summary">Altere o modo de abertura para a sessão.
|
||||
\n
|
||||
\n\"Somente leitura\" evita que você faça alterações não intencionais no banco de dados.
|
||||
\n\"Gravação\" permite você a adicionar, excluir ou modificar todos os elementos.</string>
|
||||
\n\"Modificável\" permite você adicionar, excluir ou modificar todos os elementos que desejar.</string>
|
||||
<string name="education_field_copy_title">Copiar um campo</string>
|
||||
<string name="education_field_copy_summary">Campos copiados podem ser colados em qualquer lugar.
|
||||
\n
|
||||
@@ -262,7 +262,7 @@
|
||||
<string name="education_lock_title">Bloqueie o banco de dados</string>
|
||||
<string name="education_lock_summary">Bloqueie seu banco de dados rapidamente, você pode parametrizar o aplicativo para bloqueá-lo depois de um tempo, e quando a tela se apaga.</string>
|
||||
<string name="education_sort_title">Ordenação de itens</string>
|
||||
<string name="education_sort_summary">Escolha como entradas e grupos são ordenadas.</string>
|
||||
<string name="education_sort_summary">Escolha como entradas e grupos são ordenados.</string>
|
||||
<string name="education_donation_title">Participar</string>
|
||||
<string name="education_donation_summary">Ajude a aumentar a estabilidade, segurança e na adição de mais recursos.</string>
|
||||
<string name="html_text_ad_free">Ao contrário de muitos aplicativos de gerenciamento de senhas, este aplicativo é <strong>livre de anúncios</strong>, <strong>livre de direitos autorais</strong> e não recupera dados pessoais em seus servidores, mesmo em sua versão gratuita.</string>
|
||||
@@ -275,7 +275,7 @@
|
||||
<string name="html_text_dev_feature_encourage">Você está incentivando os desenvolvedores a criar <strong>novos recursos</strong> e a <strong>corrigir erros </strong> de acordo com suas observações.</string>
|
||||
<string name="html_text_dev_feature_thanks">Obrigado por sua contribuição.</string>
|
||||
<string name="html_text_dev_feature_work_hard">Estamos trabalhando duro para lançar esse recurso o mais rápido possível.</string>
|
||||
<string name="html_text_dev_feature_upgrade">Lembre-se de manter seu aplicativo atualizado.</string>
|
||||
<string name="html_text_dev_feature_upgrade">Não se esqueça de instalar as novas versões para manter seu aplicativo atualizado.</string>
|
||||
<string name="download">Baixar</string>
|
||||
<string name="contribute">Contribuir</string>
|
||||
<string name="style_choose_title">Tema do aplicativo</string>
|
||||
@@ -283,7 +283,7 @@
|
||||
<string name="icon_pack_choose_title">Pacote de ícones</string>
|
||||
<string name="icon_pack_choose_summary">Pacote de ícones usado no aplicativo</string>
|
||||
<string name="edit_entry">Editar entrada</string>
|
||||
<string name="error_load_database">Falha ao carregar o banco.</string>
|
||||
<string name="error_load_database">Não foi possível carregar seu banco de dados.</string>
|
||||
<string name="error_load_database_KDF_memory">Não pôde carregar a chave. Tente diminuir o \"Uso de Memória\" do KDF.</string>
|
||||
<string name="list_entries_show_username_title">Mostrar nomes de usuário</string>
|
||||
<string name="list_entries_show_username_summary">Mostrar nomes de usuário em listas de entrada</string>
|
||||
@@ -305,21 +305,21 @@
|
||||
<string name="keyboard_appearance_category">Aparência</string>
|
||||
<string name="keyboard_theme_title">Tema do teclado</string>
|
||||
<string name="keyboard_keys_category">Teclas</string>
|
||||
<string name="keyboard_key_vibrate_title">Vibrar ao clicar</string>
|
||||
<string name="keyboard_key_sound_title">Clicar audível</string>
|
||||
<string name="selection_mode">Modo de seleção</string>
|
||||
<string name="keyboard_key_vibrate_title">Vibrar ao pressionar teclas</string>
|
||||
<string name="keyboard_key_sound_title">Teclas audíveis</string>
|
||||
<string name="selection_mode">Modo seleção</string>
|
||||
<string name="do_not_kill_app">Não feche o aplicativo…</string>
|
||||
<string name="lock_database_back_root_title">Pressione \'Voltar\' para trancar</string>
|
||||
<string name="lock_database_back_root_title">Pressione \'Voltar\' para bloquear</string>
|
||||
<string name="lock_database_back_root_summary">Trancar a base de dados quando o usuário pressiona o botão \"Voltar\" na tela inicial</string>
|
||||
<string name="clear_clipboard_notification_title">Limpar ao fechar</string>
|
||||
<string name="clear_clipboard_notification_summary">Bloquear o banco de dados quando a duração da área de transferência expirar ou a notificação for fechada depois do início do uso</string>
|
||||
<string name="recycle_bin">Lixeira</string>
|
||||
<string name="keyboard_selection_entry_title">Seleção de entrada</string>
|
||||
<string name="keyboard_selection_entry_summary">Mostrar campos de entrada no Magikeyboard quando estiver visualizando uma Entrada</string>
|
||||
<string name="delete_entered_password_title">Deletar senha</string>
|
||||
<string name="keyboard_selection_entry_summary">Ao visualizar uma entrada no KeePassDX, preencher o Magikeyboard com essa entrada</string>
|
||||
<string name="delete_entered_password_title">Excluir senha</string>
|
||||
<string name="delete_entered_password_summary">Deleta a senha inserida após uma tentativa de conexão com o banco de dados</string>
|
||||
<string name="content_description_open_file">Abrir arquivo</string>
|
||||
<string name="content_description_add_node">Inserir nó</string>
|
||||
<string name="content_description_add_node">Adicionar nó</string>
|
||||
<string name="content_description_add_entry">Adicionar entrada</string>
|
||||
<string name="content_description_add_group">Adicionar grupo</string>
|
||||
<string name="content_description_file_information">Informações do arquivo</string>
|
||||
@@ -327,14 +327,14 @@
|
||||
<string name="entry_password_generator">Gerador de senhas</string>
|
||||
<string name="content_description_password_length">Comprimento da senha</string>
|
||||
<string name="entry_add_field">Adicionar campo</string>
|
||||
<string name="content_description_remove_field">Remover campo</string>
|
||||
<string name="content_description_remove_field">Excluir campo</string>
|
||||
<string name="entry_UUID">UUID</string>
|
||||
<string name="error_move_entry_here">Você não pode mover uma entrada para cá.</string>
|
||||
<string name="error_copy_entry_here">Você não pode copiar uma entrada daqui.</string>
|
||||
<string name="list_groups_show_number_entries_title">Mostrar número de entradas</string>
|
||||
<string name="list_groups_show_number_entries_summary">Mostrar o número de entradas dentro de um grupo</string>
|
||||
<string name="content_description_node_children">Nó filho</string>
|
||||
<string name="content_description_password_checkbox">Caixa de seleção de senha</string>
|
||||
<string name="content_description_password_checkbox">Caixa de seleção da senha</string>
|
||||
<string name="content_description_keyfile_checkbox">Caixa de seleção do arquivo-chave</string>
|
||||
<string name="content_description_repeat_toggle_password_visibility">Repetir mudança de visibilidade da senha</string>
|
||||
<string name="content_description_background">Plano de fundo</string>
|
||||
@@ -343,14 +343,14 @@
|
||||
<string name="error_create_database_file">Impossibilitado de criar um banco de dados com essa senha e arquivo-chave.</string>
|
||||
<string name="menu_advanced_unlock_settings">Desbloqueio avançado</string>
|
||||
<string name="biometric">Biometria</string>
|
||||
<string name="biometric_auto_open_prompt_title">Abrir automaticamente o prompt de biometria</string>
|
||||
<string name="biometric_auto_open_prompt_summary">Pedir automaticamente pelo prompt de biometria se a base de dados estiver configurada para usá-la</string>
|
||||
<string name="biometric_auto_open_prompt_title">Abrir automaticamente o prompt</string>
|
||||
<string name="biometric_auto_open_prompt_summary">Solicitar desbloqueio avançado automaticamente se o banco de dados estiver configurado para usá-lo</string>
|
||||
<string name="enable">Habilitado</string>
|
||||
<string name="disable">Desabilitado</string>
|
||||
<string name="master_key">Chave mestra</string>
|
||||
<string name="security">Segurança</string>
|
||||
<string name="entry_history">Histórico</string>
|
||||
<string name="entry_setup_otp">Configurar OTP</string>
|
||||
<string name="entry_setup_otp">Configure uma senha de uso único</string>
|
||||
<string name="otp_type">Tipo OTP</string>
|
||||
<string name="otp_secret">Segredo</string>
|
||||
<string name="otp_period">Período (segundos)</string>
|
||||
@@ -397,16 +397,16 @@
|
||||
<string name="menu_empty_recycle_bin">Esvaziar lixeira</string>
|
||||
<string name="command_execution">Executando o comando…</string>
|
||||
<string name="warning_permanently_delete_nodes">Apagar permanentemente os nós selecionados\?</string>
|
||||
<string name="keystore_not_accessible">A chave não foi propriamente inicializada.</string>
|
||||
<string name="keystore_not_accessible">O armazenamento chaves não foi propriamente inicializado.</string>
|
||||
<string name="recycle_bin_group_title">Grupo de lixeira</string>
|
||||
<string name="enable_auto_save_database_title">Salvar automaticamente a base de dados</string>
|
||||
<string name="enable_auto_save_database_summary">Salvar automaticamente a base de dados depois de uma ação importante (somente no modo \"Gravação\")</string>
|
||||
<string name="enable_auto_save_database_summary">Salvar automaticamente a base de dados depois de uma ação importante (somente no modo \"Modificável\")</string>
|
||||
<string name="discard">Descartar</string>
|
||||
<string name="contact">Contato</string>
|
||||
<string name="auto_focus_search_title">Pesquisa rápida</string>
|
||||
<string name="auto_focus_search_title">Busca rápida</string>
|
||||
<string name="menu_delete_entry_history">Apagar histórico</string>
|
||||
<string name="menu_restore_entry_history">Restaurar histórico</string>
|
||||
<string name="autofill_auto_search_summary">Sugerir resultados de pesquisa de domínios da internet ou de aplicações automaticamente</string>
|
||||
<string name="autofill_auto_search_summary">Sugerir resultados de busca de domínios da internet ou de aplicativos automaticamente</string>
|
||||
<string name="hide_expired_entries_summary">Entradas expiradas foram escondidas</string>
|
||||
<string name="hide_expired_entries_title">Esconder entradas expiradas</string>
|
||||
<string name="download_complete">Completo!</string>
|
||||
@@ -416,33 +416,33 @@
|
||||
<string name="download_attachment">Baixar %1$s</string>
|
||||
<string name="education_setup_OTP_summary">Configure o gerenciamento de senha descartável (HOTP / TOTP) para gerar um token solicitado para autenticação de dois fatores (2FA).</string>
|
||||
<string name="education_setup_OTP_title">Configurar OTP</string>
|
||||
<string name="autofill_auto_search_title">Pesquisa automática</string>
|
||||
<string name="keyboard_auto_go_action_summary">Ação da tecla \"Go\" após pressionar a tecla \"Field\"</string>
|
||||
<string name="keyboard_auto_go_action_title">Ação automática de tecla</string>
|
||||
<string name="autofill_auto_search_title">Busca automática</string>
|
||||
<string name="keyboard_auto_go_action_summary">Ação da tecla \"Ir\" após pressionar a tecla \"Campo\"</string>
|
||||
<string name="keyboard_auto_go_action_title">Ação de tecla automática</string>
|
||||
<string name="lock_database_show_button_summary">Mostrar o botão de bloqueio na interface do usuário</string>
|
||||
<string name="lock_database_show_button_title">Mostrar botão de bloqueio</string>
|
||||
<string name="autofill_preference_title">Configurações de preenchimento automático</string>
|
||||
<string name="warning_database_link_revoked">Acesso ao arquivo revogado pelo gerenciador de arquivos</string>
|
||||
<string name="warning_database_read_only">Conceder acesso de gravação de arquivo para salvar alterações na base de dados</string>
|
||||
<string name="hide_broken_locations_summary">Esconder links quebrados na lista de bases de dados recentes</string>
|
||||
<string name="hide_broken_locations_title">Esconder links quebrados de bases de dados</string>
|
||||
<string name="hide_broken_locations_title">Ocultar links quebrados do banco de dados</string>
|
||||
<string name="remember_keyfile_locations_summary">Manter o local onde os arquivos-chave são armazenados</string>
|
||||
<string name="remember_keyfile_locations_title">Lembrar a localização dos arquivos-chave</string>
|
||||
<string name="remember_database_locations_summary">Manter o local onde os bancos de dados são armazenados</string>
|
||||
<string name="remember_database_locations_summary">Lembra o local onde os bancos de dados são guardados</string>
|
||||
<string name="remember_database_locations_title">Lembrar a localização dos bancos de dados</string>
|
||||
<string name="auto_focus_search_summary">Solicitar uma pesquisa quando abrir a base de dados</string>
|
||||
<string name="error_create_database">Incapaz de criar arquivo de base de dados.</string>
|
||||
<string name="auto_focus_search_summary">Solicitar uma busca ao abrir um banco de dados</string>
|
||||
<string name="error_create_database">Não foi possível criar o arquivo do banco de dados.</string>
|
||||
<string name="error_label_exists">Este rótulo já existe.</string>
|
||||
<string name="entry_attachments">Acessórios</string>
|
||||
<string name="html_about_contribution">Para <strong>manter sua liberdade</strong>, <strong>solucionar bugs</strong>, <strong>adicionar funções</strong> e <strong>para ser sempre ativo</strong>, nós contamos com sua <strong>contribuição</strong>.</string>
|
||||
<string name="entry_attachments">Anexos</string>
|
||||
<string name="html_about_contribution">Para <strong>manter nossa liberdade</strong>, <strong>consertar erros</strong>, <strong>adicionar recursos</strong> e <strong>para estar sempre ativo</strong>, contamos com sua <strong>contribuição</strong>.</string>
|
||||
<string name="entry_add_attachment">Adicionar anexo</string>
|
||||
<string name="discard_changes">Descartar alterações\?</string>
|
||||
<string name="validate">Validação</string>
|
||||
<string name="discard_changes">Descartar mudanças\?</string>
|
||||
<string name="validate">Validar</string>
|
||||
<string name="contribution">Contribuição</string>
|
||||
<string name="keyboard_search_share_summary">Procurar automaticamente por informação compartilhada para popular o teclado</string>
|
||||
<string name="keyboard_search_share_summary">Ao compartilhar um URL para KeePassDX, filtre as entradas usando esse domínio de URL</string>
|
||||
<string name="keyboard_search_share_title">Procurar informação compartilhada</string>
|
||||
<string name="upload_attachment">Upload %1$s</string>
|
||||
<string name="keyboard_previous_fill_in_summary">Retornar automaticamente para o teclado anterior após executar a ação automática de tecla</string>
|
||||
<string name="keyboard_previous_fill_in_summary">Retornar automaticamente para o teclado anterior após executar a \"ação de tecla automática\"</string>
|
||||
<string name="keyboard_previous_fill_in_title">Ação automática de tecla</string>
|
||||
<string name="warning_remove_unlinked_attachment">A remoção de dados não vinculados pode diminuir o tamanho do seu banco de dados, mas também pode excluir os dados usados para plug-ins KeePass.</string>
|
||||
<string name="warning_replace_file">O upload deste arquivo substituirá o existente.</string>
|
||||
@@ -463,14 +463,141 @@
|
||||
<string name="warning_empty_keyfile">Não é recomendado adicionar um arquivo-chave vazio.</string>
|
||||
<string name="warning_sure_remove_data">Remover esses dados mesmo assim\?</string>
|
||||
<string name="warning_sure_add_file">Adicionar o arquivo mesmo assim\?</string>
|
||||
<string name="warning_file_too_big">Um banco de dados KeePass deve conter somente pequenos arquivos de utilitários (como arquivos de chave PGP).
|
||||
<string name="warning_file_too_big">Um banco de dados KeePass deve conter apenas pequenos arquivos de utilitários (como arquivos de chave PGP).
|
||||
\n
|
||||
\nSeu banco de dados pode ficar muito grande e reduzir o desempenho com este upload.</string>
|
||||
<string name="filter">Filtro</string>
|
||||
<string name="subdomain_search_summary">Pesquisar domínios da web com restrições de subdomínios</string>
|
||||
<string name="subdomain_search_title">Pesquisa de subdomínio</string>
|
||||
<string name="error_string_type">Esse texto não conbina com o item solicitado.</string>
|
||||
<string name="subdomain_search_summary">Buscar por domínios na web com restrições de subdomínios</string>
|
||||
<string name="subdomain_search_title">Busca de subdomínio</string>
|
||||
<string name="error_string_type">Esse texto não coincide com o item requerido.</string>
|
||||
<string name="content_description_credentials_information">Informações de credenciais</string>
|
||||
<string name="content_description_add_item">Adicionar item</string>
|
||||
<string name="autofill_block_restart">Reinicie o aplicativo que contém o formulário para ativar o bloqueio.</string>
|
||||
<string name="menu_keystore_remove_key">Excluir chave de desbloqueio avançado</string>
|
||||
<string name="menu_reload_database">Recarregar banco de dados</string>
|
||||
<string name="error_start_database_action">Ocorreu um erro ao executar uma ação no banco de dados.</string>
|
||||
<string name="error_remove_file">Ocorreu um erro ao remover os dados do arquivo.</string>
|
||||
<string name="error_duplicate_file">Os dados do arquivo já existem.</string>
|
||||
<string name="error_upload_file">Ocorreu um erro ao enviar os dados do arquivo.</string>
|
||||
<string name="error_file_to_big">O arquivo que você está tentando enviar é muito grande.</string>
|
||||
<string name="error_rebuild_list">Incapaz de reconstruir corretamente a lista.</string>
|
||||
<string name="error_database_uri_null">O URI do banco de dados não pode ser recuperado.</string>
|
||||
<string name="error_field_name_already_exists">O nome do campo já existe.</string>
|
||||
<string name="error_registration_read_only">Não é permitido salvar um novo item em um banco de dados somente de leitura</string>
|
||||
<string name="error_otp_type">O tipo de OTP existente não é reconhecido por este formulário, sua validação pode não gerar mais o token corretamente.</string>
|
||||
<string name="error_word_reserved">Esta palavra é reservada e não pode ser usada.</string>
|
||||
<string name="version">Versão</string>
|
||||
<string name="template">Modelo</string>
|
||||
<string name="standard">Padrão</string>
|
||||
<string name="membership">Afiliação</string>
|
||||
<string name="secure_note">Nota segura</string>
|
||||
<string name="international_bank_account_number">IBAN</string>
|
||||
<string name="bank_identifier_code">SWIFT / BIC</string>
|
||||
<string name="bank_name">Nome do banco</string>
|
||||
<string name="bank">Banco</string>
|
||||
<string name="account">Conta</string>
|
||||
<string name="seed">Semente</string>
|
||||
<string name="private_key">Chave privada</string>
|
||||
<string name="public_key">Chave pública</string>
|
||||
<string name="token">Token</string>
|
||||
<string name="cryptocurrency">Carteira de criptomoedas</string>
|
||||
<string name="type">Tipo</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="email_address">Endereço eletrônico</string>
|
||||
<string name="email">Email</string>
|
||||
<string name="date_of_issue">Data de emissão</string>
|
||||
<string name="place_of_issue">Local de emissão</string>
|
||||
<string name="name">Nome</string>
|
||||
<string name="id_card">Cédula de identidade</string>
|
||||
<string name="personal_identification_number">PIN</string>
|
||||
<string name="card_verification_value">CVV</string>
|
||||
<string name="number">Número</string>
|
||||
<string name="holder">Titular</string>
|
||||
<string name="debit_credit_card">Cartão de débito / crédito</string>
|
||||
<string name="template_group_name">Modelos</string>
|
||||
<string name="content_description_otp_information">Informação de senha de uso único</string>
|
||||
<string name="device_credential">Credencial do dispositivo</string>
|
||||
<string name="properties">Propriedades</string>
|
||||
<string name="credential_before_click_advanced_unlock_button">Digite a senha e clique neste botão.</string>
|
||||
<string name="advanced_unlock_prompt_not_initialized">Incapaz de inicializar o prompt de desbloqueio avançado.</string>
|
||||
<string name="advanced_unlock_scanning_error">Erro de desbloqueio avançado: %1$s</string>
|
||||
<string name="advanced_unlock_not_recognized">Não foi possível reconhecer a impressão de desbloqueio avançado</string>
|
||||
<string name="advanced_unlock_invalid_key">Não é possível ler a chave de desbloqueio avançado. Exclua-o e repita o procedimento de reconhecimento de desbloqueio.</string>
|
||||
<string name="advanced_unlock_prompt_extract_credential_message">Extraia credencial de banco de dados com dados de desbloqueio avançado</string>
|
||||
<string name="advanced_unlock_prompt_extract_credential_title">Banco de dados aberto com reconhecimento avançado de desbloqueio</string>
|
||||
<string name="advanced_unlock_prompt_store_credential_message">Aviso: você ainda precisa lembrar sua senha mestra se usar o reconhecimento de desbloqueio avançado.</string>
|
||||
<string name="advanced_unlock_prompt_store_credential_title">Reconhecimento de desbloqueio avançado</string>
|
||||
<string name="open_advanced_unlock_prompt_store_credential">Abra o prompt de desbloqueio avançado para armazenar credenciais</string>
|
||||
<string name="open_advanced_unlock_prompt_unlock_database">Abra o prompt de desbloqueio avançado para desbloquear o banco de dados</string>
|
||||
<string name="biometric_security_update_required">Atualização de segurança biométrica necessária.</string>
|
||||
<string name="configure_biometric">Nenhuma credencial biométrica ou de dispositivo está registrada.</string>
|
||||
<string name="warning_database_revoked">Acesso ao arquivo revogado pelo gerenciador de arquivos, feche o banco de dados e reabra-o de sua localização.</string>
|
||||
<string name="warning_database_info_changed_options">Substitua as modificações externas salvando o banco de dados ou recarregue-o com as alterações mais recentes.</string>
|
||||
<string name="warning_database_info_changed">As informações contidas em seu arquivo de banco de dados foram modificadas fora do aplicativo.</string>
|
||||
<string name="warning_empty_recycle_bin">Deletar permanentemente todos os nós da lixeira\?</string>
|
||||
<string name="error_export_app_properties">Erro durante a exportação de propriedades do aplicativo</string>
|
||||
<string name="success_export_app_properties">Propriedades do aplicativo exportadas</string>
|
||||
<string name="error_import_app_properties">Erro durante a importação de propriedades do aplicativo</string>
|
||||
<string name="success_import_app_properties">Propriedades de aplicativos importadas</string>
|
||||
<string name="description_app_properties">Propriedades KeePassDX para gerenciar configurações de aplicativos</string>
|
||||
<string name="export_app_properties_summary">Crie um arquivo para exportar as propriedades do aplicativo</string>
|
||||
<string name="export_app_properties_title">Exportar propriedades do aplicativo</string>
|
||||
<string name="import_app_properties_summary">Selecione um arquivo para importar as propriedades do aplicativo</string>
|
||||
<string name="import_app_properties_title">Importar propriedades do aplicativo</string>
|
||||
<string name="registration_mode">Modo registro</string>
|
||||
<string name="save_mode">Modo salvar</string>
|
||||
<string name="search_mode">Modo busca</string>
|
||||
<string name="menu_external_icon">Ícone externo</string>
|
||||
<string name="show_otp_token_summary">Exibe tokens OTP na lista de entradas</string>
|
||||
<string name="show_otp_token_title">Mostrar token OTP</string>
|
||||
<string name="show_uuid_summary">Exibe o UUID vinculado a uma entrada ou grupo</string>
|
||||
<string name="show_uuid_title">Mostrar UUID</string>
|
||||
<string name="icon_section_custom">Personalizado</string>
|
||||
<string name="icon_section_standard">Padrão</string>
|
||||
<string name="style_brightness_summary">Selecione temas claros ou escuros</string>
|
||||
<string name="style_brightness_title">Brilho do tema</string>
|
||||
<string name="unit_gibibyte">GiB</string>
|
||||
<string name="unit_mebibyte">MiB</string>
|
||||
<string name="unit_kibibyte">KiB</string>
|
||||
<string name="unit_byte">B</string>
|
||||
<string name="download_canceled">Cancelado!</string>
|
||||
<string name="education_advanced_unlock_summary">Vincule sua senha à credencial biométrica ou do dispositivo digitalizada para desbloquear rapidamente seu banco de dados.</string>
|
||||
<string name="education_advanced_unlock_title">Desbloqueio avançado de banco de dados</string>
|
||||
<string name="autofill_inline_suggestions_keyboard">Sugestões de preenchimento automático adicionadas.</string>
|
||||
<string name="autofill_read_only_save">A salvação de dados não é permitida para um banco de dados aberto apenas como leitura.</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Pedir para salvar dados quando um formulário for validado</string>
|
||||
<string name="autofill_ask_to_save_data_title">Perguntar para salvar dados</string>
|
||||
<string name="autofill_save_search_info_summary">Tente salvar informações de pesquisa ao fazer uma seleção manual de entrada</string>
|
||||
<string name="autofill_save_search_info_title">Salvar informações de busca</string>
|
||||
<string name="autofill_manual_selection_summary">Exibir opção para permitir que o usuário selecione a entrada do banco de dados</string>
|
||||
<string name="autofill_manual_selection_title">Seleção manual</string>
|
||||
<string name="autofill_inline_suggestions_summary">Tente exibir sugestões de preenchimento automático diretamente de um teclado compatível</string>
|
||||
<string name="autofill_inline_suggestions_title">Sugestões em linha</string>
|
||||
<string name="autofill_close_database_summary">Feche o banco de dados após uma seleção de preenchimento automático</string>
|
||||
<string name="autofill_close_database_title">Fechar banco de dados</string>
|
||||
<string name="enter">Enter</string>
|
||||
<string name="backspace">← Deletar</string>
|
||||
<string name="select_entry">Selecionar entrada</string>
|
||||
<string name="back_to_previous_keyboard">Voltar ao teclado anterior</string>
|
||||
<string name="custom_fields">Campos personalizados</string>
|
||||
<string name="keyboard_previous_lock_summary">Retornar automaticamente para o teclado anterior depois de bloquear o banco de dados</string>
|
||||
<string name="keyboard_previous_lock_title">Bloquear banco de dados</string>
|
||||
<string name="keyboard_save_search_info_summary">Depois de compartilhar uma URL para o KeePassDX, quando uma entrada é selecionada, tente lembrar que a entrada para usos adicionais</string>
|
||||
<string name="keyboard_save_search_info_title">Salvar informações compartilhadas</string>
|
||||
<string name="templates">Modelos</string>
|
||||
<string name="notification">Notificação</string>
|
||||
<string name="templates_group_uuid_title">Grupo de modelos</string>
|
||||
<string name="templates_group_enable_summary">Use modelos dinâmicos para preencher os campos de uma entrada</string>
|
||||
<string name="templates_group_enable_title">Uso de modelos</string>
|
||||
<string name="advanced_unlock_delete_all_key_warning">Apagar todas as chaves de cifragem relacionadas ao reconhecimento de desbloqueio avançado\?</string>
|
||||
<string name="advanced_unlock_timeout">Tempo limite de desbloqueio avançado</string>
|
||||
<string name="temp_advanced_unlock_timeout_summary">Duração do uso de desbloqueio avançado antes de excluir seu conteúdo</string>
|
||||
<string name="temp_advanced_unlock_timeout_title">Expiração de desbloqueio avançado</string>
|
||||
<string name="temp_advanced_unlock_enable_summary">Não armazene nenhum conteúdo cifrado para usar desbloqueio avançado</string>
|
||||
<string name="temp_advanced_unlock_enable_title">Desbloqueio avançado temporário</string>
|
||||
<string name="device_credential_unlock_enable_summary">Permite que você use a credencial do seu dispositivo para abrir o banco de dados</string>
|
||||
<string name="device_credential_unlock_enable_title">Desbloqueio de credencial de dispositivo</string>
|
||||
<string name="advanced_unlock_tap_delete">Toque para excluir as chaves de desbloqueio avançado</string>
|
||||
<string name="content">Conteúdo</string>
|
||||
<string name="autofill_select_entry">Selecione a entrada…</string>
|
||||
</resources>
|
||||
@@ -24,26 +24,26 @@
|
||||
<string name="add_entry">Adicionar entrada</string>
|
||||
<string name="add_group">Adicionar grupo</string>
|
||||
<string name="encryption_algorithm">Algoritmo de encriptação</string>
|
||||
<string name="app_timeout">Tempo de espera da app</string>
|
||||
<string name="app_timeout">Tempo de espera</string>
|
||||
<string name="app_timeout_summary">Inatividade antes de bloquear a base de dados</string>
|
||||
<string name="application">App</string>
|
||||
<string name="menu_app_settings">Configurações do app</string>
|
||||
<string name="application">Aplicação</string>
|
||||
<string name="menu_app_settings">Configurações da aplicação</string>
|
||||
<string name="brackets">Parênteses</string>
|
||||
<string name="file_manager_install_description">Um gestor de ficheiros que aceita a ação intencional ACTION_CREATE_DOCUMENT e ACTION_OPEN_DOCUMENT é necessário para criar, abrir e gravar ficheiros de base de dados.</string>
|
||||
<string name="file_manager_install_description">Um gestor de ficheiros que aceita a ação intencional ACTION_CREATE_DOCUMENT e ACTION_OPEN_DOCUMENT é necessário para criar, abrir e gravar ficheiros da base de dados.</string>
|
||||
<string name="clipboard_cleared">Área de transferência limpa</string>
|
||||
<string name="clipboard_error_title">Erro na área de transferência</string>
|
||||
<string name="clipboard_error">Alguns aparelhos não deixam as apps usarem a área de transferência.</string>
|
||||
<string name="clipboard_error">Alguns dispositivos não permitem que as aplicações usem a área de transferência.</string>
|
||||
<string name="clipboard_error_clear">Não foi possível limpar a área de transferência</string>
|
||||
<string name="clipboard_timeout">Tempo de espera da área de transferência</string>
|
||||
<string name="clipboard_timeout_summary">Duração do armazenamento na área de transferência (se for suportado pelo seu aparelho)</string>
|
||||
<string name="clipboard_timeout_summary">Duração do armazenamento na área de transferência (se for suportado pelo seu dispositivo)</string>
|
||||
<string name="select_to_copy">Selecione para copiar %1$s para a área de transferência</string>
|
||||
<string name="retrieving_db_key">A criar a chave da base de dados…</string>
|
||||
<string name="database">Base de dados</string>
|
||||
<string name="decrypting_db">A desencriptar o conteúdo da base de dados…</string>
|
||||
<string name="default_checkbox">Utilizar como base de dados predefinida</string>
|
||||
<string name="digits">Dígitos</string>
|
||||
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft é <strong>open source</strong> e <strong>sem publicidade</strong>.
|
||||
\nÉ fornecido como está, sob a <strong>licença GPLv3</strong>, sem qualquer garantia.</string>
|
||||
<string name="html_about_licence">KeePassDX © %1$d Kunzisoft tem o <strong>código-fonte aberto</strong> e <strong>sem publicidade</strong>.
|
||||
\nÉ fornecido como está, sob a <strong>licença GPLv3</strong>, sem qualquer garantia.</string>
|
||||
<string name="select_database_file">Abrir uma base de dados existente</string>
|
||||
<string name="entry_accessed">Acedido</string>
|
||||
<string name="entry_cancel">Cancelar</string>
|
||||
@@ -51,103 +51,103 @@
|
||||
<string name="entry_confpassword">Confirmar palavra-passe</string>
|
||||
<string name="entry_created">Criado</string>
|
||||
<string name="entry_expires">Expira</string>
|
||||
<string name="entry_keyfile">Ficheiro chave</string>
|
||||
<string name="entry_modified">Modificado</string>
|
||||
<string name="entry_keyfile">Ficheiro-chave</string>
|
||||
<string name="entry_modified">Alterado</string>
|
||||
<string name="entry_not_found">Não foi possível encontrar os dados da entrada.</string>
|
||||
<string name="entry_password">Palavra-passe</string>
|
||||
<string name="save">Guardar</string>
|
||||
<string name="entry_title">Nome</string>
|
||||
<string name="entry_title">Título</string>
|
||||
<string name="entry_url">URL</string>
|
||||
<string name="entry_user_name">Nome de utilizador</string>
|
||||
<string name="error_arc4">A cifra de fluxo Arcfour não é suportada.</string>
|
||||
<string name="error_can_not_handle_uri">Não pôde tratar esta URI no KeePassDX.</string>
|
||||
<string name="error_can_not_handle_uri">Não foi possível processar esta URI no KeePassDX.</string>
|
||||
<string name="error_file_not_create">Não foi possível criar o ficheiro</string>
|
||||
<string name="error_invalid_db">Não foi possível ler o banco de dados.</string>
|
||||
<string name="error_invalid_db">Não foi possível ler a base de dados.</string>
|
||||
<string name="error_invalid_path">Certifique-se que o caminho é válido.</string>
|
||||
<string name="error_no_name">Introduza um nome.</string>
|
||||
<string name="error_nokeyfile">Selecione um ficheiro chave.</string>
|
||||
<string name="error_out_of_memory">Falta de memória para carregar toda a base de dados.</string>
|
||||
<string name="error_pass_gen_type">Pelo menos um tipo de geração de palavra-chave deve ser selecionado.</string>
|
||||
<string name="error_nokeyfile">Selecione um ficheiro-chave.</string>
|
||||
<string name="error_out_of_memory">Sem memória suficiente para carregar toda a base de dados.</string>
|
||||
<string name="error_pass_gen_type">Tem de ser selecionado pelo menos um tipo de geração de palavra-chave.</string>
|
||||
<string name="error_pass_match">As palavras-passe não coincidem.</string>
|
||||
<string name="error_rounds_too_large">\"Número de rodadas\" é muito grande. Modificado para 2147483648.</string>
|
||||
<string name="error_string_key">Um nome do campo é necessário para cada string.</string>
|
||||
<string name="error_wrong_length">Digite um número inteiro positivo no campo \"Tamanho\".</string>
|
||||
<string name="error_rounds_too_large">\"Rodadas de transformação\" é muito grande. Alterado para 2147483648.</string>
|
||||
<string name="error_string_key">É necessário um nome de campo para cada cadeia.</string>
|
||||
<string name="error_wrong_length">Digite um número inteiro positivo no campo \"Comprimento\".</string>
|
||||
<string name="field_name">Nome do campo</string>
|
||||
<string name="field_value">Valor do campo</string>
|
||||
<string name="file_not_found_content">Ficheiro não encontrado. Tente reabrí-lo de seu provedor de conteúdo.</string>
|
||||
<string name="file_not_found_content">Não foi possível encontrar o ficheiro. Tente reabri-lo no seu navegador de ficheiros.</string>
|
||||
<string name="file_browser">Gestor de ficheiros</string>
|
||||
<string name="generate_password">Gerar palavra-chave</string>
|
||||
<string name="generate_password">Gerar palavra-passe</string>
|
||||
<string name="hint_conf_pass">Confirmar a palavra-passe</string>
|
||||
<string name="hint_generated_password">Palavra-chave gerada</string>
|
||||
<string name="hint_generated_password">Palavra-passe gerada</string>
|
||||
<string name="hint_group_name">Nome do grupo</string>
|
||||
<string name="hint_keyfile">Ficheiro-chave</string>
|
||||
<string name="hint_length">Comprimento</string>
|
||||
<string name="hint_pass">Palavra-passe</string>
|
||||
<string name="password">Palavra-chave</string>
|
||||
<string name="password">Palavra-passe</string>
|
||||
<string name="invalid_credentials">Não foi possível ler as credenciais.</string>
|
||||
<string name="invalid_algorithm">Algoritmo errado.</string>
|
||||
<string name="invalid_db_sig">Não pôde reconhecer formato da base de dados.</string>
|
||||
<string name="invalid_db_sig">Não foi possível reconhecer o formato da base de dados.</string>
|
||||
<string name="keyfile_is_empty">O ficheiro-chave está vazio.</string>
|
||||
<string name="length">Comprimento</string>
|
||||
<string name="list_size_title">Tamanho da lista de grupos</string>
|
||||
<string name="list_size_summary">Tamanho do texto na lista de grupos</string>
|
||||
<string name="loading_database">A carregar base de dados…</string>
|
||||
<string name="loading_database">A carregar a base de dados…</string>
|
||||
<string name="lowercase">Minúsculas</string>
|
||||
<string name="hide_password_title">Esconder palavras-passe</string>
|
||||
<string name="hide_password_title">Ocultar palavras-passe</string>
|
||||
<string name="hide_password_summary">Mascarar palavras-passe (***) por predefinição</string>
|
||||
<string name="about">Sobre</string>
|
||||
<string name="menu_change_key_settings">Alterar chave mestre</string>
|
||||
<string name="menu_change_key_settings">Alterar chave mestra</string>
|
||||
<string name="settings">Configurações</string>
|
||||
<string name="menu_database_settings">Definições da base de dados</string>
|
||||
<string name="menu_database_settings">Configurações da base de dados</string>
|
||||
<string name="menu_delete">Eliminar</string>
|
||||
<string name="menu_donate">Doar</string>
|
||||
<string name="menu_donate">Donativos</string>
|
||||
<string name="menu_edit">Editar</string>
|
||||
<string name="menu_hide_password">Ocultar palavra-chave</string>
|
||||
<string name="menu_lock">Trancar base de dados</string>
|
||||
<string name="menu_lock">Bloquear base de dados</string>
|
||||
<string name="menu_open">Abrir</string>
|
||||
<string name="menu_search">Pesquisar</string>
|
||||
<string name="menu_showpass">Mostrar palavra-chave</string>
|
||||
<string name="menu_showpass">Mostrar palavra-passe</string>
|
||||
<string name="menu_url">Ir para o URL</string>
|
||||
<string name="minus">Menos</string>
|
||||
<string name="never">Nunca</string>
|
||||
<string name="no_results">A pesquisa não obteve resultados</string>
|
||||
<string name="no_url_handler">Instale um navegador para abrir esta URL.</string>
|
||||
<string name="omit_backup_search_title">Não procurar por entradas no backup ou na lixeira</string>
|
||||
<string name="omit_backup_search_summary">Omite os grupos \"Backup\" e \"Cesto da reciclagem\" dos resultados da busca</string>
|
||||
<string name="omit_backup_search_title">Não procurar por entradas na cópia de segurança e lixo</string>
|
||||
<string name="omit_backup_search_summary">Omite os grupos \"Cópia de segurança\" e \"Caixote da reciclagem\" dos resultados da busca</string>
|
||||
<string name="progress_create">A criar nova base de dados…</string>
|
||||
<string name="progress_title">Em funcionamento…</string>
|
||||
<string name="protection">Proteção</string>
|
||||
<string name="read_only">Apenas leitura</string>
|
||||
<string name="read_only_warning">KeePassDX precisa de permissões de escrita para poder mudar qualquer coisa no seu banco.</string>
|
||||
<string name="read_only_warning">Dependendo do seu gestor de ficheiros, o KeePassDX pode não ter permissão de escrita no armazenamento.</string>
|
||||
<string name="content_description_remove_from_list">Remover</string>
|
||||
<string name="root">Raiz</string>
|
||||
<string name="rounds">Rodadas de criptografia</string>
|
||||
<string name="rounds_explanation">Rodadas adicionais de criptografia adicionam mais proteção contra ataques de força bruta, mas podem tornar o processo de carregar e gravar mais lentos.</string>
|
||||
<string name="saving_database">A gravar a base de dados…</string>
|
||||
<string name="rounds">Rodadas de transformação</string>
|
||||
<string name="rounds_explanation">As rodadas adicionais de encriptação fornecem mais proteção contra ataques de força bruta, mas podem tornar o processo de carregar e guardar mais lentos.</string>
|
||||
<string name="saving_database">A guardar a base de dados…</string>
|
||||
<string name="space">Espaço</string>
|
||||
<string name="search_label">Pesquisar</string>
|
||||
<string name="sort_db">Ordenação natural</string>
|
||||
<string name="special">Especiais</string>
|
||||
<string name="search">Título/descrição da entrada</string>
|
||||
<string name="search">Pesquisar</string>
|
||||
<string name="search_results">Resultados da pesquisa</string>
|
||||
<string name="underline">Sublinhado</string>
|
||||
<string name="unsupported_db_version">Versão da base de dados não suportada.</string>
|
||||
<string name="uppercase">Maiúsculas</string>
|
||||
<string name="warning">Aviso</string>
|
||||
<string name="warning_password_encoding">Evite caracteres fora do formato de codificação do ficheiro do banco (todos os caracteres não reconhecidos são convertidos para a mesma letra).</string>
|
||||
<string name="warning_password_encoding">Evite caracteres fora do formato de codificação do ficheiro da base de dados (todos os caracteres não reconhecidos são convertidos para a mesma letra).</string>
|
||||
<string name="version_label">Versão %1$s</string>
|
||||
<string name="education_unlock_summary">Entre com a palavra-passe e/ou com o caminho para o ficheiro-chave da base de dados.
|
||||
\n
|
||||
\nGuarde uma cópia do seu ficheiro do banco num lugar mais seguro depois de cada alteração.</string>
|
||||
<string name="education_unlock_summary">Introduza a palavra-passe e/ou com o caminho para o ficheiro-chave da base de dados.
|
||||
\n
|
||||
\nGuarde uma cópia de segurança do ficheiro da sua base de dados num lugar seguro depois de cada alteração.</string>
|
||||
<string-array name="list_size_options">
|
||||
<item>Pequena</item>
|
||||
<item>Média</item>
|
||||
<item>Grande</item>
|
||||
</string-array>
|
||||
<string name="extended_ASCII">ASCII Extendido</string>
|
||||
<string name="extended_ASCII">ASCII estendido</string>
|
||||
<string name="allow">Permitir</string>
|
||||
<string name="error_load_database">Não foi possível abrir a sua base de dados.</string>
|
||||
<string name="error_load_database_KDF_memory">Não foi possível carregar a chave. Tente descarregar o \"Uso de Memória\" do KDF.</string>
|
||||
<string name="error_load_database_KDF_memory">Não foi possível carregar a chave. Tente diminuir o \"Uso de memória\" do KDF.</string>
|
||||
<string name="list_entries_show_username_title">Mostrar nomes de utilizador</string>
|
||||
<string name="copy_field">Cópia de %1$s</string>
|
||||
<string name="menu_form_filling_settings">Preenchimento de formulário</string>
|
||||
@@ -155,25 +155,25 @@
|
||||
<string name="menu_move">Mover</string>
|
||||
<string name="menu_paste">Colar</string>
|
||||
<string name="menu_cancel">Cancelar</string>
|
||||
<string name="menu_file_selection_read_only">Protegido contra escrita</string>
|
||||
<string name="menu_open_file_read_and_write">Pode ser modificado</string>
|
||||
<string name="menu_file_selection_read_only">Apenas leitura</string>
|
||||
<string name="menu_open_file_read_and_write">Alterável</string>
|
||||
<string name="create_keepass_file">Criar base de dados</string>
|
||||
<string name="kdf_explanation">Para gerar uma chave para o algoritmo de encriptação, a chave mestre comprimida (SHA-256) é transformada usando uma função de derivação de chave (com um salt aleatório).</string>
|
||||
<string name="kdf_explanation">Para gerar a chave para o algoritmo de encriptação, a chave mestra é transformada usando uma função de derivação de chave com um salt aleatório.</string>
|
||||
<string name="memory_usage">Uso de memória</string>
|
||||
<string name="memory_usage_explanation">Quantidade de memória a ser usada pela função de derivação de chave.</string>
|
||||
<string name="parallelism">Paralelismo</string>
|
||||
<string name="parallelism_explanation">Grau de paralelismo (ou seja, número de threads) usado pela função de derivação de chave.</string>
|
||||
<string name="sort_menu">Ordenar</string>
|
||||
<string name="sort_ascending">Ascendente</string>
|
||||
<string name="sort_ascending">Mais baixo primeiro ↓</string>
|
||||
<string name="sort_groups_before">Grupos primeiro</string>
|
||||
<string name="sort_recycle_bin_bottom">Cesto da reciclagem no fundo</string>
|
||||
<string name="sort_recycle_bin_bottom">Caixote da reciclagem no fundo</string>
|
||||
<string name="sort_title">Título</string>
|
||||
<string name="sort_username">Nome de utilizador</string>
|
||||
<string name="sort_creation_time">Data de criação</string>
|
||||
<string name="sort_last_modify_time">Última modificação</string>
|
||||
<string name="sort_last_modify_time">Última alteração</string>
|
||||
<string name="sort_last_access_time">Último acesso</string>
|
||||
<string name="warning_empty_password">Continuar sem proteção de desbloqueio por palavra-passe\?</string>
|
||||
<string name="warning_no_encryption_key">Continuar sem a chave de criptografia\?</string>
|
||||
<string name="warning_no_encryption_key">Continuar sem a chave de encriptação\?</string>
|
||||
<string name="build_label">Compilação %1$s</string>
|
||||
<string name="encrypted_value_stored">Palavra-passe encriptada armazenada</string>
|
||||
<string name="no_credentials_stored">Ainda não há nenhuma palavra-chave armazenada nesta base de dados.</string>
|
||||
@@ -181,107 +181,105 @@
|
||||
<string name="menu_appearance_settings">Aparência</string>
|
||||
<string name="general">Geral</string>
|
||||
<string name="autofill">Preenchimento automático</string>
|
||||
<string name="autofill_service_name">Serviço de Preenchimento Automático do KeePassDX</string>
|
||||
<string name="autofill_sign_in_prompt">Entrar com KeePassDX</string>
|
||||
<string name="autofill_service_name">Serviço de preenchimento automático do KeePassDX</string>
|
||||
<string name="autofill_sign_in_prompt">Iniciar sessão com KeePassDX</string>
|
||||
<string name="set_autofill_service_title">Definir como serviço de preenchimento automático predefinido</string>
|
||||
<string name="autofill_explanation_summary">Ativar o serviço para preencher formulários em outras aplicações</string>
|
||||
<string name="password_size_title">Tamanho da palavra-chave gerada</string>
|
||||
<string name="autofill_explanation_summary">Ative o serviço de preencher automático para preencher formulários noutras aplicações</string>
|
||||
<string name="password_size_title">Tamanho da palavra-passe gerada</string>
|
||||
<string name="edit_entry">Editar entrada</string>
|
||||
<string name="encryption">Encriptação</string>
|
||||
<string name="key_derivation_function">Função de derivação de chave</string>
|
||||
<string name="error_autofill_enable_service">Não pôde ser ativado o serviço de preenchimento automático.</string>
|
||||
<string name="error_autofill_enable_service">Não foi possível ativar o serviço de preenchimento automático.</string>
|
||||
<string name="encryption_explanation">Algoritmo de encriptação usado para todos os dados.</string>
|
||||
<string name="password_size_summary">Define o tamanho predefinido para palavras-passe geradas</string>
|
||||
<string name="list_password_generator_options_title">Caracteres da palavra-passe</string>
|
||||
<string name="list_password_generator_options_summary">Definir os caracteres permitodos para o gerador de palavra-passe</string>
|
||||
<string name="password_size_summary">Define o tamanho predefinido para as palavras-passe geradas</string>
|
||||
<string name="list_password_generator_options_title">Caracteres das palavras-passe</string>
|
||||
<string name="list_password_generator_options_summary">Definir os caracteres permitidos para o gerador de palavras-passe</string>
|
||||
<string name="clipboard_notifications_title">Notificações da área de transferência</string>
|
||||
<string name="clipboard_notifications_summary">Mostrar notificações de área de transferência para copiar campos ao visualizar uma entrada</string>
|
||||
<string name="clipboard_notifications_summary">Mostrar notificações da área de transferência para copiar campos ao visualizar uma entrada</string>
|
||||
<string name="lock">Bloquear</string>
|
||||
<string name="lock_database_screen_off_title">Bloqueio de ecrã</string>
|
||||
<string name="lock_database_screen_off_summary">Bloqueie a base de dados quando o ecrã estiver desligado</string>
|
||||
<string name="unavailable_feature_text">Não foi possível iniciar esse recurso.</string>
|
||||
<string name="unavailable_feature_version">O aparelho está a executar Android %1$s, mas precisa de %2$s ou posterior.</string>
|
||||
<string name="lock_database_screen_off_summary">Bloquear a base de dados após alguns segundos após o ecrã estar desligado</string>
|
||||
<string name="unavailable_feature_text">Não foi possível iniciar esta funcionalidade.</string>
|
||||
<string name="unavailable_feature_version">O dispositivo está a usar o Android %1$s, mas precisa do %2$s ou posterior.</string>
|
||||
<string name="unavailable_feature_hardware">Não foi possível encontrar o hardware correspondente.</string>
|
||||
<string name="file_name">Nome do ficheiro</string>
|
||||
<string name="path">Caminho</string>
|
||||
<string name="assign_master_key">Defina uma chave mestre</string>
|
||||
<string name="recycle_bin_title">Usar cesto da reciclagem</string>
|
||||
<string name="recycle_bin_summary">Move grupos e entradas para o \"Cesto da reciclagem\" antes de apagar</string>
|
||||
<string name="monospace_font_fields_enable_title">Fonte do Campo</string>
|
||||
<string name="monospace_font_fields_enable_summary">Muda a fonte usada nos campos para melhor visibilidade dos caracteres</string>
|
||||
<string name="allow_copy_password_title">Confiança da área de transferência</string>
|
||||
<string name="allow_copy_password_summary">Permite copiar a palavra-passe e campos protegidos à área de transferência</string>
|
||||
<string name="assign_master_key">Atribuir uma chave mestra</string>
|
||||
<string name="recycle_bin_title">Utilização do caixote da reciclagem</string>
|
||||
<string name="recycle_bin_summary">Move grupos e entradas para o \"Caixote da reciclagem\" antes de eliminar</string>
|
||||
<string name="monospace_font_fields_enable_title">Tipo de letra nos campos</string>
|
||||
<string name="monospace_font_fields_enable_summary">Muda a fonte tipográfica usada nos campos de dados para melhor visibilidade dos caracteres</string>
|
||||
<string name="allow_copy_password_title">Confiança na área de transferência</string>
|
||||
<string name="allow_copy_password_summary">Permite copiar a palavra-passe e campos protegidos para a área de transferência</string>
|
||||
<string name="database_name_title">Nome da base de dados</string>
|
||||
<string name="database_description_title">Descrição da base de dados</string>
|
||||
<string name="database_version_title">Versão da base de dados</string>
|
||||
<string name="text_appearance">Texto</string>
|
||||
<string name="application_appearance">App</string>
|
||||
<string name="application_appearance">Interface</string>
|
||||
<string name="other">Outros</string>
|
||||
<string name="keyboard">Teclado</string>
|
||||
<string name="magic_keyboard_title">Magikeyboard</string>
|
||||
<string name="magic_keyboard_explanation_summary">Ative um teclado customizado, populando suas palavras-passe e todos os campos de identidade</string>
|
||||
<string name="reset_education_screens_title">Reiniciar dicas educacionais</string>
|
||||
<string name="reset_education_screens_summary">Exibir todas as informações educacionais novamente</string>
|
||||
<string name="reset_education_screens_text">Dicas educacionais redefinidas</string>
|
||||
<string name="education_create_database_title">Crie um ficheiro de base de dados</string>
|
||||
<string name="magic_keyboard_explanation_summary">Ative um teclado personalizado para as suas palavras-passe e todos os campos de identidade</string>
|
||||
<string name="reset_education_screens_title">Reiniciar as dicas</string>
|
||||
<string name="reset_education_screens_summary">Mostrar todas as dicas novamente</string>
|
||||
<string name="reset_education_screens_text">Dicas repostas</string>
|
||||
<string name="education_create_database_title">Criar um ficheiro da base de dados</string>
|
||||
<string name="education_create_database_summary">Crie o seu primeiro ficheiro de gestão de palavras-passe.</string>
|
||||
<string name="education_select_database_title">Abra uma base de dados existente</string>
|
||||
<string name="education_select_database_summary">Abra a sua base de dados de mais cedo pelo seu navegador de ficheiros.</string>
|
||||
<string name="education_new_node_title">Adicione itens ao seu banco</string>
|
||||
<string name="education_new_node_summary">Entradas ajudam a gerir as suas identidades digitais.
|
||||
\n
|
||||
\nGrupos (~pastas) organizam as suas entradas na sua base de dados.</string>
|
||||
<string name="education_search_title">Pesquise suas entradas</string>
|
||||
<string name="education_search_summary">Entre com título, nome de utilizador ou outros campos para recuperar facilmente as suas palavras-passe.</string>
|
||||
<string name="education_entry_edit_title">Modifique a entrada</string>
|
||||
<string name="education_select_database_title">Abrir uma base de dados existente</string>
|
||||
<string name="education_select_database_summary">Abra a sua base de dados anterior no navegador de ficheiros para continuar a usá-la.</string>
|
||||
<string name="education_new_node_title">Adicionar itens à base de dados</string>
|
||||
<string name="education_new_node_summary">As entradas ajudam a gerir as suas identidades digitais.
|
||||
\n
|
||||
\nOs grupos (~pastas) organizam as suas entradas na base de dados.</string>
|
||||
<string name="education_search_title">Pesquisar nas entradas</string>
|
||||
<string name="education_search_summary">Digite o título, nome de utilizador ou outros campos para recuperar facilmente as suas palavras-passe.</string>
|
||||
<string name="education_entry_edit_title">Editar a entrada</string>
|
||||
<string name="education_entry_edit_summary">Edite a sua entrada com campos personalizados. Os conjuntos de dados podem ser referenciados entre campos de entradas diferentes.</string>
|
||||
<string name="education_generate_password_title">Crie uma palavra-passe forte</string>
|
||||
<string name="education_generate_password_summary">Gere uma palavra-passe forte para associar a sua entrada, defina-a facilmente de acordo com os critérios do formulário e não se esqueça de torná-la segura.</string>
|
||||
<string name="education_entry_new_field_title">Adicione campos customizados</string>
|
||||
<string name="education_entry_new_field_summary">Registe um campo adicional, acrescente um valor e proteja-o opcionalmente.</string>
|
||||
<string name="education_unlock_title">Desbloqueie a sua base de dados</string>
|
||||
<string name="education_generate_password_title">Criar uma palavra-passe forte</string>
|
||||
<string name="education_generate_password_summary">Crie uma palavra-passe forte para associar à sua entrada, defina-a facilmente de acordo com os critérios do formulário e não se esqueça de torná-la segura.</string>
|
||||
<string name="education_entry_new_field_title">Adicionar campos personalizados</string>
|
||||
<string name="education_entry_new_field_summary">Registe um campo adicional, adicione um valor e proteja-o opcionalmente.</string>
|
||||
<string name="education_unlock_title">Desbloquear a base de dados</string>
|
||||
<string name="education_field_copy_title">Copiar um campo</string>
|
||||
<string name="education_field_copy_summary">Campos copiados podem ser colados em qualquer lugar.
|
||||
\n
|
||||
\nUse a forma de preenchimento de formulário que preferir.</string>
|
||||
<string name="education_lock_title">Bloqueie a base de dados</string>
|
||||
<string name="education_lock_summary">Bloqueie a sua base de dados rapidamente, pode parametrizar a app para bloqueá-lo depois de um tempo, e quando o ecrã se apaga.</string>
|
||||
<string name="education_field_copy_summary">Os campos copiados podem ser colados em qualquer lugar.
|
||||
\n
|
||||
\nUse o método de preenchimento de formulário que preferir.</string>
|
||||
<string name="education_lock_title">Bloquear a base de dados</string>
|
||||
<string name="education_lock_summary">Bloqueie a sua base de dados rapidamente. Pode configurar a aplicação para bloqueá-la após um tempo e quando o ecrã se desliga.</string>
|
||||
<string name="education_sort_title">Ordenação de itens</string>
|
||||
<string name="education_sort_summary">Escolha como entradas e grupos são ordenadas.</string>
|
||||
<string name="education_sort_summary">Escolha como são ordenadas as entradas e os grupos.</string>
|
||||
<string name="education_donation_title">Participar</string>
|
||||
<string name="education_donation_summary">Ajude a aumentar a estabilidade, segurança e na adição de mais recursos.</string>
|
||||
<string name="html_text_ad_free">Ao contrário de muitas apps de gestão de palavras-passe, esta app é <strong>livre de anúncios</strong>, é <strong>software livre copyleft</strong> e não coleta dados pessoais nos servidores dela, mesmo na sua versão gratuita.</string>
|
||||
<string name="html_text_buy_pro">Ao comprar a versão pro, terá acesso a este <strong>recurso visual</strong> e ajudará especialmente a <strong>realizar projetos comunitários.</strong></string>
|
||||
<string name="education_donation_summary">Ajude a aumentar a estabilidade, segurança e novas funcionalidades.</string>
|
||||
<string name="html_text_ad_free">Ao contrário de muitas aplicações de gestão de palavras-passe, esta aplicação <strong>não tem anúncios</strong>, é <strong>um programa de código-fonte livre</strong> e não recolhe dados pessoais para os servidores dela, seja qual for a versão que utiliza.</string>
|
||||
<string name="html_text_buy_pro">Ao comprar a versão pro, terá acesso a este <strong>estilo visual</strong> e ajudará especialmente a <strong>realizar projetos comunitários.</strong></string>
|
||||
<string name="html_text_feature_generosity">Este <strong>estilo visual</strong> está disponível graças à sua generosidade.</string>
|
||||
<string name="html_text_donation">Para manter a nossa liberdade e estarmos sempre ativos, nós contamos com a sua <strong>contribuição.</strong>
|
||||
</string>
|
||||
<string name="html_text_dev_feature">Esse recurso está <strong>em desenvolvimento</strong> e exige que sua <strong>contribuição</strong> para que esteja disponível em breve.</string>
|
||||
<string name="html_text_donation">Para manter a nossa liberdade e estarmos sempre ativos, contamos com a sua <strong>contribuição.</strong></string>
|
||||
<string name="html_text_dev_feature">Esta funcionalidade está <strong>em desenvolvimento</strong> e necessita da sua <strong>contribuição</strong> para que esteja disponível brevemente.</string>
|
||||
<string name="html_text_dev_feature_buy_pro">Ao comprar a versão <strong>pro</strong>,</string>
|
||||
<string name="html_text_dev_feature_contibute">
|
||||
<strong>Contribuindo </strong>,</string>
|
||||
<string name="html_text_dev_feature_encourage">está a incentivar os programadores a criar <strong>novos recursos</strong> e a <strong>corrigir erros </strong> de acordo com as suas observações.</string>
|
||||
<string name="html_text_dev_feature_thanks">Obrigado por sua contribuição.</string>
|
||||
<string name="html_text_dev_feature_work_hard">Estamos trabalhando duro para lançar esse recurso o mais rápido possível.</string>
|
||||
<string name="html_text_dev_feature_upgrade">Lembre-se de manter o sua app atualizada, instalando novas versões.</string>
|
||||
<string name="html_text_dev_feature_contibute">Ao <strong>contribuir</strong>,</string>
|
||||
<string name="html_text_dev_feature_encourage">está a incentivar os programadores a adicionar <strong>novas funcionalidades</strong> e a <strong>corrigir erros</strong> reportados pelos utilizadores.</string>
|
||||
<string name="html_text_dev_feature_thanks">Obrigado pela sua contribuição.</string>
|
||||
<string name="html_text_dev_feature_work_hard">Estamos a trabalhar para lançar esta funcionalidade o mais rápido possível.</string>
|
||||
<string name="html_text_dev_feature_upgrade">Lembre-se de manter a sua aplicação atualizada, instalando novas versões.</string>
|
||||
<string name="download">Descarregar</string>
|
||||
<string name="contribute">Contribuir</string>
|
||||
<string name="style_choose_title">Tema da app</string>
|
||||
<string name="style_choose_summary">Tema usado na app</string>
|
||||
<string name="style_choose_title">Tema da aplicação</string>
|
||||
<string name="style_choose_summary">Tema usado na aplicação</string>
|
||||
<string name="icon_pack_choose_title">Pacote de ícones</string>
|
||||
<string name="icon_pack_choose_summary">Pacote de ícones usado na app</string>
|
||||
<string name="clipboard_warning">Se a limpeza da área de transferência falhar, limpe seu histórico manualmente.</string>
|
||||
<string name="allow_copy_password_warning">Aviso: A área de transferência é compartilhada por todas as apps. Se dados sensíveis forem copiados, outros programas podem recuperá-lo.</string>
|
||||
<string name="icon_pack_choose_summary">Pacote de ícones usado na aplicação</string>
|
||||
<string name="clipboard_warning">Se a limpeza da área de transferência falhar, limpe o histórico desta manualmente.</string>
|
||||
<string name="allow_copy_password_warning">Aviso: a área de transferência é partilhada por todas as aplicações. Se forem copiados dados sensíveis, os outros programas podem ler esses dados.</string>
|
||||
<string name="allow_no_password_title">Não permitir chave mestra</string>
|
||||
<string name="allow_no_password_summary">Permite tocar no botão \"Abrir\" se nenhumas credenciais estiverem selecionadas</string>
|
||||
<string name="allow_no_password_summary">Permite tocar no botão \"Abrir\" se não estiverem selecionadas nenhumas credenciais</string>
|
||||
<string name="enable_education_screens_title">Dicas educacionais</string>
|
||||
<string name="enable_education_screens_summary">Destacar elementos para aprender como a app funciona</string>
|
||||
<string name="enable_education_screens_summary">Destacar elementos para saber como a aplicação funciona</string>
|
||||
<string name="enable_read_only_title">Apenas leitura</string>
|
||||
<string name="enable_read_only_summary">Abrir a base de dados somente leitura por defeito</string>
|
||||
<string name="education_read_only_title">Proteja seu banco de modificações</string>
|
||||
<string name="education_read_only_summary">Altere o modo de abertura para a sessão.
|
||||
\n
|
||||
\n\"Somente leitura\" evita que faça alterações não intencionais na base de dados.
|
||||
\n\"Gravação\" permite-o adicionar, apagar ou modificar todos os elementos.</string>
|
||||
<string name="enable_read_only_summary">Abrir a base de dados com permissão de apenas leitura por predefinição</string>
|
||||
<string name="education_read_only_title">Proteger a base de dados contra alterações</string>
|
||||
<string name="education_read_only_summary">Altere o modo de abertura para a sessão.
|
||||
\n
|
||||
\n\"Apenas leitura\" evita que faça alterações não intencionais na base de dados.
|
||||
\n\"Alterável\" permite adicionar, eliminar ou alterar todos os elementos.</string>
|
||||
<string name="list_entries_show_username_summary">Mostrar nomes de utilizador na lista entradas</string>
|
||||
<string name="clipboard">Área de transferência</string>
|
||||
<string name="keyboard_name">Magikeyboard</string>
|
||||
@@ -296,31 +294,31 @@
|
||||
<string name="keyboard_notification_entry_content_title">%1$s disponível no Magikeyboard</string>
|
||||
<string name="keyboard_notification_entry_content_text">%1$s</string>
|
||||
<string name="keyboard_notification_entry_clear_close_title">Limpar ao fechar</string>
|
||||
<string name="keyboard_notification_entry_clear_close_summary">Fecha a base de dados ao dispensar a notificação</string>
|
||||
<string name="keyboard_notification_entry_clear_close_summary">Fecha a base de dados ao fechar a notificação</string>
|
||||
<string name="keyboard_appearance_category">Aparência</string>
|
||||
<string name="keyboard_theme_title">Tema do teclado</string>
|
||||
<string name="keyboard_keys_category">Teclas</string>
|
||||
<string name="keyboard_key_vibrate_title">Pressão de chaves vibratórias</string>
|
||||
<string name="keyboard_key_vibrate_title">Vibrar ao pressionar teclas</string>
|
||||
<string name="keyboard_key_sound_title">Som ao pressionar teclas</string>
|
||||
<string name="selection_mode">Modo de seleção</string>
|
||||
<string name="do_not_kill_app">Não mate a app…</string>
|
||||
<string name="do_not_kill_app">Não feche a aplicação…</string>
|
||||
<string name="lock_database_back_root_title">Pressione \'Voltar\' para bloquear</string>
|
||||
<string name="lock_database_back_root_summary">Tranca a base de dados quando o utilizador pressiona o botão voltar no ecrã inicial</string>
|
||||
<string name="clear_clipboard_notification_title">Limpar ao fechar</string>
|
||||
<string name="clear_clipboard_notification_summary">Bloquear a base de dados quando a duração da área de transferência expirar ou quando a notificação for fechada depois de começar a utilizá-la</string>
|
||||
<string name="recycle_bin">Cesto da reciclagem</string>
|
||||
<string name="recycle_bin">Caixote da reciclagem</string>
|
||||
<string name="keyboard_selection_entry_title">Seleção de entrada</string>
|
||||
<string name="keyboard_selection_entry_summary">Mostrar campos de entrada no Magikeyboard quando estiver visualizando uma Entrada</string>
|
||||
<string name="delete_entered_password_title">Deletar palavra-passe</string>
|
||||
<string name="delete_entered_password_summary">Apaga a palavra-passe inserida após uma tentativa de conexão</string>
|
||||
<string name="keyboard_selection_entry_summary">Ao ver uma entrada no KeePassDX, preencher o Magikeyboard com essa entrada</string>
|
||||
<string name="delete_entered_password_title">Eliminar palavra-passe</string>
|
||||
<string name="delete_entered_password_summary">Eliminar a palavra-passe inserida após uma tentativa de conexão a uma base de dados</string>
|
||||
<string name="content_description_open_file">Abrir ficheiro</string>
|
||||
<string name="content_description_node_children">Crianças do nó</string>
|
||||
<string name="content_description_add_node">Inserir nó</string>
|
||||
<string name="content_description_node_children">Nó filho</string>
|
||||
<string name="content_description_add_node">Adicionar nó</string>
|
||||
<string name="content_description_add_entry">Adicionar entrada</string>
|
||||
<string name="content_description_add_group">Adicionar grupo</string>
|
||||
<string name="content_description_file_information">Informações sobre ficheiro</string>
|
||||
<string name="content_description_password_checkbox">Caixa de seleção da palavra-passe</string>
|
||||
<string name="content_description_keyfile_checkbox">Caixa de seleção keyfile</string>
|
||||
<string name="content_description_keyfile_checkbox">Caixa de seleção do ficheiro-chave</string>
|
||||
<string name="content_description_repeat_toggle_password_visibility">Repetir alternar a visibilidade da palavra-passe</string>
|
||||
<string name="content_description_entry_icon">Ícone da entrada</string>
|
||||
<string name="entry_password_generator">Gerador de palavras-passe</string>
|
||||
@@ -328,30 +326,30 @@
|
||||
<string name="entry_add_field">Adicionar campo</string>
|
||||
<string name="content_description_remove_field">Remover campo</string>
|
||||
<string name="entry_UUID">UUID</string>
|
||||
<string name="error_move_entry_here">Não pode mover uma entrada para cá.</string>
|
||||
<string name="error_copy_entry_here">Não pode copiar uma entrada aqui.</string>
|
||||
<string name="error_move_entry_here">Não se pode mover uma entrada para aqui.</string>
|
||||
<string name="error_copy_entry_here">Não se pode copiar uma entrada aqui.</string>
|
||||
<string name="list_groups_show_number_entries_title">Mostrar número de entradas</string>
|
||||
<string name="list_groups_show_number_entries_summary">Mostrar o número de entradas dentro de um grupo</string>
|
||||
<string name="database_custom_color_title">Cor personalizada da base de dados</string>
|
||||
<string name="database_data_compression_summary">A compressão de dados reduz o tamanho da base de dados</string>
|
||||
<string name="biometric_unlock_enable_summary">Permite que escaneie o seu biométrico para abrir a base de dados</string>
|
||||
<string name="advanced_unlock_explanation_summary">Usar desbloqueamento avançado para abrir a base de dados mais facilmente</string>
|
||||
<string name="biometric_unlock_enable_summary">Permite que leia os seus dados biométricos para abrir a base de dados</string>
|
||||
<string name="advanced_unlock_explanation_summary">Usar desbloqueio avançado para abrir a base de dados mais facilmente</string>
|
||||
<string name="database_opened">Base de dados aberta</string>
|
||||
<string name="contains_duplicate_uuid">A base de dados contém UUIDs duplicados.</string>
|
||||
<string name="menu_save_database">Gravar base de dados</string>
|
||||
<string name="menu_save_database">Guardar base de dados</string>
|
||||
<string name="creating_database">A criar a base de dados…</string>
|
||||
<string name="error_save_database">Não foi possível gravar a base de dados.</string>
|
||||
<string name="error_create_database_file">Impossível de criar uma base de dados com essa palavra-passe e ficheiro-chave.</string>
|
||||
<string name="error_label_exists">Este rótulo já existe.</string>
|
||||
<string name="autofill_block_restart">Reinicie a app que contém o formulário para ativar o bloqueio.</string>
|
||||
<string name="error_save_database">Não foi possível guardar a base de dados.</string>
|
||||
<string name="error_create_database_file">Não foi possível criar a base de dados com essa palavra-passe e ficheiro-chave.</string>
|
||||
<string name="error_label_exists">Esta etiqueta já existe.</string>
|
||||
<string name="autofill_block_restart">Reinicie a aplicação que contém o formulário para ativar o bloqueio.</string>
|
||||
<string name="autofill_block">Bloquear preenchimento automático</string>
|
||||
<string name="autofill_web_domain_blocklist_summary">Lista de bloqueio que impede o preenchimento automático de domínios da web</string>
|
||||
<string name="autofill_web_domain_blocklist_title">Lista de bloqueio de domínio da web</string>
|
||||
<string name="autofill_application_id_blocklist_summary">Lista de bloqueio que impede o preenchimento automático de apps</string>
|
||||
<string name="autofill_web_domain_blocklist_summary">Lista de domínios da web bloqueados sem permissão de preenchimento automático</string>
|
||||
<string name="autofill_web_domain_blocklist_title">Lista de bloqueio de domínios da web</string>
|
||||
<string name="autofill_application_id_blocklist_summary">Lista de aplicações bloqueadas sem permissão de preenchimento automático</string>
|
||||
<string name="autofill_application_id_blocklist_title">Lista de bloqueio de aplicações</string>
|
||||
<string name="autofill_auto_search_summary">Sugerir resultados de pesquisa automaticamente do domínio da web ou do ID da aplicação</string>
|
||||
<string name="keyboard_previous_fill_in_summary">Voltar automaticamente para o teclado anterior depois de executar a ação da tecla automática</string>
|
||||
<string name="keyboard_previous_fill_in_title">Ação de tecla automática</string>
|
||||
<string name="keyboard_previous_fill_in_summary">Mudar automaticamente para o teclado anterior depois de executar a \"tecla automática\"</string>
|
||||
<string name="keyboard_previous_fill_in_title">Ação da tecla automática</string>
|
||||
<string name="keyboard_previous_database_credentials_summary">Voltar automaticamente para o teclado anterior no ecrã de credenciais da base de dados</string>
|
||||
<string name="keyboard_previous_database_credentials_title">Ecrã de credenciais da base de dados</string>
|
||||
<string name="keyboard_change">Mudar de teclado</string>
|
||||
@@ -361,145 +359,245 @@
|
||||
<string name="subdomain_search_title">Pesquisa de subdomínios</string>
|
||||
<string name="error_string_type">Este texto não corresponde ao item solicitado.</string>
|
||||
<string name="content_description_add_item">Adicionar item</string>
|
||||
<string name="error_otp_digits">O token deve conter de %1$d até %2$d dígitos.</string>
|
||||
<string name="error_otp_digits">O token tem de ter entre %1$d e %2$d dígitos.</string>
|
||||
<string name="max_history_items_title">Número máximo</string>
|
||||
<string name="warning_permanently_delete_nodes">Apagar permanentemente os nós selecionados\?</string>
|
||||
<string name="warning_permanently_delete_nodes">Eliminar permanentemente os nós selecionados\?</string>
|
||||
<string name="max_history_size_title">Tamanho máximo</string>
|
||||
<string name="recycle_bin_group_title">Grupo de cesto da reciclagem</string>
|
||||
<string name="recycle_bin_group_title">Grupo do caixote da reciclagem</string>
|
||||
<string name="otp_secret">Segredo</string>
|
||||
<string name="keyboard_auto_go_action_summary">Ação da tecla \"Go\" após pressionar a tecla \"Field\"</string>
|
||||
<string name="keyboard_auto_go_action_summary">Ação da tecla \"Ir\" após pressionar a tecla \"Campo\"</string>
|
||||
<string name="otp_type">Tipo do OTP</string>
|
||||
<string name="entry_add_attachment">Adicionar anexo</string>
|
||||
<string name="education_setup_OTP_title">Configurar OTP</string>
|
||||
<string name="education_setup_OTP_title">Configurar o OTP</string>
|
||||
<string name="compression">Compressão</string>
|
||||
<string name="validate">Validação</string>
|
||||
<string name="remember_keyfile_locations_summary">Mantém o controle sobre onde os ficheiros de chaves são armazenados</string>
|
||||
<string name="validate">Validar</string>
|
||||
<string name="remember_keyfile_locations_summary">Mantém um registo dos locais onde os ficheiros-chave são armazenados</string>
|
||||
<string name="entry_history">Histórico</string>
|
||||
<string name="error_otp_period">O período deve estar entre %1$d e %2$d segundos.</string>
|
||||
<string name="master_key">Chave Mestre</string>
|
||||
<string name="settings_database_recommend_changing_master_key_summary">Recomendar mudança da chave mestre (em dias)</string>
|
||||
<string name="error_otp_period">O período tem de estar entre %1$d e %2$d segundos.</string>
|
||||
<string name="master_key">Chave mestra</string>
|
||||
<string name="settings_database_recommend_changing_master_key_summary">Recomendar alteração da chave mestra (em dias)</string>
|
||||
<string name="remember_database_locations_title">Lembrar locais das bases de dados</string>
|
||||
<string name="download_initialization">A inicializar…</string>
|
||||
<string name="menu_security_settings">Configurações de segurança</string>
|
||||
<string name="disable">Desativar</string>
|
||||
<string name="lock_database_show_button_summary">Mostrar o botão de bloqueio na interface do utilizador</string>
|
||||
<string name="lock_database_show_button_summary">Mostrar o botão de bloqeuar na interface do utilizador</string>
|
||||
<string name="max_history_size_summary">Limitar o tamanho do histórico por entrada</string>
|
||||
<string name="error_otp_secret_key">A chave secreta deve estar em formato Base32.</string>
|
||||
<string name="error_otp_secret_key">A chave secreta tem de ser no formato Base32.</string>
|
||||
<string name="enable">Ativar</string>
|
||||
<string name="database_data_compression_title">Compressão dos dados</string>
|
||||
<string name="html_about_contribution">Para <strong>manter a liberdade</strong>, <strong>solucionar bugs</strong>, <strong>adicionar funções</strong> e <strong>para sermos sempre ativoa</strong>, contamos com sua <strong>contribuição</strong>.</string>
|
||||
<string name="biometric_unlock_enable_title">Desbloqueio por biométrico</string>
|
||||
<string name="database_data_compression_title">Compressão de dados</string>
|
||||
<string name="html_about_contribution">Para <strong>manter a liberdade</strong>, <strong>corrigir erros</strong>, <strong>adicionar funcionalidades</strong> e <strong>para sermos sempre ativos</strong>, contamos com sua <strong>contribuição</strong>.</string>
|
||||
<string name="biometric_unlock_enable_title">Desbloqueio biométrico</string>
|
||||
<string name="entry_attachments">Anexos</string>
|
||||
<string name="compression_gzip">Gzip</string>
|
||||
<string name="discard">Descartar</string>
|
||||
<string name="remember_database_locations_summary">Mantém o controle sobre onde os bancos de dados são armazenados</string>
|
||||
<string name="remember_database_locations_summary">Mantém um registo dos locais onde as bases de dados são armazenadas</string>
|
||||
<string name="auto_focus_search_summary">Solicitar uma pesquisa quando abrir a base de dados</string>
|
||||
<string name="show_recent_files_summary">Lembrar nomes recentes de ficheiros</string>
|
||||
<string name="show_recent_files_summary">Mostrar localizações de bases de dados recentes</string>
|
||||
<string name="download_finalization">A finalizar…</string>
|
||||
<string name="autofill_preference_title">Configurações de preenchimento automático</string>
|
||||
<string name="max_history_items_summary">Limitar a quantidade de itens do histórico por entrada</string>
|
||||
<string name="max_history_items_summary">Limitar a quantidade de itens no histórico por entrada</string>
|
||||
<string name="download_complete">Completo!</string>
|
||||
<string name="content_description_update_from_list">Atualizar</string>
|
||||
<string name="contribution">Contribuição</string>
|
||||
<string name="hide_broken_locations_summary">Esconder ligações quebradas na lista de bases de dados recentes</string>
|
||||
<string name="hide_broken_locations_summary">Ocultar ligações quebradas na lista de bases de dados recentes</string>
|
||||
<string name="download_attachment">Descarregar %1$s</string>
|
||||
<string name="warning_database_read_only">Conceder acesso de gravação de ficheiro para gravar alterações na base de dados</string>
|
||||
<string name="clipboard_explanation_summary">Copiar campos de entrada usando a área de transferência do seu aparelho</string>
|
||||
<string name="warning_database_read_only">Conceda o acesso de gravação de ficheiros para guardar as alterações na base de dados</string>
|
||||
<string name="clipboard_explanation_summary">Copiar campos de entrada usando a área de transferência do seu dispositivo</string>
|
||||
<string name="otp_digits">Dígitos</string>
|
||||
<string name="discard_changes">Descartar alterações\?</string>
|
||||
<string name="keystore_not_accessible">A chave não foi propriamente inicializada.</string>
|
||||
<string name="keystore_not_accessible">O armazém de chaves não foi propriamente inicializado.</string>
|
||||
<string name="auto_focus_search_title">Pesquisa rápida</string>
|
||||
<string name="biometric_delete_all_key_title">Apague chaves de encriptação</string>
|
||||
<string name="biometric_delete_all_key_title">Eliminar chaves de encriptação</string>
|
||||
<string name="invalid_db_same_uuid">%1$s com o mesmo UUID %2$s já existe.</string>
|
||||
<string name="autofill_auto_search_title">Pesquisa automática</string>
|
||||
<string name="settings_database_force_changing_master_key_summary">Forçar mudança de chave-mestre (em dias)</string>
|
||||
<string name="settings_database_force_changing_master_key_summary">Forçar alteração da chave mestra (em dias)</string>
|
||||
<string name="command_execution">A executar o comando…</string>
|
||||
<string name="otp_algorithm">Algorítimo</string>
|
||||
<string name="show_recent_files_title">Histórico de ficheiros recentes</string>
|
||||
<string name="show_recent_files_title">Mostrar ficheiros recentes</string>
|
||||
<string name="content_description_background">Plano de fundo</string>
|
||||
<string name="lock_database_show_button_title">Mostrar botão de bloqueio</string>
|
||||
<string name="lock_database_show_button_title">Mostrar botão de bloquear</string>
|
||||
<string name="security">Segurança</string>
|
||||
<string name="hide_broken_locations_title">Esconder ligações quebradas de bases de dados</string>
|
||||
<string name="hide_broken_locations_title">Ocultar ligações quebradas de bases de dados</string>
|
||||
<string name="content_description_keyboard_close_fields">Fechar campos</string>
|
||||
<string name="biometric">Biométrico</string>
|
||||
<string name="error_create_database">Incapaz de criar o ficheiro de base de dados.</string>
|
||||
<string name="keyboard_search_share_summary">Procurar automaticamente pela informação compartilhada para popular o teclado</string>
|
||||
<string name="error_otp_counter">O contador deve estar entre %1$d e %2$d.</string>
|
||||
<string name="error_create_database">Não foi possível criar o ficheiro da base de dados.</string>
|
||||
<string name="keyboard_search_share_summary">Ao partilhar um URL com o KeePassDX, filtrar as entradas usando esse domínio de URL</string>
|
||||
<string name="error_otp_counter">O contador tem de estar entre %1$d e %2$d.</string>
|
||||
<string name="otp_period">Período (segundos)</string>
|
||||
<string name="device_keyboard_setting_title">Configurações do teclado do aparelho</string>
|
||||
<string name="biometric_delete_all_key_summary">Apague todas as chaves de encriptação relacionadas ao reconhecimento de biométrico</string>
|
||||
<string name="biometric_auto_open_prompt_summary">Pedir pelo biométrico automaticamente se a base de dados estiver configurada para usá-la</string>
|
||||
<string name="warning_database_link_revoked">Acesso ao ficheiro revogado pelo gestor de ficheiros</string>
|
||||
<string name="device_keyboard_setting_title">Configurações do teclado do dispositivo</string>
|
||||
<string name="biometric_delete_all_key_summary">Eliminar todas as chaves de encriptação relacionadas com o desbloqueio de reconhecimento avançado</string>
|
||||
<string name="biometric_auto_open_prompt_summary">Pedir automaticamente o desbloqueio avançado se a base de dados estiver configurada para usá-lo</string>
|
||||
<string name="warning_database_link_revoked">O acesso ao ficheiro foi revogado pelo gestor de ficheiros</string>
|
||||
<string name="error_invalid_OTP">Segredo OTP inválido.</string>
|
||||
<string name="contact">Contato</string>
|
||||
<string name="contact">Contacto</string>
|
||||
<string name="otp_counter">Contador</string>
|
||||
<string name="menu_restore_entry_history">Restaurar histórico</string>
|
||||
<string name="entry_otp">OTP</string>
|
||||
<string name="compression_none">Nenhum</string>
|
||||
<string name="enable_auto_save_database_summary">Gravar a base de dados automaticamente depois de uma ação importante (somente no modo \"Modificável\")</string>
|
||||
<string name="error_copy_group_here">Não pode copiar um grupo aqui.</string>
|
||||
<string name="menu_delete_entry_history">Apagar histórico</string>
|
||||
<string name="error_disallow_no_credentials">Ao menos uma credencial deve ser definida.</string>
|
||||
<string name="compression_none">Nenhuma</string>
|
||||
<string name="enable_auto_save_database_summary">Guardar a base de dados automaticamente depois de uma ação importante (apenas no modo \"Alterável\")</string>
|
||||
<string name="error_copy_group_here">Não se pode copiar um grupo aqui.</string>
|
||||
<string name="menu_delete_entry_history">Eliminar histórico</string>
|
||||
<string name="error_disallow_no_credentials">Tem de ser definida pelo menos uma credencial.</string>
|
||||
<string name="settings_database_force_changing_master_key_title">Forçar renovação</string>
|
||||
<string name="enable_auto_save_database_title">Gravar a base de dados automaticamente</string>
|
||||
<string name="keyboard_auto_go_action_title">Ação de chave automática</string>
|
||||
<string name="enable_auto_save_database_title">Guardar automaticamente a base de dados</string>
|
||||
<string name="keyboard_auto_go_action_title">Ação de tecla automática</string>
|
||||
<string name="hide_expired_entries_title">Ocultar entradas expiradas</string>
|
||||
<string name="hide_expired_entries_summary">As entradas expiradas não são mostradas</string>
|
||||
<string name="menu_master_key_settings">Configurações da chave-mestre</string>
|
||||
<string name="entry_setup_otp">Configurar OTP</string>
|
||||
<string name="keyboard_search_share_title">Procurar informação compartilhada</string>
|
||||
<string name="menu_empty_recycle_bin">Esvaziar cesto da reciclagem</string>
|
||||
<string name="settings_database_force_changing_master_key_next_time_summary">Forçar mudança da chave-mestre na próxima vez (uma vez)</string>
|
||||
<string name="contains_duplicate_uuid_procedure">Consertar o problema gerando novas UUIDs para duplicatas para continuar\?</string>
|
||||
<string name="menu_master_key_settings">Configurações da chave mestra</string>
|
||||
<string name="entry_setup_otp">Configurar palavra-passe de uso único</string>
|
||||
<string name="keyboard_search_share_title">Procurar informação partilhada</string>
|
||||
<string name="menu_empty_recycle_bin">Esvaziar caixote da reciclagem</string>
|
||||
<string name="settings_database_force_changing_master_key_next_time_summary">Forçar alteração da chave mestra na próxima vez (uma vez)</string>
|
||||
<string name="contains_duplicate_uuid_procedure">Resolver o problema gerando novas UUIDs para os duplicados para continuar\?</string>
|
||||
<string name="settings_database_force_changing_master_key_next_time_title">Forçar renovação na próxima vez</string>
|
||||
<string name="menu_advanced_unlock_settings">Desbloqueio avançado</string>
|
||||
<string name="education_setup_OTP_summary">Configurar a gestão de palavra-passe única (HOTP / TOTP) para gerar um token solicitado para autenticação de dois fatores (2FA).</string>
|
||||
<string name="remember_keyfile_locations_title">Lembrar locais de ficheiros-chave</string>
|
||||
<string name="education_setup_OTP_summary">Configure a gestão de palavra-passe única (HOTP / TOTP) para gerar um token solicitado para autenticação de dois fatores (2FA).</string>
|
||||
<string name="remember_keyfile_locations_title">Lembrar locais dos ficheiros-chave</string>
|
||||
<string name="download_progression">Em progresso: %1$d%%</string>
|
||||
<string name="biometric_auto_open_prompt_title">Abrir automaticamente o escaneamento de biomẽtrico</string>
|
||||
<string name="biometric_auto_open_prompt_title">Abrir automaticamente o leitor</string>
|
||||
<string name="advanced_unlock">Desbloqueio avançado</string>
|
||||
<string name="settings_database_recommend_changing_master_key_title">Renovação recomendada</string>
|
||||
<string name="upload_attachment">Enviar %1$s</string>
|
||||
<string name="education_add_attachment_summary">Envie um anexo à sua entrada para gravar dados externos importantes.</string>
|
||||
<string name="education_add_attachment_title">Adicionar anexo</string>
|
||||
<string name="education_add_attachment_summary">Envie um anexo para a sua entrada para guardar dados externos importantes.</string>
|
||||
<string name="education_add_attachment_title">Adicionar um anexo</string>
|
||||
<string name="database_data_remove_unlinked_attachments_summary">Remove anexos contidos na base de dados, mas não ligados a uma entrada</string>
|
||||
<string name="database_data_remove_unlinked_attachments_title">Remover dados não ligados</string>
|
||||
<string name="data">Dados</string>
|
||||
<string name="warning_empty_keyfile_explanation">O conteúdo do ficheiro-chave nunca deve ser alterado e, no melhor dos casos, deve conter dados gerados aleatoriamente.</string>
|
||||
<string name="warning_empty_keyfile">Não é recomendável adicionar um ficheiro de chave vazio.</string>
|
||||
<string name="warning_sure_remove_data">Remover esses dados mesmo assim\?</string>
|
||||
<string name="warning_remove_unlinked_attachment">Remover dados não ligados pode diminuir o tamanho da sua base de dados, mas também pode apagar dados utilizados para os plugins do KeePass.</string>
|
||||
<string name="warning_empty_keyfile">Não é recomendável adicionar um ficheiro-chave vazio.</string>
|
||||
<string name="warning_sure_remove_data">Remover estes dados mesmo assim\?</string>
|
||||
<string name="warning_remove_unlinked_attachment">Remover dados não ligados pode diminuir o tamanho da sua base de dados, mas também pode eliminar dados utilizados para os plug-ins do KeePass.</string>
|
||||
<string name="warning_sure_add_file">Adicionar o ficheiro mesmo assim\?</string>
|
||||
<string name="warning_replace_file">Enviar deste ficheiro substituirá o existente.</string>
|
||||
<string name="warning_file_too_big">Uma base de dados KeePass deve conter apenas pequenos ficheiros utilitários (tais como ficheiros chave PGP).
|
||||
<string name="warning_replace_file">Este ficheiro enviado substituirá o existente.</string>
|
||||
<string name="warning_file_too_big">Uma base de dados KeePass deve conter apenas pequenos ficheiros utilitários (tais como ficheiros-chave PGP).
|
||||
\n
|
||||
\nA sua base de dados pode se tornar muito grande e reduzir o desempenho com este envio.</string>
|
||||
\nA sua base de dados pode-se tornar muito grande e reduzir o desempenho com este envio.</string>
|
||||
<string name="content_description_credentials_information">Informações sobre credenciais</string>
|
||||
<string name="device_credential">Credencial do dispositivo</string>
|
||||
<string name="credential_before_click_advanced_unlock_button">Digite a palavra-chave, e depois clique no botão \"Desbloqueio avançado\".</string>
|
||||
<string name="advanced_unlock_prompt_not_initialized">Incapaz de inicializar o desbloqueio antecipado.</string>
|
||||
<string name="credential_before_click_advanced_unlock_button">Digite a palavra-passe e depois clique neste botão.</string>
|
||||
<string name="advanced_unlock_prompt_not_initialized">Não foi possível inicializar o desbloqueio avançado.</string>
|
||||
<string name="advanced_unlock_scanning_error">Erro de desbloqueio avançado: %1$s</string>
|
||||
<string name="advanced_unlock_not_recognized">Não conseguia reconhecer impressão de desbloqueio avançado</string>
|
||||
<string name="advanced_unlock_invalid_key">Não consegue ler a chave de desbloqueio avançada. Por favor, apague-a e repita o procedimento de desbloqueio de reconhecimento.</string>
|
||||
<string name="advanced_unlock_prompt_extract_credential_message">Extrair credencial de base de dados com dados de desbloqueio avançados</string>
|
||||
<string name="advanced_unlock_prompt_extract_credential_title">Base de dados aberta com reconhecimento avançado de desbloqueio</string>
|
||||
<string name="advanced_unlock_prompt_store_credential_message">Advertência: Ainda precisa de se lembrar da sua palavra-passe principal se usar o reconhecimento avançado de desbloqueio.</string>
|
||||
<string name="advanced_unlock_prompt_store_credential_title">Reconhecimento avançado de desbloqueio</string>
|
||||
<string name="advanced_unlock_not_recognized">Não foi possível reconhecer a impressão de desbloqueio avançado</string>
|
||||
<string name="advanced_unlock_invalid_key">Não foi possível ler a chave de desbloqueio avançada. Por favor, elimine-a e repita o procedimento de reconhecimento de desbloqueio.</string>
|
||||
<string name="advanced_unlock_prompt_extract_credential_message">Extrair credencial da base de dados com dados de desbloqueio avançados</string>
|
||||
<string name="advanced_unlock_prompt_extract_credential_title">Abrir base de dados com reconhecimento de desbloqueio avançado</string>
|
||||
<string name="advanced_unlock_prompt_store_credential_message">Advertência: ainda tem de se lembrar da sua palavra-passe principal se usar o reconhecimento de desbloqueio avançado.</string>
|
||||
<string name="advanced_unlock_prompt_store_credential_title">Reconhecimento de desbloqueio avançado</string>
|
||||
<string name="open_advanced_unlock_prompt_store_credential">Abrir o alerta de desbloqueio avançado para armazenar as credenciais</string>
|
||||
<string name="open_advanced_unlock_prompt_unlock_database">Abrir o alerta de desbloqueio avançado para desbloquear a base de dados</string>
|
||||
<string name="biometric_security_update_required">É necessária uma actualização de segurança biométrica.</string>
|
||||
<string name="configure_biometric">O escaneamento biométrico é suportado, mas não configurado.</string>
|
||||
<string name="warning_database_revoked">Acesso ao ficheiro revogado pelo gestor do ficheiro, fechar a base de dados e reabri-la a partir da sua localização.</string>
|
||||
<string name="warning_database_info_changed_options">Sobregravar as modificações externas, guardando a base de dados ou recarregando-a com as últimas alterações.</string>
|
||||
<string name="warning_database_info_changed">A informação contida no seu ficheiro de base de dados foi modificada fora da aplicação.</string>
|
||||
<string name="warning_empty_recycle_bin">Apagar permanentemente todos os nós do caixote do lixo da reciclagem\?</string>
|
||||
<string name="biometric_security_update_required">É necessária uma atualização de segurança biométrica.</string>
|
||||
<string name="configure_biometric">Não está registada nenhuma credencial biométrica ou de dispositivo.</string>
|
||||
<string name="warning_database_revoked">Acesso ao ficheiro revogado pelo gestor de ficheiros. Feche a base de dados e reabra-a a partir da sua localização.</string>
|
||||
<string name="warning_database_info_changed_options">Substitua as alterações externas, guardando a base de dados ou recarregando-a com as últimas alterações.</string>
|
||||
<string name="warning_database_info_changed">A informação contida no seu ficheiro da base de dados foi alterada fora da aplicação.</string>
|
||||
<string name="warning_empty_recycle_bin">Eliminar permanentemente todos os nós do caixote da reciclagem\?</string>
|
||||
<string name="registration_mode">Modo de registo</string>
|
||||
<string name="save_mode">Modo Guardar</string>
|
||||
<string name="save_mode">Modo de guardar</string>
|
||||
<string name="search_mode">Modo de pesquisa</string>
|
||||
<string name="menu_keystore_remove_key">Apagar chave de desbloqueio avançada</string>
|
||||
<string name="menu_keystore_remove_key">Eliminar chave de desbloqueio avançada</string>
|
||||
<string name="menu_reload_database">Recarregar base de dados</string>
|
||||
<string name="error_rebuild_list">Incapaz de reconstruir adequadamente a lista.</string>
|
||||
<string name="error_database_uri_null">O URI da base de dados não pode ser recuperado.</string>
|
||||
<string name="error_rebuild_list">Não foi possível reconstruir adequadamente a lista.</string>
|
||||
<string name="error_database_uri_null">Não foi possível recuperar o URI da base de dados.</string>
|
||||
<string name="error_field_name_already_exists">O nome do campo já existe.</string>
|
||||
<string name="error_registration_read_only">Salvar um novo item não é permitido numa base de dados só de leitura</string>
|
||||
<string name="error_registration_read_only">Não é permitido guardar um novo item numa base de dados só de leitura</string>
|
||||
<string name="content_description_otp_information">Informações sobre a palavra-passe de uso único</string>
|
||||
<string name="show_otp_token_summary">Mostra os tokens OTP na lista de entradas</string>
|
||||
<string name="show_otp_token_title">Mostrar token OTP</string>
|
||||
<string name="show_uuid_summary">Mostra o UUID ligado a uma entrada ou grupo</string>
|
||||
<string name="show_uuid_title">Mostrar UUID</string>
|
||||
<string name="icon_section_custom">Personalizado</string>
|
||||
<string name="icon_section_standard">Predefinido</string>
|
||||
<string name="style_brightness_summary">Escolha temas claros ou escuros</string>
|
||||
<string name="style_brightness_title">Brilho do tema</string>
|
||||
<string name="unit_gibibyte">GiB</string>
|
||||
<string name="unit_mebibyte">MiB</string>
|
||||
<string name="unit_kibibyte">KiB</string>
|
||||
<string name="unit_byte">B</string>
|
||||
<string name="download_canceled">Cancelado!</string>
|
||||
<string name="education_advanced_unlock_summary">Ligue a sua palavra-passe às suas credenciais biométricas ou do dispositivo para desbloquear rapidamente a sua base de dados.</string>
|
||||
<string name="education_advanced_unlock_title">Desbloqueio avançado da base de dados</string>
|
||||
<string name="autofill_inline_suggestions_keyboard">Adicionadas sugestões de preenchimento automático.</string>
|
||||
<string name="autofill_read_only_save">Não é possível guardar dados numa base de dados aberta apenas com permissão de leitura.</string>
|
||||
<string name="autofill_ask_to_save_data_summary">Pedir para guardar dados quando é validado um formulário</string>
|
||||
<string name="autofill_ask_to_save_data_title">Pedir para guardar dados</string>
|
||||
<string name="autofill_save_search_info_summary">Tentar guardar as informações de pesquisas ao fazer uma seleção de entrada manual</string>
|
||||
<string name="autofill_save_search_info_title">Guardar informações de pesquisas</string>
|
||||
<string name="autofill_manual_selection_summary">Mostrar opção para permitir que o utilizador selecione a entrada da base de dados</string>
|
||||
<string name="autofill_manual_selection_title">Seleção manual</string>
|
||||
<string name="autofill_inline_suggestions_summary">Tentar mostrar sugestões de preenchimento automático diretamente de um teclado compatível</string>
|
||||
<string name="autofill_inline_suggestions_title">Sugestões dentro da linha</string>
|
||||
<string name="autofill_close_database_summary">Fechar a base de dados após a seleção de preencher automático</string>
|
||||
<string name="autofill_close_database_title">Fechar base de dados</string>
|
||||
<string name="enter">Enter</string>
|
||||
<string name="backspace">← Apagar</string>
|
||||
<string name="select_entry">Selecionar entrada</string>
|
||||
<string name="back_to_previous_keyboard">Voltar ao teclado anterior</string>
|
||||
<string name="custom_fields">Campos personalizados</string>
|
||||
<string name="keyboard_previous_lock_summary">Mudar automaticamente para o teclado anterior após bloquear a base de dados</string>
|
||||
<string name="keyboard_previous_lock_title">Bloquear base de dados</string>
|
||||
<string name="keyboard_save_search_info_summary">Depois de partilhar um URL com o KeePassDX, quando uma entrada for selecionada, memorizar essa entrada para utilizações posteriores</string>
|
||||
<string name="keyboard_save_search_info_title">Guardar informação partilhada</string>
|
||||
<string name="templates">Modelos</string>
|
||||
<string name="notification">Notificação</string>
|
||||
<string name="autofill_select_entry">Selecionar entrada…</string>
|
||||
<string name="properties">Propriedades</string>
|
||||
<string name="error_export_app_properties">Erro ao exportar as propriedades da aplicação</string>
|
||||
<string name="success_export_app_properties">Propriedades da aplicação exportadas</string>
|
||||
<string name="error_import_app_properties">Erro ao importar as propriedades da aplicação</string>
|
||||
<string name="success_import_app_properties">Propriedades da aplicação importadas</string>
|
||||
<string name="description_app_properties">Propriedades do KeePassDX para gerir as configurações da aplicação</string>
|
||||
<string name="export_app_properties_summary">Criar um ficheiro para exportar as propriedades da aplicação</string>
|
||||
<string name="export_app_properties_title">Exportar as propriedades da aplicação</string>
|
||||
<string name="import_app_properties_summary">Selecione um ficheiro para importar as propriedades da aplicação</string>
|
||||
<string name="import_app_properties_title">Importar propriedades da aplicação</string>
|
||||
<string name="menu_external_icon">Ícone externo</string>
|
||||
<string name="error_start_database_action">Ocorreu um erro ao tentar executar uma ação na base de dados.</string>
|
||||
<string name="error_remove_file">Ocorreu um erro ao tentar remover o ficheiro de dados.</string>
|
||||
<string name="error_duplicate_file">O ficheiro de dados já existe.</string>
|
||||
<string name="error_upload_file">Surgiu um erro ao tentar enviar o ficheiro de dados.</string>
|
||||
<string name="error_file_to_big">O ficheiro que está a tentar enviar é demasiado grande.</string>
|
||||
<string name="error_otp_type">O tipo de OTP existente não é reconhecido por este formulário, é possível que a sua validação possa não gerar o token corretamente.</string>
|
||||
<string name="error_word_reserved">Esta palavra está reservada e não pode ser utilizada.</string>
|
||||
<string name="version">Versão</string>
|
||||
<string name="template">Modelo</string>
|
||||
<string name="standard">Predefinido</string>
|
||||
<string name="membership">Filiação</string>
|
||||
<string name="secure_note">Nota segura</string>
|
||||
<string name="international_bank_account_number">IBAN</string>
|
||||
<string name="bank_identifier_code">SWIFT / BIC</string>
|
||||
<string name="bank_name">Nome do banco</string>
|
||||
<string name="bank">Banco</string>
|
||||
<string name="account">Conta</string>
|
||||
<string name="seed">Semente</string>
|
||||
<string name="private_key">Chave privada</string>
|
||||
<string name="public_key">Chave pública</string>
|
||||
<string name="token">Token</string>
|
||||
<string name="cryptocurrency">Carteira de criptomoedas</string>
|
||||
<string name="type">Tipo</string>
|
||||
<string name="ssid">SSID</string>
|
||||
<string name="email_address">Endereço de email</string>
|
||||
<string name="email">Email</string>
|
||||
<string name="date_of_issue">Data de emissão</string>
|
||||
<string name="place_of_issue">Local de emissão</string>
|
||||
<string name="name">Nome</string>
|
||||
<string name="id_card">Cartão de identificação</string>
|
||||
<string name="personal_identification_number">PIN</string>
|
||||
<string name="card_verification_value">CVV</string>
|
||||
<string name="number">Número</string>
|
||||
<string name="holder">Titular</string>
|
||||
<string name="debit_credit_card">Cartão de crédito / débito</string>
|
||||
<string name="template_group_name">Modelos</string>
|
||||
<string name="templates_group_uuid_title">Grupo de modelos</string>
|
||||
<string name="templates_group_enable_summary">Usa modelos dinâmicos para preencher os campos de uma entrada</string>
|
||||
<string name="templates_group_enable_title">Utilização de modelos</string>
|
||||
<string name="advanced_unlock_delete_all_key_warning">Eliminar todas as chaves de encriptação relacionadas com o desbloqueio de reconhecimento avançado\?</string>
|
||||
<string name="advanced_unlock_timeout">Tempo limite do desbloqueio avançado</string>
|
||||
<string name="temp_advanced_unlock_timeout_summary">Duração do uso do desbloqueio avançado antes de eliminar os seus conteúdos</string>
|
||||
<string name="temp_advanced_unlock_timeout_title">Duração do desbloqueio avançado</string>
|
||||
<string name="temp_advanced_unlock_enable_summary">Não armazenar nenhum conteúdo encriptado para usar o desbloqueio avançado</string>
|
||||
<string name="temp_advanced_unlock_enable_title">Desbloqueio avançado temporário</string>
|
||||
<string name="device_credential_unlock_enable_summary">Permite-lhe usar as credenciais do seu dispositivo para abrir a base de dados</string>
|
||||
<string name="device_credential_unlock_enable_title">Desbloqueio das credenciais do dispositivo</string>
|
||||
<string name="advanced_unlock_tap_delete">Tocar para as eliminar chaves de desbloqueio avançado</string>
|
||||
<string name="content">Conteúdo</string>
|
||||
</resources>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user