mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add dialog with a warning to copy, add the setting to copy the protected custom fields #139
This commit is contained in:
@@ -6,6 +6,7 @@ KeepassDX (2.5.0.0beta12)
|
||||
* New adaptive launcher icon
|
||||
* Added a setting to disable the open button when no password is identified
|
||||
* Added a setting to disable the education screens
|
||||
* Added a setting to disable the copy of protected custom fields
|
||||
* Fix the fingerprint recognition (WARNING : The keystore is reinit, you must delete the old keys)
|
||||
* Fix small bugs
|
||||
|
||||
|
||||
@@ -152,12 +152,28 @@ public class EntryActivity extends LockingHideActivity {
|
||||
// Start to manage field reference to copy a value from ref
|
||||
mEntry.startToManageFieldReferences(App.getDB().getPwDatabase());
|
||||
|
||||
boolean containsUsernameToCopy =
|
||||
mEntry.getUsername().length() > 0;
|
||||
boolean containsPasswordToCopy =
|
||||
(mEntry.getPassword().length() > 0
|
||||
&& PreferencesUtil.allowCopyPasswordAndProtectedFields(this));
|
||||
boolean containsExtraFieldToCopy =
|
||||
(mEntry.allowExtraFields()
|
||||
&& ((mEntry.containsCustomFields()
|
||||
&& mEntry.containsCustomFieldsNotProtected())
|
||||
|| (mEntry.containsCustomFields()
|
||||
&& mEntry.containsCustomFieldsProtected()
|
||||
&& PreferencesUtil.allowCopyPasswordAndProtectedFields(this))
|
||||
)
|
||||
);
|
||||
|
||||
// If notifications enabled in settings
|
||||
// Don't if application timeout
|
||||
if (firstLaunchOfActivity && !App.isShutdown() && isClipboardNotificationsEnable(getApplicationContext())) {
|
||||
if (mEntry.getUsername().length() > 0
|
||||
|| (mEntry.getPassword().length() > 0 && PreferencesUtil.allowCopyPassword(this))
|
||||
|| mEntry.containsCustomFields()) {
|
||||
if (containsUsernameToCopy
|
||||
|| containsPasswordToCopy
|
||||
|| containsExtraFieldToCopy
|
||||
) {
|
||||
// username already copied, waiting for user's action before copy password.
|
||||
Intent intent = new Intent(this, NotificationCopyingService.class);
|
||||
intent.setAction(NotificationCopyingService.ACTION_NEW_NOTIFICATION);
|
||||
@@ -166,35 +182,37 @@ public class EntryActivity extends LockingHideActivity {
|
||||
// Construct notification fields
|
||||
ArrayList<NotificationField> notificationFields = new ArrayList<>();
|
||||
// Add username if exists to notifications
|
||||
if (mEntry.getUsername().length() > 0)
|
||||
if (containsUsernameToCopy)
|
||||
notificationFields.add(
|
||||
new NotificationField(
|
||||
NotificationField.NotificationFieldId.USERNAME,
|
||||
mEntry.getUsername(),
|
||||
getResources()));
|
||||
// Add password to notifications
|
||||
if (PreferencesUtil.allowCopyPassword(this)) {
|
||||
if (mEntry.getPassword().length() > 0)
|
||||
notificationFields.add(
|
||||
new NotificationField(
|
||||
NotificationField.NotificationFieldId.PASSWORD,
|
||||
mEntry.getPassword(),
|
||||
getResources()));
|
||||
if (containsPasswordToCopy) {
|
||||
notificationFields.add(
|
||||
new NotificationField(
|
||||
NotificationField.NotificationFieldId.PASSWORD,
|
||||
mEntry.getPassword(),
|
||||
getResources()));
|
||||
}
|
||||
// Add extra fields
|
||||
if (mEntry.allowExtraFields()) {
|
||||
if (containsExtraFieldToCopy) {
|
||||
try {
|
||||
mEntry.getFields().doActionToAllCustomProtectedField(new ExtraFields.ActionProtected() {
|
||||
private int anonymousFieldNumber = 0;
|
||||
@Override
|
||||
public void doAction(String key, ProtectedString value) {
|
||||
notificationFields.add(
|
||||
new NotificationField(
|
||||
NotificationField.NotificationFieldId.getAnonymousFieldId()[anonymousFieldNumber],
|
||||
value.toString(),
|
||||
key,
|
||||
getResources()));
|
||||
anonymousFieldNumber++;
|
||||
//If value is not protected or allowed
|
||||
if (!value.isProtected() || PreferencesUtil.allowCopyPasswordAndProtectedFields(EntryActivity.this)) {
|
||||
notificationFields.add(
|
||||
new NotificationField(
|
||||
NotificationField.NotificationFieldId.getAnonymousFieldId()[anonymousFieldNumber],
|
||||
value.toString(),
|
||||
key,
|
||||
getResources()));
|
||||
anonymousFieldNumber++;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
@@ -313,7 +331,7 @@ public class EntryActivity extends LockingHideActivity {
|
||||
);
|
||||
|
||||
entryContentsView.assignPassword(mEntry.getPassword());
|
||||
if (PreferencesUtil.allowCopyPassword(this)) {
|
||||
if (PreferencesUtil.allowCopyPasswordAndProtectedFields(this)) {
|
||||
entryContentsView.assignPasswordCopyListener(view ->
|
||||
clipboardHelper.timeoutCopyToClipboard(mEntry.getPassword(),
|
||||
getString(R.string.copy_field, getString(R.string.entry_password)))
|
||||
@@ -329,14 +347,15 @@ public class EntryActivity extends LockingHideActivity {
|
||||
if (mEntry.allowExtraFields()) {
|
||||
entryContentsView.clearExtraFields();
|
||||
|
||||
mEntry.getFields().doActionToAllCustomProtectedField((label, value) ->
|
||||
|
||||
entryContentsView.addExtraField(label, value, view ->
|
||||
mEntry.getFields().doActionToAllCustomProtectedField((label, value) -> {
|
||||
boolean showAction = (!value.isProtected() || PreferencesUtil.allowCopyPasswordAndProtectedFields(EntryActivity.this));
|
||||
entryContentsView.addExtraField(label, value, showAction, view ->
|
||||
clipboardHelper.timeoutCopyToClipboard(
|
||||
value.toString(),
|
||||
getString(R.string.copy_field, label)
|
||||
)
|
||||
));
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Assign dates
|
||||
|
||||
@@ -44,6 +44,22 @@ public class ExtraFields implements Serializable, Cloneable {
|
||||
return !getCustomProtectedFields().keySet().isEmpty();
|
||||
}
|
||||
|
||||
public boolean containsCustomFieldsProtected() {
|
||||
for (Map.Entry<String, ProtectedString> field : getCustomProtectedFields().entrySet()) {
|
||||
if (field.getValue().isProtected())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsCustomFieldsNotProtected() {
|
||||
for (Map.Entry<String, ProtectedString> field : getCustomProtectedFields().entrySet()) {
|
||||
if (!field.getValue().isProtected())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getProtectedStringValue(String key) {
|
||||
ProtectedString value = fields.get(key);
|
||||
if ( value == null ) return "";
|
||||
|
||||
@@ -117,6 +117,22 @@ public abstract class PwEntry<Parent extends PwGroup> extends PwNode<Parent> {
|
||||
return getFields().containsCustomFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* If entry contains extra fields that are protected
|
||||
* @return true if there is extra fields protected
|
||||
*/
|
||||
public boolean containsCustomFieldsProtected() {
|
||||
return getFields().containsCustomFieldsProtected();
|
||||
}
|
||||
|
||||
/**
|
||||
* If entry contains extra fields that are not protected
|
||||
* @return true if there is extra fields not protected
|
||||
*/
|
||||
public boolean containsCustomFieldsNotProtected() {
|
||||
return getFields().containsCustomFieldsNotProtected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an extra field to the list (standard or custom)
|
||||
* @param label Label of field, must be unique
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX 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.
|
||||
*
|
||||
* KeePass DX 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 KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.dialogs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public class StorageAccessFrameworkDialog extends AlertDialog {
|
||||
|
||||
public StorageAccessFrameworkDialog(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public StorageAccessFrameworkDialog(@NonNull Context context, int themeResId) {
|
||||
super(context, themeResId);
|
||||
}
|
||||
|
||||
public StorageAccessFrameworkDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
|
||||
super(context, cancelable, cancelListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Context ctx = getContext();
|
||||
setMessage(ctx.getString(R.string.warning_disabling_storage_access_framework));
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,6 @@ import android.support.annotation.RequiresApi;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.hardware.fingerprint.FingerprintManagerCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
@@ -47,7 +46,6 @@ import com.kunzisoft.keepass.R;
|
||||
import com.kunzisoft.keepass.app.App;
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.dialogs.ProFeatureDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.StorageAccessFrameworkDialog;
|
||||
import com.kunzisoft.keepass.dialogs.UnavailableFeatureDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.UnderDevelopmentFeatureDialogFragment;
|
||||
import com.kunzisoft.keepass.fingerprint.FingerPrintHelper;
|
||||
@@ -117,6 +115,8 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
|
||||
case APPLICATION:
|
||||
setPreferencesFromResource(R.xml.application_preferences, rootKey);
|
||||
|
||||
allowCopyPassword();
|
||||
|
||||
Preference keyFile = findPreference(getString(R.string.keyfile_key));
|
||||
keyFile.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
Boolean value = (Boolean) newValue;
|
||||
@@ -142,17 +142,18 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
|
||||
storageAccessFramework.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
Boolean value = (Boolean) newValue;
|
||||
if (!value && getContext() != null) {
|
||||
StorageAccessFrameworkDialog safDialog = new StorageAccessFrameworkDialog(getContext());
|
||||
safDialog.setButton(AlertDialog.BUTTON1, getText(android.R.string.ok),
|
||||
AlertDialog alertDialog = new AlertDialog.Builder(getContext())
|
||||
.setMessage(getString(R.string.warning_disabling_storage_access_framework)).create();
|
||||
alertDialog.setButton(AlertDialog.BUTTON1, getText(android.R.string.ok),
|
||||
(dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
safDialog.setButton(AlertDialog.BUTTON2, getText(android.R.string.cancel),
|
||||
alertDialog.setButton(AlertDialog.BUTTON2, getText(android.R.string.cancel),
|
||||
(dialog, which) -> {
|
||||
storageAccessFramework.setChecked(true);
|
||||
dialog.dismiss();
|
||||
});
|
||||
safDialog.show();
|
||||
alertDialog.show();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
@@ -297,6 +298,9 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
|
||||
return false;
|
||||
});
|
||||
|
||||
// Present in two places
|
||||
allowCopyPassword();
|
||||
|
||||
break;
|
||||
|
||||
case DATABASE:
|
||||
@@ -427,6 +431,28 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
|
||||
}
|
||||
}
|
||||
|
||||
private void allowCopyPassword() {
|
||||
SwitchPreference copyPasswordPreference = (SwitchPreference) findPreference(getString(R.string.allow_copy_password_key));
|
||||
copyPasswordPreference.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
if ((Boolean) newValue && getContext() != null) {
|
||||
String message = getString(R.string.allow_copy_password_warning) +
|
||||
"\n\n" +
|
||||
getString(R.string.clipboard_warning);
|
||||
AlertDialog warningDialog = new AlertDialog.Builder(getContext())
|
||||
.setMessage(message).create();
|
||||
warningDialog.setButton(AlertDialog.BUTTON1, getText(android.R.string.ok),
|
||||
(dialog, which) -> dialog.dismiss());
|
||||
warningDialog.setButton(AlertDialog.BUTTON2, getText(android.R.string.cancel),
|
||||
(dialog, which) -> {
|
||||
copyPasswordPreference.setChecked(false);
|
||||
dialog.dismiss();
|
||||
});
|
||||
warningDialog.show();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void preferenceInDevelopment(Preference preferenceInDev) {
|
||||
preferenceInDev.setOnPreferenceClickListener(preference -> {
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
|
||||
@@ -139,7 +139,7 @@ public class PreferencesUtil {
|
||||
ctx.getResources().getBoolean(R.bool.auto_open_file_uri_default));
|
||||
}
|
||||
|
||||
public static boolean allowCopyPassword(Context ctx) {
|
||||
public static boolean allowCopyPasswordAndProtectedFields(Context ctx) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
return prefs.getBoolean(ctx.getString(R.string.allow_copy_password_key),
|
||||
ctx.getResources().getBoolean(R.bool.allow_copy_password_default));
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ClipboardHelper {
|
||||
public void copyToClipboard(String label, String value) throws SamsungClipboardException {
|
||||
try {
|
||||
clipboardManager.setPrimaryClip(ClipData.newPlainText(label, value));
|
||||
} catch (NullPointerException e) {
|
||||
} catch (Exception e) {
|
||||
throw new SamsungClipboardException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,12 +193,12 @@ public class EntryContentsView extends LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
public void addExtraField(String title, ProtectedString value, OnClickListener onActionClickListener) {
|
||||
public void addExtraField(String title, ProtectedString value, boolean showAction, OnClickListener onActionClickListener) {
|
||||
EntryCustomField entryCustomField;
|
||||
if (value.isProtected())
|
||||
entryCustomField = new EntryCustomFieldProtected(getContext(), null, title, value, onActionClickListener);
|
||||
entryCustomField = new EntryCustomFieldProtected(getContext(), null, title, value, showAction, onActionClickListener);
|
||||
else
|
||||
entryCustomField = new EntryCustomField(getContext(), null, title, value, onActionClickListener);
|
||||
entryCustomField = new EntryCustomField(getContext(), null, title, value, showAction, onActionClickListener);
|
||||
entryCustomField.applyFontVisibility(fontInVisibility);
|
||||
extrasView.addView(entryCustomField);
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ public class EntryCustomField extends LinearLayout {
|
||||
}
|
||||
|
||||
public EntryCustomField(Context context, AttributeSet attrs, String title, ProtectedString value) {
|
||||
this(context, attrs, title, value, null);
|
||||
this(context, attrs, title, value, false, null);
|
||||
}
|
||||
|
||||
public EntryCustomField(Context context, AttributeSet attrs, String label, ProtectedString value, OnClickListener onClickActionListener) {
|
||||
public EntryCustomField(Context context, AttributeSet attrs, String label, ProtectedString value, boolean showAction, OnClickListener onClickActionListener) {
|
||||
super(context, attrs);
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
@@ -61,7 +61,12 @@ public class EntryCustomField extends LinearLayout {
|
||||
|
||||
setLabel(label);
|
||||
setValue(value);
|
||||
setAction(onClickActionListener);
|
||||
|
||||
if (!showAction) {
|
||||
actionImageView.setVisibility(INVISIBLE);
|
||||
} else {
|
||||
setAction(onClickActionListener);
|
||||
}
|
||||
}
|
||||
|
||||
public void applyFontVisibility(boolean fontInVisibility) {
|
||||
|
||||
@@ -39,8 +39,8 @@ public class EntryCustomFieldProtected extends EntryCustomField{
|
||||
super(context, attrs, title, value);
|
||||
}
|
||||
|
||||
public EntryCustomFieldProtected(Context context, AttributeSet attrs, String label, ProtectedString value, OnClickListener onClickActionListener) {
|
||||
super(context, attrs, label, value, onClickActionListener);
|
||||
public EntryCustomFieldProtected(Context context, AttributeSet attrs, String label, ProtectedString value, boolean showAction, OnClickListener onClickActionListener) {
|
||||
super(context, attrs, label, value, showAction, onClickActionListener);
|
||||
}
|
||||
|
||||
public void setValue(ProtectedString value) {
|
||||
|
||||
@@ -212,7 +212,8 @@
|
||||
<string name="list_password_generator_options_summary">Définir les caractères par défaut du générateur de mot de passe</string>
|
||||
<string name="notifications">Notifications</string>
|
||||
<string name="clipboard_notifications_title">Notifications du presse-papiers</string>
|
||||
<string name="clipboard_notifications_summary">Activer les notifications du presse-papiers pour copier le nom d\'utilisateur et le mot de passe</string>
|
||||
<string name="clipboard_notifications_summary">Activer les notifications du presse-papiers pour copier les champs d\'entrées</string>
|
||||
<string name="clipboard_warning">Certains appareils ne sont pas en mesure de supprimer automatiquement les éléments du presse-papiers. Si votre gestionnaire n\'autorise pas cette suppression, vous devrez supprimer manuellement l\'élément copié de l\'historique de votre presse-papiers.</string>
|
||||
<string name="lock_database_screen_off_title">Verrouillage d\'écran</string>
|
||||
<string name="lock_database_screen_off_summary">Verrouiller la base de données quand l\'écran est éteint</string>
|
||||
<string name="fingerprint_quick_unlock_title">Comment configurer l\'empreinte digitale pour un déverrouillage rapide?</string>
|
||||
@@ -249,7 +250,8 @@
|
||||
<string name="auto_open_file_uri_title">Ouvrir le fichier sélectionné automatiquement</string>
|
||||
<string name="auto_open_file_uri_summary">Ouvrir automatiquement un fichier à partir de l\'écran de sélection après une sélection dans le navigateur de fichiers</string>
|
||||
<string name="allow_copy_password_title">Copie de mot de passe</string>
|
||||
<string name="allow_copy_password_summary">Autoriser la copie du mot de passe dans le presse-papiers.</string>
|
||||
<string name="allow_copy_password_summary">Autoriser la copie du mot de passe et des champs protégés dans le presse-papiers.</string>
|
||||
<string name="allow_copy_password_warning">ATTENTION : Le presse-papiers est partagé par toutes les applications. Si des données sensibles sont copiés, d\'autres logiciels peuvent les récupérer.</string>
|
||||
<string name="warning_disabling_storage_access_framework">ATTENTION : désactiver cette fonctionnalité peut engendrer une impossibilité d\'ouvrir ou sauvegarder les bases de données</string>
|
||||
<string name="open_link_database">Lien du fichier Kdbx à ouvrir</string>
|
||||
<string name="database_name_title">Nom de la base de données</string>
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<bool name="sort_recycle_bin_bottom_default" translatable="false">true</bool>
|
||||
<bool name="monospace_font_fields_enable_default" translatable="false">true</bool>
|
||||
<bool name="auto_open_file_uri_default" translatable="false">true</bool>
|
||||
<bool name="allow_copy_password_default" translatable="false">true</bool>
|
||||
<bool name="allow_copy_password_default" translatable="false">false</bool>
|
||||
<bool name="enable_education_screens_default" translatable="false">true</bool>
|
||||
<bool name="education_create_db_default" translatable="false">false</bool>
|
||||
<bool name="education_select_db_default" translatable="false">false</bool>
|
||||
|
||||
@@ -215,7 +215,8 @@
|
||||
<string name="list_password_generator_options_summary">Set the default password generator characters</string>
|
||||
<string name="notifications">Notifications</string>
|
||||
<string name="clipboard_notifications_title">Clipboard Notifications</string>
|
||||
<string name="clipboard_notifications_summary">Enable clipboard notifications to copy username and password</string>
|
||||
<string name="clipboard_notifications_summary">Enable clipboard notifications to copy entry fields</string>
|
||||
<string name="clipboard_warning">Some devices are not able to automatically delete clips from the clipboard. If your manager does not allow this deletion, you will have to manually delete the copied item from your clipboard history.</string>
|
||||
<string name="lock">Lock</string>
|
||||
<string name="lock_database_screen_off_title">Screen lock</string>
|
||||
<string name="lock_database_screen_off_summary">Lock the database when the screen is off</string>
|
||||
@@ -253,7 +254,8 @@
|
||||
<string name="auto_open_file_uri_title">Auto open selected file</string>
|
||||
<string name="auto_open_file_uri_summary">Automatically open a file from the selection screen after a selection in the file browser</string>
|
||||
<string name="allow_copy_password_title">Copy of password</string>
|
||||
<string name="allow_copy_password_summary">Allow the copy of the password to the clipboard.</string>
|
||||
<string name="allow_copy_password_summary">Allow the copy of the password and protected fields to the clipboard.</string>
|
||||
<string name="allow_copy_password_warning">WARNING : The clipboard is shared by all applications. If sensitive data is copied, other software may recover it.</string>
|
||||
<string name="warning_disabling_storage_access_framework">WARNING : disabling this feature may result in an inability to open or save the databases</string>
|
||||
<string name="open_link_database">Link of the Kdbx file to open</string>
|
||||
<string name="database_name_title">Database name</string>
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
android:title="@string/clipboard_notifications_title"
|
||||
android:defaultValue="@bool/clipboard_notifications_default"
|
||||
android:summary="@string/clipboard_notifications_summary" />
|
||||
<SwitchPreference
|
||||
android:key="@string/allow_copy_password_key"
|
||||
android:title="@string/allow_copy_password_title"
|
||||
android:summary="@string/allow_copy_password_summary"
|
||||
android:defaultValue="@bool/allow_copy_password_default"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -3,6 +3,5 @@
|
||||
* New navigation in a single screen / new animations between activities
|
||||
* New icons for the material pack
|
||||
* New adaptive launcher icon
|
||||
* Added a setting to disable the open button when no password is identified
|
||||
* Added a setting to disable the education screens
|
||||
* Added a setting to disable the open button when no password is identified / the education screens / the copy of protected custom fields
|
||||
* Fix the fingerprint recognition (WARNING : The keystore is reinit, you must delete the old keys)
|
||||
@@ -3,6 +3,5 @@
|
||||
* Nouvelle navigation dans un seul écran / nouvelles animations entre activités
|
||||
* Nouveaux icones pour le pack material
|
||||
* Nouvel icone de lancement adaptatif
|
||||
* Ajout d'un paramètre pour désactiver le bouton d'ouverture quand aucun mot de passe n'est identifié
|
||||
* Ajout d'un paramètre pour désactiver les écrans d'éducation
|
||||
* Ajout d'un paramètre pour désactiver le bouton d'ouverture quand aucun mot de passe n'est identifié / les écrans d'éducation / la copie des champs customisés protégés
|
||||
* Correction de la reconnaissance des empreintes digitales (ATTENTION: le keystore est réinitialisé, vous devez supprimer les anciennes clés)
|
||||
Reference in New Issue
Block a user