mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add clear database option when close clipboard notification
This commit is contained in:
@@ -146,7 +146,7 @@
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
<service
|
||||
android:name="com.kunzisoft.keepass.notifications.CopyingEntryNotificationService"
|
||||
android:name="com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
<!-- Receiver for Autofill -->
|
||||
@@ -171,7 +171,10 @@
|
||||
<action android:name="android.view.InputMethod" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service android:name="com.kunzisoft.keepass.magikeyboard.KeyboardEntryNotificationService" />
|
||||
<service
|
||||
android:name="com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
|
||||
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
||||
</application>
|
||||
|
||||
@@ -43,7 +43,7 @@ import com.kunzisoft.keepass.database.element.PwNodeId
|
||||
import com.kunzisoft.keepass.education.EntryActivityEducation
|
||||
import com.kunzisoft.keepass.icons.assignDatabaseIcon
|
||||
import com.kunzisoft.keepass.magikeyboard.MagikIME
|
||||
import com.kunzisoft.keepass.notifications.CopyingEntryNotificationService
|
||||
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil.isFirstTimeAskAllowCopyPasswordAndProtectedFields
|
||||
import com.kunzisoft.keepass.settings.SettingsAutofillActivity
|
||||
@@ -133,7 +133,7 @@ class EntryActivity : LockingHideActivity() {
|
||||
// Manage entry copy to start notification if allowed
|
||||
if (firstLaunchOfActivity) {
|
||||
// Manage entry to launch copying notification if allowed
|
||||
CopyingEntryNotificationService.launchNotificationIfAllowed(this, entryInfo)
|
||||
ClipboardEntryNotificationService.launchNotificationIfAllowed(this, entryInfo)
|
||||
// Manage entry to populate Magikeyboard and launch keyboard notification if allowed
|
||||
if (PreferencesUtil.isKeyboardEntrySelectionEnable(this)) {
|
||||
MagikIME.addEntryAndLaunchNotificationIfAllowed(this, entryInfo)
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
|
||||
import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
|
||||
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.magikeyboard.KeyboardEntryNotificationService
|
||||
import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService
|
||||
import com.kunzisoft.keepass.magikeyboard.MagikIME
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.magikeyboard.adapter.FieldsAdapter
|
||||
import com.kunzisoft.keepass.model.EntryInfo
|
||||
import com.kunzisoft.keepass.model.Field
|
||||
import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.utils.LOCK_ACTION
|
||||
import com.kunzisoft.keepass.utils.REMOVE_ENTRY_MAGIKEYBOARD_ACTION
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.ArrayList
|
||||
/**
|
||||
* Utility class to manage fields in Notifications
|
||||
*/
|
||||
open class NotificationCopyingField : Parcelable {
|
||||
open class ClipboardEntryNotificationField : Parcelable {
|
||||
|
||||
private var id: NotificationFieldId = NotificationFieldId.UNKNOWN
|
||||
var value: String
|
||||
@@ -79,7 +79,7 @@ open class NotificationCopyingField : Parcelable {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
val field = other as NotificationCopyingField
|
||||
val field = other as ClipboardEntryNotificationField
|
||||
return id == field.id
|
||||
}
|
||||
|
||||
@@ -111,15 +111,15 @@ open class NotificationCopyingField : Parcelable {
|
||||
|
||||
companion object {
|
||||
|
||||
private val TAG = NotificationCopyingField::class.java.name
|
||||
private val TAG = ClipboardEntryNotificationField::class.java.name
|
||||
|
||||
@JvmField
|
||||
val CREATOR: Parcelable.Creator<NotificationCopyingField> = object : Parcelable.Creator<NotificationCopyingField> {
|
||||
override fun createFromParcel(`in`: Parcel): NotificationCopyingField {
|
||||
return NotificationCopyingField(`in`)
|
||||
val CREATOR: Parcelable.Creator<ClipboardEntryNotificationField> = object : Parcelable.Creator<ClipboardEntryNotificationField> {
|
||||
override fun createFromParcel(`in`: Parcel): ClipboardEntryNotificationField {
|
||||
return ClipboardEntryNotificationField(`in`)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<NotificationCopyingField?> {
|
||||
override fun newArray(size: Int): Array<ClipboardEntryNotificationField?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
@@ -30,16 +30,17 @@ import com.kunzisoft.keepass.model.EntryInfo
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.timeout.ClipboardHelper
|
||||
import com.kunzisoft.keepass.timeout.TimeoutHelper.NEVER
|
||||
import com.kunzisoft.keepass.utils.LOCK_ACTION
|
||||
import java.util.*
|
||||
|
||||
class CopyingEntryNotificationService : NotificationService() {
|
||||
class ClipboardEntryNotificationService : NotificationService() {
|
||||
|
||||
private var notificationId = 485
|
||||
private var cleanNotificationTimer: Thread? = null
|
||||
private var cleanNotificationTimerTask: Thread? = null
|
||||
private var notificationTimeoutMilliSecs: Long = 0
|
||||
|
||||
private var clipboardHelper: ClipboardHelper? = null
|
||||
private var countingDownTask: Thread? = null
|
||||
private var cleanCopyNotificationTimerTask: Thread? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
@@ -47,6 +48,13 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
clipboardHelper = ClipboardHelper(this)
|
||||
}
|
||||
|
||||
private fun stopNotificationAndSendLockIfNeeded() {
|
||||
// Clear the entry if define in preferences
|
||||
if (PreferencesUtil.isClearClipboardNotificationEnable(this)) {
|
||||
sendBroadcast(Intent(LOCK_ACTION))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
//Get settings
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
@@ -61,17 +69,18 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
newNotification(title, constructListOfField(intent))
|
||||
}
|
||||
ACTION_CLEAN_CLIPBOARD == intent.action -> {
|
||||
stopTask(countingDownTask)
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
try {
|
||||
clipboardHelper?.cleanClipboard()
|
||||
} catch (e: SamsungClipboardException) {
|
||||
Log.e(TAG, "Clipboard can't be cleaned", e)
|
||||
}
|
||||
stopNotificationAndSendLockIfNeeded()
|
||||
}
|
||||
else -> for (actionKey in NotificationCopyingField.allActionKeys) {
|
||||
else -> for (actionKey in ClipboardEntryNotificationField.allActionKeys) {
|
||||
if (actionKey == intent.action) {
|
||||
val fieldToCopy = intent.getParcelableExtra<NotificationCopyingField>(
|
||||
NotificationCopyingField.getExtraKeyLinkToActionKey(actionKey))
|
||||
val fieldToCopy = intent.getParcelableExtra<ClipboardEntryNotificationField>(
|
||||
ClipboardEntryNotificationField.getExtraKeyLinkToActionKey(actionKey))
|
||||
val nextFields = constructListOfField(intent)
|
||||
// Remove the current field from the next fields
|
||||
nextFields.remove(fieldToCopy)
|
||||
@@ -82,8 +91,8 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
private fun constructListOfField(intent: Intent?): ArrayList<NotificationCopyingField> {
|
||||
var fieldList = ArrayList<NotificationCopyingField>()
|
||||
private fun constructListOfField(intent: Intent?): ArrayList<ClipboardEntryNotificationField> {
|
||||
var fieldList = ArrayList<ClipboardEntryNotificationField>()
|
||||
if (intent != null && intent.extras != null) {
|
||||
if (intent.extras!!.containsKey(EXTRA_FIELDS))
|
||||
fieldList = intent.getParcelableArrayListExtra(EXTRA_FIELDS)
|
||||
@@ -91,8 +100,8 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
return fieldList
|
||||
}
|
||||
|
||||
private fun getCopyPendingIntent(fieldToCopy: NotificationCopyingField, fieldsToAdd: ArrayList<NotificationCopyingField>): PendingIntent {
|
||||
val copyIntent = Intent(this, CopyingEntryNotificationService::class.java)
|
||||
private fun getCopyPendingIntent(fieldToCopy: ClipboardEntryNotificationField, fieldsToAdd: ArrayList<ClipboardEntryNotificationField>): PendingIntent {
|
||||
val copyIntent = Intent(this, ClipboardEntryNotificationService::class.java)
|
||||
copyIntent.action = fieldToCopy.actionKey
|
||||
copyIntent.putExtra(fieldToCopy.extraKey, fieldToCopy)
|
||||
copyIntent.putParcelableArrayListExtra(EXTRA_FIELDS, fieldsToAdd)
|
||||
@@ -101,8 +110,8 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
this, 0, copyIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
private fun newNotification(title: String?, fieldsToAdd: ArrayList<NotificationCopyingField>) {
|
||||
stopTask(countingDownTask)
|
||||
private fun newNotification(title: String?, fieldsToAdd: ArrayList<ClipboardEntryNotificationField>) {
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
|
||||
val builder = buildNewNotification()
|
||||
.setSmallIcon(R.drawable.ic_key_white_24dp)
|
||||
@@ -129,24 +138,24 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
notificationManager?.notify(++notificationId, builder.build())
|
||||
|
||||
val myNotificationId = notificationId
|
||||
stopTask(cleanNotificationTimer)
|
||||
stopTask(cleanNotificationTimerTask)
|
||||
// If timer
|
||||
if (notificationTimeoutMilliSecs != NEVER) {
|
||||
cleanNotificationTimer = Thread {
|
||||
cleanNotificationTimerTask = Thread {
|
||||
try {
|
||||
Thread.sleep(notificationTimeoutMilliSecs)
|
||||
} catch (e: InterruptedException) {
|
||||
cleanNotificationTimer = null
|
||||
cleanNotificationTimerTask = null
|
||||
}
|
||||
notificationManager?.cancel(myNotificationId)
|
||||
}
|
||||
cleanNotificationTimer?.start()
|
||||
cleanNotificationTimerTask?.start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyField(fieldToCopy: NotificationCopyingField, nextFields: ArrayList<NotificationCopyingField>) {
|
||||
stopTask(countingDownTask)
|
||||
stopTask(cleanNotificationTimer)
|
||||
private fun copyField(fieldToCopy: ClipboardEntryNotificationField, nextFields: ArrayList<ClipboardEntryNotificationField>) {
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
stopTask(cleanNotificationTimerTask)
|
||||
|
||||
try {
|
||||
clipboardHelper?.copyToClipboard(fieldToCopy.label, fieldToCopy.value)
|
||||
@@ -165,7 +174,7 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
builder.setContentText(getString(R.string.clipboard_swipe_clean))
|
||||
}
|
||||
|
||||
val cleanIntent = Intent(this, CopyingEntryNotificationService::class.java)
|
||||
val cleanIntent = Intent(this, ClipboardEntryNotificationService::class.java)
|
||||
cleanIntent.action = ACTION_CLEAN_CLIPBOARD
|
||||
val cleanPendingIntent = PendingIntent.getService(
|
||||
this, 0, cleanIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
@@ -174,10 +183,10 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
val myNotificationId = notificationId
|
||||
|
||||
if (notificationTimeoutMilliSecs != NEVER) {
|
||||
countingDownTask = Thread {
|
||||
cleanCopyNotificationTimerTask = Thread {
|
||||
val maxPos = 100
|
||||
val posDurationMills = notificationTimeoutMilliSecs / maxPos
|
||||
for (pos in maxPos downTo 1) {
|
||||
for (pos in maxPos downTo 0) {
|
||||
builder.setProgress(maxPos, pos, false)
|
||||
notificationManager?.notify(myNotificationId, builder.build())
|
||||
try {
|
||||
@@ -185,9 +194,11 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
} catch (e: InterruptedException) {
|
||||
break
|
||||
}
|
||||
|
||||
if (pos <= 0) {
|
||||
stopNotificationAndSendLockIfNeeded()
|
||||
}
|
||||
}
|
||||
countingDownTask = null
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
notificationManager?.cancel(myNotificationId)
|
||||
// Clean password only if no next field
|
||||
if (nextFields.size <= 0)
|
||||
@@ -197,7 +208,7 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
Log.e(TAG, "Clipboard can't be cleaned", e)
|
||||
}
|
||||
}
|
||||
countingDownTask?.start()
|
||||
cleanCopyNotificationTimerTask?.start()
|
||||
} else {
|
||||
// No timer
|
||||
notificationManager?.notify(myNotificationId, builder.build())
|
||||
@@ -216,7 +227,7 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
|
||||
companion object {
|
||||
|
||||
private val TAG = CopyingEntryNotificationService::class.java.name
|
||||
private val TAG = ClipboardEntryNotificationService::class.java.name
|
||||
|
||||
const val ACTION_NEW_NOTIFICATION = "ACTION_NEW_NOTIFICATION"
|
||||
const val EXTRA_ENTRY_TITLE = "EXTRA_ENTRY_TITLE"
|
||||
@@ -240,23 +251,23 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
if (containsUsernameToCopy || containsPasswordToCopy || containsExtraFieldToCopy) {
|
||||
|
||||
// username already copied, waiting for user's action before copy password.
|
||||
val intent = Intent(context, CopyingEntryNotificationService::class.java)
|
||||
val intent = Intent(context, ClipboardEntryNotificationService::class.java)
|
||||
intent.action = ACTION_NEW_NOTIFICATION
|
||||
intent.putExtra(EXTRA_ENTRY_TITLE, entry.title)
|
||||
// Construct notification fields
|
||||
val notificationFields = ArrayList<NotificationCopyingField>()
|
||||
val notificationFields = ArrayList<ClipboardEntryNotificationField>()
|
||||
// Add username if exists to notifications
|
||||
if (containsUsernameToCopy)
|
||||
notificationFields.add(
|
||||
NotificationCopyingField(
|
||||
NotificationCopyingField.NotificationFieldId.USERNAME,
|
||||
ClipboardEntryNotificationField(
|
||||
ClipboardEntryNotificationField.NotificationFieldId.USERNAME,
|
||||
entry.username,
|
||||
context.resources))
|
||||
// Add password to notifications
|
||||
if (containsPasswordToCopy) {
|
||||
notificationFields.add(
|
||||
NotificationCopyingField(
|
||||
NotificationCopyingField.NotificationFieldId.PASSWORD,
|
||||
ClipboardEntryNotificationField(
|
||||
ClipboardEntryNotificationField.NotificationFieldId.PASSWORD,
|
||||
entry.password,
|
||||
context.resources))
|
||||
}
|
||||
@@ -269,8 +280,8 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
if (!field.protectedValue.isProtected
|
||||
|| PreferencesUtil.allowCopyPasswordAndProtectedFields(context)) {
|
||||
notificationFields.add(
|
||||
NotificationCopyingField(
|
||||
NotificationCopyingField.NotificationFieldId.anonymousFieldId[anonymousFieldNumber],
|
||||
ClipboardEntryNotificationField(
|
||||
ClipboardEntryNotificationField.NotificationFieldId.anonymousFieldId[anonymousFieldNumber],
|
||||
field.protectedValue.toString(),
|
||||
field.name,
|
||||
context.resources))
|
||||
@@ -278,7 +289,7 @@ class CopyingEntryNotificationService : NotificationService() {
|
||||
}
|
||||
}
|
||||
} catch (e: ArrayIndexOutOfBoundsException) {
|
||||
Log.w("NotificationEntryCopyMg", "Only " + NotificationCopyingField.NotificationFieldId.anonymousFieldId.size +
|
||||
Log.w("NotificationEntryCopyMg", "Only " + ClipboardEntryNotificationField.NotificationFieldId.anonymousFieldId.size +
|
||||
" anonymous notifications are available")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.kunzisoft.keepass.magikeyboard
|
||||
package com.kunzisoft.keepass.notifications
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
@@ -8,8 +8,8 @@ import android.content.IntentFilter
|
||||
import android.support.v7.preference.PreferenceManager
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.magikeyboard.MagikIME
|
||||
import com.kunzisoft.keepass.model.EntryInfo
|
||||
import com.kunzisoft.keepass.notifications.NotificationService
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
||||
import com.kunzisoft.keepass.utils.LOCK_ACTION
|
||||
@@ -17,7 +17,7 @@ import com.kunzisoft.keepass.utils.LOCK_ACTION
|
||||
class KeyboardEntryNotificationService : NotificationService() {
|
||||
|
||||
private val notificationId = 486
|
||||
private var cleanNotificationTimer: Thread? = null
|
||||
private var cleanNotificationTimerTask: Thread? = null
|
||||
private var notificationTimeoutMilliSecs: Long = 0
|
||||
|
||||
private var lockBroadcastReceiver: BroadcastReceiver? = null
|
||||
@@ -95,7 +95,7 @@ class KeyboardEntryNotificationService : NotificationService() {
|
||||
notificationManager?.notify(notificationId, builder.build())
|
||||
|
||||
|
||||
stopTask(cleanNotificationTimer)
|
||||
stopTask(cleanNotificationTimerTask)
|
||||
// Timeout only if notification clear is available
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
if (sharedPreferences.getBoolean(getString(R.string.keyboard_notification_entry_clear_close_key),
|
||||
@@ -109,7 +109,7 @@ class KeyboardEntryNotificationService : NotificationService() {
|
||||
}
|
||||
|
||||
if (notificationTimeoutMilliSecs != TimeoutHelper.NEVER) {
|
||||
cleanNotificationTimer = Thread {
|
||||
cleanNotificationTimerTask = Thread {
|
||||
val maxPos = 100
|
||||
val posDurationMills = notificationTimeoutMilliSecs / maxPos
|
||||
for (pos in maxPos downTo 0) {
|
||||
@@ -125,7 +125,7 @@ class KeyboardEntryNotificationService : NotificationService() {
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanNotificationTimer?.start()
|
||||
cleanNotificationTimerTask?.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,8 +136,8 @@ class KeyboardEntryNotificationService : NotificationService() {
|
||||
}
|
||||
|
||||
private fun destroyKeyboardNotification() {
|
||||
stopTask(cleanNotificationTimer)
|
||||
cleanNotificationTimer = null
|
||||
stopTask(cleanNotificationTimerTask)
|
||||
cleanNotificationTimerTask = null
|
||||
unregisterReceiver(lockBroadcastReceiver)
|
||||
pendingDeleteIntent?.cancel()
|
||||
|
||||
@@ -184,6 +184,12 @@ object PreferencesUtil {
|
||||
context.resources.getBoolean(R.bool.allow_copy_password_default))
|
||||
}
|
||||
|
||||
fun isClearClipboardNotificationEnable(context: Context): Boolean {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
return prefs.getBoolean(context.getString(R.string.clear_clipboard_notification_key),
|
||||
context.resources.getBoolean(R.bool.clear_clipboard_notification_default))
|
||||
}
|
||||
|
||||
fun setAllowCopyPasswordAndProtectedFields(context: Context, allowCopy: Boolean) {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
prefs.edit()
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
<bool name="maskpass_default" translatable="false">true</bool>
|
||||
<string name="allow_copy_password_key" translatable="false">allow_copy_password_key</string>
|
||||
<bool name="allow_copy_password_default" translatable="false">false</bool>
|
||||
<string name="clear_clipboard_notification_key" translatable="false">clear_clipboard_notification_key</string>
|
||||
<bool name="clear_clipboard_notification_default" translatable="false">false</bool>
|
||||
<string name="recentfile_key" translatable="false">recentfile</string>
|
||||
<bool name="recentfile_default" translatable="false">true</bool>
|
||||
<string name="keyfile_key" translatable="false">keyfile</string>
|
||||
|
||||
@@ -270,6 +270,8 @@
|
||||
<string name="allow_copy_password_title">Clipboard trust</string>
|
||||
<string name="allow_copy_password_summary">Allow the entry password and protected fields to enter the clipboard</string>
|
||||
<string name="allow_copy_password_warning">WARNING: The clipboard is shared by all apps. If sensitive data is copied, other software may recover it.</string>
|
||||
<string name="clear_clipboard_notification_title">Clear at closing</string>
|
||||
<string name="clear_clipboard_notification_summary">Close the database when closing the notification</string>
|
||||
<string name="warning_disabling_storage_access_framework">WARNING: Turning off this feature may prevent opening or saving databases.</string>
|
||||
<string name="open_link_database">Link of database file to open</string>
|
||||
<string name="database_name_title">Database name</string>
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
android:title="@string/allow_copy_password_title"
|
||||
android:summary="@string/allow_copy_password_summary"
|
||||
android:defaultValue="@bool/allow_copy_password_default"/>
|
||||
<SwitchPreference
|
||||
android:key="@string/clear_clipboard_notification_key"
|
||||
android:title="@string/clear_clipboard_notification_title"
|
||||
android:summary="@string/clear_clipboard_notification_summary"
|
||||
android:defaultValue="@bool/clear_clipboard_notification_default"/>
|
||||
<ListPreference
|
||||
android:key="@string/clipboard_timeout_key"
|
||||
android:title="@string/clipboard_timeout"
|
||||
|
||||
Reference in New Issue
Block a user