mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Merge branch 'develop' into upstream-update
This commit is contained in:
@@ -2,7 +2,15 @@ KeepassDX (2.5.0.0beta4)
|
||||
* Merge KeePassDroid 2.2.1
|
||||
|
||||
KeepassDX (2.5.0.0beta3)
|
||||
* New database workflow with new screens and folder selection
|
||||
* Settings for default password generation
|
||||
* Fingerprint dialog for explanations
|
||||
* Setting to disable fingerprint
|
||||
* Directly opening kdbx file
|
||||
* Setting to disable notifications
|
||||
* Setting to lock database when screen is shut off
|
||||
* Merge KeePassDroid 2.2.0.9
|
||||
* Add corruption fix mode
|
||||
|
||||
KeepassDX (2.5.0.0beta2)
|
||||
* Remove libs for F-Droid
|
||||
|
||||
@@ -14,7 +14,7 @@ Tadashi Saito
|
||||
vhschlenker
|
||||
bumper314 - Samsung multiwindow support
|
||||
Hans Cappelle - fingerprint sensor integration
|
||||
Jeremy Jamet - Material Design - Patches
|
||||
Jeremy Jamet - Keepass DX Material Design - Patches
|
||||
|
||||
Translations:
|
||||
Diego Pierotto - Italian
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
|
||||
### Features
|
||||
|
||||
- Create database file / entries and groups
|
||||
- Simplified creation of the database file
|
||||
- Create entries and groups
|
||||
- Open database, copy username / password, open URI / URL
|
||||
- Fingerprint for fast unlocking
|
||||
- Material design with themes
|
||||
- Device integration and AutoFill (In progress)
|
||||
|
||||
<img src="https://raw.githubusercontent.com/Kunzisoft/KeePassDX/master/art/screen0.jpg" width="220">
|
||||
<img src="https://raw.githubusercontent.com/Kunzisoft/KeePassDX/master/art/screen1.jpg" width="220">
|
||||
<img src="https://raw.githubusercontent.com/Kunzisoft/KeePassDX/master/art/screen2.jpg" width="220">
|
||||
|
||||
## What is KeePass?
|
||||
|
||||
@@ -69,7 +69,10 @@ dependencies {
|
||||
compile "com.android.support:design:$supportVersion"
|
||||
compile "com.android.support:preference-v7:$supportVersion"
|
||||
compile "com.android.support:preference-v14:$supportVersion"
|
||||
compile "com.android.support:cardview-v7:$supportVersion"
|
||||
compile "com.madgag.spongycastle:core:$spongycastleVersion"
|
||||
compile "com.madgag.spongycastle:prov:$spongycastleVersion"
|
||||
compile "joda-time:joda-time:2.9.9"
|
||||
compile "org.sufficientlysecure:html-textview:3.5"
|
||||
compile "com.nononsenseapps:filepicker:4.1.0"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.kunzisoft.keepass"
|
||||
android:installLocation="auto">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.kunzisoft.keepass"
|
||||
android:installLocation="auto">
|
||||
<supports-screens
|
||||
android:smallScreens="true"
|
||||
android:normalScreens="true"
|
||||
@@ -19,10 +20,31 @@
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/backup"
|
||||
android:backupAgent="com.keepassdroid.backup.SettingsBackupAgent"
|
||||
android:theme="@style/KeepassDXStyle.Light">
|
||||
android:theme="@style/KeepassDXStyle.Light"
|
||||
tools:replace="android:theme">
|
||||
<!-- TODO backup API Key -->
|
||||
<meta-data android:name="com.google.android.backup.api_key"
|
||||
android:value="" />
|
||||
|
||||
<!-- Folder picker -->
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/nnf_provider_paths" />
|
||||
</provider>
|
||||
<activity
|
||||
android:name="com.keepassdroid.FilePickerStylishActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.GET_CONTENT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".KeePass"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
@@ -41,7 +63,8 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
<data android:host="*" />
|
||||
<data android:pathPattern=".*\\.kdb" />
|
||||
<data android:pathPattern=".*\\..*\\.kdb" />
|
||||
@@ -66,14 +89,10 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.keepassdroid.GroupActivityV3" android:configChanges="orientation|keyboardHidden">
|
||||
<!-- This metadata entry causes .app.SearchQueryResults to be the default context -->
|
||||
<!-- whenever the user invokes search while in this Activity. -->
|
||||
<meta-data android:name="android.app.default_searchable"
|
||||
android:value="com.keepassdroid.search.SearchResults" />
|
||||
</activity>
|
||||
<activity android:name="com.keepassdroid.GroupActivityV4" android:configChanges="orientation|keyboardHidden">
|
||||
<!-- This metadata entry causes .app.SearchQueryResults to be the default context -->
|
||||
<!-- whenever the user invokes search while in this Activity. -->
|
||||
<meta-data android:name="android.app.default_searchable"
|
||||
android:value="com.keepassdroid.search.SearchResults"
|
||||
android:exported="false" />
|
||||
|
||||
274
app/src/main/java/com/keepassdroid/AssignMasterKeyDialog.java
Normal file
274
app/src/main/java/com/keepassdroid/AssignMasterKeyDialog.java
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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 2 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.keepassdroid;
|
||||
|
||||
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.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.keepassdroid.utils.EmptyUtils;
|
||||
import com.keepassdroid.utils.UriUtil;
|
||||
import com.keepassdroid.view.KeyFileHelper;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public class AssignMasterKeyDialog extends DialogFragment {
|
||||
|
||||
private String masterPassword;
|
||||
private Uri mKeyfile;
|
||||
|
||||
private View rootView;
|
||||
private CompoundButton passwordCheckBox;
|
||||
private TextView passView;
|
||||
private TextView passConfView;
|
||||
private CompoundButton keyfileCheckBox;
|
||||
private TextView keyfileView;
|
||||
|
||||
private AssignPasswordDialogListener mListener;
|
||||
|
||||
private KeyFileHelper keyFileHelper;
|
||||
|
||||
public interface AssignPasswordDialogListener {
|
||||
void onAssignKeyDialogPositiveClick(boolean masterPasswordChecked, String masterPassword,
|
||||
boolean keyFileChecked, Uri keyFile);
|
||||
void onAssignKeyDialogNegativeClick(boolean masterPasswordChecked, String masterPassword,
|
||||
boolean keyFileChecked, Uri keyFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mListener = (AssignPasswordDialogListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement " + AssignPasswordDialogListener.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
|
||||
rootView = inflater.inflate(R.layout.set_password, null);
|
||||
builder.setView(rootView)
|
||||
.setTitle(R.string.assign_master_key)
|
||||
// Add action buttons
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
}
|
||||
});
|
||||
|
||||
passwordCheckBox = (CompoundButton) rootView.findViewById(R.id.password_checkbox);
|
||||
passView = (TextView) rootView.findViewById(R.id.pass_password);
|
||||
passView.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
passwordCheckBox.setChecked(true);
|
||||
}
|
||||
});
|
||||
passConfView = (TextView) rootView.findViewById(R.id.pass_conf_password);
|
||||
|
||||
keyfileCheckBox = (CompoundButton) rootView.findViewById(R.id.keyfile_checkox);
|
||||
keyfileView = (TextView) rootView.findViewById(R.id.pass_keyfile);
|
||||
keyfileView.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
keyfileCheckBox.setChecked(true);
|
||||
}
|
||||
});
|
||||
|
||||
keyFileHelper = new KeyFileHelper(this);
|
||||
rootView.findViewById(R.id.browse_button)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
keyFileHelper.getOpenFileOnClickViewListener().onClick(view);
|
||||
}
|
||||
});
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
|
||||
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||
@Override
|
||||
public void onShow(final DialogInterface dialog) {
|
||||
Button positiveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
positiveButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
|
||||
masterPassword = "";
|
||||
mKeyfile = null;
|
||||
|
||||
boolean error = verifyPassword() || verifyFile();
|
||||
|
||||
if (!passwordCheckBox.isChecked() && !keyfileCheckBox.isChecked()) {
|
||||
error = true;
|
||||
showNoKeyConfirmationDialog();
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
mListener.onAssignKeyDialogPositiveClick(
|
||||
passwordCheckBox.isChecked(), masterPassword,
|
||||
keyfileCheckBox.isChecked(), mKeyfile);
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
});
|
||||
Button negativeButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_NEGATIVE);
|
||||
negativeButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
mListener.onAssignKeyDialogNegativeClick(
|
||||
passwordCheckBox.isChecked(), masterPassword,
|
||||
keyfileCheckBox.isChecked(), mKeyfile);
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private boolean verifyPassword() {
|
||||
boolean error = false;
|
||||
if (passwordCheckBox.isChecked()) {
|
||||
masterPassword = passView.getText().toString();
|
||||
String confpass = passConfView.getText().toString();
|
||||
|
||||
// Verify that passwords match
|
||||
if (!masterPassword.equals(confpass)) {
|
||||
error = true;
|
||||
// Passwords do not match
|
||||
Toast.makeText(getContext(), R.string.error_pass_match, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
if (masterPassword == null || masterPassword.isEmpty()) {
|
||||
error = true;
|
||||
showEmptyPasswordConfirmationDialog();
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
private boolean verifyFile() {
|
||||
boolean error = false;
|
||||
if (keyfileCheckBox.isChecked()) {
|
||||
Uri keyfile = UriUtil.parseDefaultFile(keyfileView.getText().toString());
|
||||
mKeyfile = keyfile;
|
||||
|
||||
// Verify that a keyfile is set
|
||||
if (EmptyUtils.isNullOrEmpty(keyfile)) {
|
||||
error = true;
|
||||
Toast.makeText(getContext(), R.string.error_nokeyfile, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
private void showEmptyPasswordConfirmationDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setMessage(R.string.warning_empty_password)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
if (!verifyFile()) {
|
||||
mListener.onAssignKeyDialogPositiveClick(
|
||||
passwordCheckBox.isChecked(), masterPassword,
|
||||
keyfileCheckBox.isChecked(), mKeyfile);
|
||||
AssignMasterKeyDialog.this.dismiss();
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {}
|
||||
});
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
private void showNoKeyConfirmationDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setMessage(R.string.warning_no_encryption_key)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
mListener.onAssignKeyDialogPositiveClick(
|
||||
passwordCheckBox.isChecked(), masterPassword,
|
||||
keyfileCheckBox.isChecked(), mKeyfile);
|
||||
AssignMasterKeyDialog.this.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {}
|
||||
});
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
keyFileHelper.onActivityResultCallback(requestCode, resultCode, data,
|
||||
new KeyFileHelper.KeyFileCallback() {
|
||||
@Override
|
||||
public void onKeyFileResultCallback(Uri uri) {
|
||||
if(uri != null) {
|
||||
Uri pathString = UriUtil.parseDefaultFile(uri.toString());
|
||||
if (pathString != null) {
|
||||
keyfileCheckBox.setChecked(true);
|
||||
keyfileView.setText(pathString.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,42 +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 2 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.keepassdroid;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
|
||||
public class CancelDialog extends Dialog {
|
||||
|
||||
private boolean mCanceled = false;
|
||||
|
||||
public CancelDialog(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public boolean canceled() {
|
||||
return mCanceled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
super.cancel();
|
||||
mCanceled = true;
|
||||
}
|
||||
}
|
||||
182
app/src/main/java/com/keepassdroid/CreateFileDialog.java
Normal file
182
app/src/main/java/com/keepassdroid/CreateFileDialog.java
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright 2017 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 2 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.keepassdroid;
|
||||
|
||||
import android.app.Activity;
|
||||
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.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import com.keepassdroid.utils.UriUtil;
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.nononsenseapps.filepicker.FilePickerActivity;
|
||||
import com.nononsenseapps.filepicker.Utils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class CreateFileDialog extends DialogFragment implements AdapterView.OnItemSelectedListener{
|
||||
|
||||
private final int FILE_CODE = 3853;
|
||||
|
||||
private EditText folderPathView;
|
||||
private EditText fileNameView;
|
||||
private DefinePathDialogListener mListener;
|
||||
private String extension;
|
||||
|
||||
private Uri uriPath;
|
||||
|
||||
public interface DefinePathDialogListener {
|
||||
boolean onDefinePathDialogPositiveClick(Uri pathFile);
|
||||
boolean onDefinePathDialogNegativeClick(Uri pathFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mListener = (DefinePathDialogListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement " + DefinePathDialogListener.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
|
||||
View rootView = inflater.inflate(R.layout.file_creation, null);
|
||||
builder.setView(rootView)
|
||||
.setTitle(R.string.create_keepass_file)
|
||||
// Add action buttons
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {}
|
||||
});
|
||||
|
||||
// Folder selection
|
||||
View browseView = rootView.findViewById(R.id.browse_button);
|
||||
folderPathView = (EditText) rootView.findViewById(R.id.folder_path);
|
||||
fileNameView = (EditText) rootView.findViewById(R.id.filename);
|
||||
String defaultPath = Environment.getExternalStorageDirectory().getPath()
|
||||
+ getString(R.string.database_file_path_default);
|
||||
folderPathView.setText(defaultPath);
|
||||
browseView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent i = new Intent(getContext(), FilePickerStylishActivity.class);
|
||||
i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false);
|
||||
i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, true);
|
||||
i.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_DIR);
|
||||
i.putExtra(FilePickerActivity.EXTRA_START_PATH,
|
||||
Environment.getExternalStorageDirectory().getPath());
|
||||
startActivityForResult(i, FILE_CODE);
|
||||
}
|
||||
});
|
||||
|
||||
// Init path
|
||||
uriPath = null;
|
||||
|
||||
// Extension
|
||||
extension = getString(R.string.database_file_extension_default);
|
||||
Spinner spinner = (Spinner) rootView.findViewById(R.id.file_types);
|
||||
spinner.setOnItemSelectedListener(this);
|
||||
|
||||
// Spinner Drop down elements
|
||||
String[] fileTypes = getResources().getStringArray(R.array.file_types);
|
||||
ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, fileTypes);
|
||||
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(dataAdapter);
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
|
||||
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||
@Override
|
||||
public void onShow(final DialogInterface dialog) {
|
||||
Button positiveButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
positiveButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
if(mListener.onDefinePathDialogPositiveClick(buildPath()))
|
||||
CreateFileDialog.this.dismiss();
|
||||
}
|
||||
});
|
||||
Button negativeButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_NEGATIVE);
|
||||
negativeButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
if(mListener.onDefinePathDialogNegativeClick(buildPath()))
|
||||
CreateFileDialog.this.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == FILE_CODE && resultCode == Activity.RESULT_OK) {
|
||||
uriPath = data.getData();
|
||||
if (uriPath != null) {
|
||||
File file = Utils.getFileForUri(uriPath);
|
||||
folderPathView.setText(file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
|
||||
extension = adapterView.getItemAtPosition(position).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
private Uri buildPath() {
|
||||
Uri path = new Uri.Builder().path(folderPathView.getText().toString())
|
||||
.appendPath(fileNameView.getText().toString() + extension)
|
||||
.build();
|
||||
path = UriUtil.translate(getContext(), path);
|
||||
return path;
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,8 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.keepassdroid.settings.PrefsUtil.isClipboardNotificationsEnable;
|
||||
|
||||
public class EntryActivity extends LockCloseHideActivity {
|
||||
public static final String KEY_ENTRY = "entry";
|
||||
public static final String KEY_REFRESH_POS = "refresh_pos";
|
||||
@@ -153,7 +155,6 @@ public class EntryActivity extends LockCloseHideActivity {
|
||||
Intent i = getIntent();
|
||||
UUID uuid = Types.bytestoUUID(i.getByteArrayExtra(KEY_ENTRY));
|
||||
mPos = i.getIntExtra(KEY_REFRESH_POS, -1);
|
||||
assert(uuid != null);
|
||||
|
||||
mEntry = db.pm.entries.get(uuid);
|
||||
if (mEntry == null) {
|
||||
@@ -171,37 +172,41 @@ public class EntryActivity extends LockCloseHideActivity {
|
||||
fillData(false);
|
||||
|
||||
setupEditButtons();
|
||||
|
||||
// Notification Manager
|
||||
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
|
||||
if ( mEntry.getPassword().length() > 0 ) {
|
||||
// only show notification if password is available
|
||||
Notification password = getNotification(Intents.COPY_PASSWORD, R.string.copy_password);
|
||||
mNM.notify(NOTIFY_PASSWORD, password);
|
||||
}
|
||||
|
||||
if ( mEntry.getUsername().length() > 0 ) {
|
||||
// only show notification if username is available
|
||||
Notification username = getNotification(Intents.COPY_USERNAME, R.string.copy_username);
|
||||
mNM.notify(NOTIFY_USERNAME, username);
|
||||
}
|
||||
|
||||
// If notifications enabled in settings
|
||||
if (isClipboardNotificationsEnable(getApplicationContext())) {
|
||||
// Notification Manager
|
||||
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
|
||||
if (mEntry.getPassword().length() > 0) {
|
||||
// only show notification if password is available
|
||||
Notification password = getNotification(Intents.COPY_PASSWORD, R.string.copy_password);
|
||||
mNM.notify(NOTIFY_PASSWORD, password);
|
||||
}
|
||||
|
||||
if (mEntry.getUsername().length() > 0) {
|
||||
// only show notification if username is available
|
||||
Notification username = getNotification(Intents.COPY_USERNAME, R.string.copy_username);
|
||||
mNM.notify(NOTIFY_USERNAME, username);
|
||||
}
|
||||
}
|
||||
|
||||
mIntentReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
|
||||
if ( action.equals(Intents.COPY_USERNAME) ) {
|
||||
String username = mEntry.getUsername();
|
||||
if ( username.length() > 0 ) {
|
||||
timeoutCopyToClipboard(username);
|
||||
}
|
||||
} else if ( action.equals(Intents.COPY_PASSWORD) ) {
|
||||
String password = new String(mEntry.getPassword());
|
||||
if ( password.length() > 0 ) {
|
||||
timeoutCopyToClipboard(new String(mEntry.getPassword()));
|
||||
if ( action != null) {
|
||||
if (action.equals(Intents.COPY_USERNAME)) {
|
||||
String username = mEntry.getUsername();
|
||||
if (username.length() > 0) {
|
||||
timeoutCopyToClipboard(username);
|
||||
}
|
||||
} else if (action.equals(Intents.COPY_PASSWORD)) {
|
||||
String password = mEntry.getPassword();
|
||||
if (password.length() > 0) {
|
||||
timeoutCopyToClipboard(password);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2017 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 2 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.keepassdroid;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StyleRes;
|
||||
import android.util.Log;
|
||||
|
||||
import com.keepassdroid.stylish.Stylish;
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.nononsenseapps.filepicker.FilePickerActivity;
|
||||
|
||||
|
||||
public class FilePickerStylishActivity extends FilePickerActivity {
|
||||
|
||||
private @StyleRes
|
||||
int themeId;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
this.themeId = FilePickerStylish.getThemeId(this);
|
||||
setTheme(themeId);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if(FilePickerStylish.getThemeId(this) != this.themeId) {
|
||||
Log.d(this.getClass().getName(), "Theme change detected, restarting activity");
|
||||
this.recreate();
|
||||
}
|
||||
}
|
||||
|
||||
public static class FilePickerStylish extends Stylish {
|
||||
public static @StyleRes int getThemeId(Context context) {
|
||||
if (themeString.equals(context.getString(R.string.list_style_name_night)))
|
||||
return R.style.KeepassDXStyle_FilePickerStyle_Night;
|
||||
|
||||
return R.style.KeepassDXStyle_FilePickerStyle_Light;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,13 +30,16 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.keepassdroid.password.PasswordGenerator;
|
||||
import com.keepassdroid.settings.PrefsUtil;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class GeneratePasswordFragment extends DialogFragment {
|
||||
|
||||
@@ -46,6 +49,15 @@ public class GeneratePasswordFragment extends DialogFragment {
|
||||
private View root;
|
||||
private EditText lengthTextView;
|
||||
|
||||
private CompoundButton uppercaseBox;
|
||||
private CompoundButton lowercaseBox;
|
||||
private CompoundButton digitsBox;
|
||||
private CompoundButton minusBox;
|
||||
private CompoundButton underlineBox;
|
||||
private CompoundButton spaceBox;
|
||||
private CompoundButton specialsBox;
|
||||
private CompoundButton bracketsBox;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
@@ -66,6 +78,17 @@ public class GeneratePasswordFragment extends DialogFragment {
|
||||
|
||||
lengthTextView = (EditText) root.findViewById(R.id.length);
|
||||
|
||||
uppercaseBox = (CompoundButton) root.findViewById(R.id.cb_uppercase);
|
||||
lowercaseBox = (CompoundButton) root.findViewById(R.id.cb_lowercase);
|
||||
digitsBox = (CompoundButton) root.findViewById(R.id.cb_digits);
|
||||
minusBox = (CompoundButton) root.findViewById(R.id.cb_minus);
|
||||
underlineBox = (CompoundButton) root.findViewById(R.id.cb_underline);
|
||||
spaceBox = (CompoundButton) root.findViewById(R.id.cb_space);
|
||||
specialsBox = (CompoundButton) root.findViewById(R.id.cb_specials);
|
||||
bracketsBox = (CompoundButton) root.findViewById(R.id.cb_brackets);
|
||||
|
||||
assignDefaultCharacters();
|
||||
|
||||
SeekBar seekBar = (SeekBar) root.findViewById(R.id.seekbar_length);
|
||||
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
@@ -79,6 +102,7 @@ public class GeneratePasswordFragment extends DialogFragment {
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
});
|
||||
seekBar.setProgress(PrefsUtil.getDefaultPasswordLength(getContext().getApplicationContext()));
|
||||
|
||||
Button genPassButton = (Button) root.findViewById(R.id.generate_password_button);
|
||||
genPassButton.setOnClickListener(new OnClickListener() {
|
||||
@@ -113,6 +137,46 @@ public class GeneratePasswordFragment extends DialogFragment {
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private void assignDefaultCharacters() {
|
||||
uppercaseBox.setChecked(false);
|
||||
lowercaseBox.setChecked(false);
|
||||
digitsBox.setChecked(false);
|
||||
minusBox.setChecked(false);
|
||||
underlineBox.setChecked(false);
|
||||
spaceBox.setChecked(false);
|
||||
specialsBox.setChecked(false);
|
||||
bracketsBox.setChecked(false);
|
||||
|
||||
Set<String> defaultPasswordChars =
|
||||
PrefsUtil.getDefaultPasswordCharacters(getContext().getApplicationContext());
|
||||
for(String passwordChar : defaultPasswordChars) {
|
||||
if (passwordChar.equals(getString(R.string.value_password_uppercase))) {
|
||||
uppercaseBox.setChecked(true);
|
||||
}
|
||||
else if (passwordChar.equals(getString(R.string.value_password_lowercase))) {
|
||||
lowercaseBox.setChecked(true);
|
||||
}
|
||||
else if (passwordChar.equals(getString(R.string.value_password_digits))) {
|
||||
digitsBox.setChecked(true);
|
||||
}
|
||||
else if (passwordChar.equals(getString(R.string.value_password_minus))) {
|
||||
minusBox.setChecked(true);
|
||||
}
|
||||
else if (passwordChar.equals(getString(R.string.value_password_underline))) {
|
||||
underlineBox.setChecked(true);
|
||||
}
|
||||
else if (passwordChar.equals(getString(R.string.value_password_space))) {
|
||||
spaceBox.setChecked(true);
|
||||
}
|
||||
else if (passwordChar.equals(getString(R.string.value_password_special))) {
|
||||
specialsBox.setChecked(true);
|
||||
}
|
||||
else if (passwordChar.equals(getString(R.string.value_password_brackets))) {
|
||||
bracketsBox.setChecked(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fillPassword() {
|
||||
EditText txtPassword = (EditText) root.findViewById(R.id.password);
|
||||
@@ -121,23 +185,19 @@ public class GeneratePasswordFragment extends DialogFragment {
|
||||
|
||||
public String generatePassword() {
|
||||
String password = "";
|
||||
|
||||
try {
|
||||
int length = Integer.valueOf(((EditText) root.findViewById(R.id.length)).getText().toString());
|
||||
|
||||
((CheckBox) root.findViewById(R.id.cb_uppercase)).isChecked();
|
||||
|
||||
PasswordGenerator generator = new PasswordGenerator(getActivity());
|
||||
|
||||
password = generator.generatePassword(length,
|
||||
((CheckBox) root.findViewById(R.id.cb_uppercase)).isChecked(),
|
||||
((CheckBox) root.findViewById(R.id.cb_lowercase)).isChecked(),
|
||||
((CheckBox) root.findViewById(R.id.cb_digits)).isChecked(),
|
||||
((CheckBox) root.findViewById(R.id.cb_minus)).isChecked(),
|
||||
((CheckBox) root.findViewById(R.id.cb_underline)).isChecked(),
|
||||
((CheckBox) root.findViewById(R.id.cb_space)).isChecked(),
|
||||
((CheckBox) root.findViewById(R.id.cb_specials)).isChecked(),
|
||||
((CheckBox) root.findViewById(R.id.cb_brackets)).isChecked());
|
||||
uppercaseBox.isChecked(),
|
||||
lowercaseBox.isChecked(),
|
||||
digitsBox.isChecked(),
|
||||
minusBox.isChecked(),
|
||||
underlineBox.isChecked(),
|
||||
spaceBox.isChecked(),
|
||||
specialsBox.isChecked(),
|
||||
bracketsBox.isChecked());
|
||||
} catch (NumberFormatException e) {
|
||||
Toast.makeText(getContext(), R.string.error_wrong_length, Toast.LENGTH_LONG).show();
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.os.Build;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -41,8 +42,6 @@ import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.kunzisoft.keepass.KeePass;
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.compat.ActivityCompat;
|
||||
import com.keepassdroid.compat.EditorCompat;
|
||||
@@ -50,10 +49,14 @@ import com.keepassdroid.database.PwGroup;
|
||||
import com.keepassdroid.database.edit.OnFinish;
|
||||
import com.keepassdroid.search.SearchResultsActivity;
|
||||
import com.keepassdroid.utils.MenuUtil;
|
||||
import com.keepassdroid.view.AssignPasswordHelper;
|
||||
import com.keepassdroid.view.ClickView;
|
||||
import com.keepassdroid.view.GroupViewOnlyView;
|
||||
import com.kunzisoft.keepass.KeePass;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public abstract class GroupBaseActivity extends LockCloseListActivity {
|
||||
public abstract class GroupBaseActivity extends LockCloseListActivity
|
||||
implements AssignMasterKeyDialog.AssignPasswordDialogListener {
|
||||
protected ListView mList;
|
||||
protected ListAdapter mAdapter;
|
||||
|
||||
@@ -267,8 +270,26 @@ public abstract class GroupBaseActivity extends LockCloseListActivity {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAssignKeyDialogPositiveClick(
|
||||
boolean masterPasswordChecked, String masterPassword,
|
||||
boolean keyFileChecked, Uri keyFile) {
|
||||
|
||||
AssignPasswordHelper assignPasswordHelper =
|
||||
new AssignPasswordHelper(this,
|
||||
masterPassword, keyFile);
|
||||
assignPasswordHelper.assignPasswordInDatabase(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAssignKeyDialogNegativeClick(
|
||||
boolean masterPasswordChecked, String masterPassword,
|
||||
boolean keyFileChecked, Uri keyFile) {
|
||||
|
||||
}
|
||||
|
||||
private void setPassword() {
|
||||
SetPasswordDialog dialog = new SetPasswordDialog();
|
||||
AssignMasterKeyDialog dialog = new AssignMasterKeyDialog();
|
||||
dialog.show(getSupportFragmentManager(), "passwordDialog");
|
||||
}
|
||||
|
||||
|
||||
@@ -22,26 +22,8 @@ package com.keepassdroid;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
|
||||
import com.kunzisoft.keepass.KeePass;
|
||||
import com.keepassdroid.app.App;
|
||||
|
||||
public abstract class LockCloseActivity extends LockingActivity {
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
checkShutdown();
|
||||
}
|
||||
|
||||
private void checkShutdown() {
|
||||
if ( App.isShutdown() && App.getDB().Loaded() ) {
|
||||
setResult(KeePass.EXIT_LOCK);
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc) Workaround for HTC Linkify issues
|
||||
* @see android.app.Activity#startActivity(android.content.Intent)
|
||||
*/
|
||||
|
||||
@@ -20,23 +20,76 @@
|
||||
package com.keepassdroid;
|
||||
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.settings.PrefsUtil;
|
||||
import com.keepassdroid.stylish.StylishActivity;
|
||||
import com.keepassdroid.timeout.TimeoutHelper;
|
||||
import com.kunzisoft.keepass.KeePass;
|
||||
|
||||
|
||||
public abstract class LockingActivity extends StylishActivity {
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
TimeoutHelper.pause(this);
|
||||
}
|
||||
private ScreenReceiver screenReceiver;
|
||||
|
||||
@Override
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (PrefsUtil.isLockDatabaseWhenScreenShutOffEnable(this)) {
|
||||
screenReceiver = new ScreenReceiver();
|
||||
registerReceiver(screenReceiver, new IntentFilter((Intent.ACTION_SCREEN_OFF)));
|
||||
} else
|
||||
screenReceiver = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
checkShutdown();
|
||||
TimeoutHelper.resume(this);
|
||||
}
|
||||
|
||||
private void checkShutdown() {
|
||||
if ( App.isShutdown() && App.getDB().Loaded() ) {
|
||||
setResult(KeePass.EXIT_LOCK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
TimeoutHelper.pause(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(screenReceiver != null)
|
||||
unregisterReceiver(screenReceiver);
|
||||
}
|
||||
|
||||
public class ScreenReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
if(intent.getAction() != null) {
|
||||
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
if (PrefsUtil.isLockDatabaseWhenScreenShutOffEnable(LockingActivity.this)) {
|
||||
App.setShutdown();
|
||||
checkShutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
package com.keepassdroid;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
@@ -44,27 +43,28 @@ import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kunzisoft.keepass.KeePass;
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.compat.BackupManagerCompat;
|
||||
import com.keepassdroid.compat.ClipDataCompat;
|
||||
import com.keepassdroid.compat.EditorCompat;
|
||||
import com.keepassdroid.compat.StorageAF;
|
||||
import com.keepassdroid.database.edit.LoadDB;
|
||||
import com.keepassdroid.database.edit.OnFinish;
|
||||
import com.keepassdroid.dialog.PasswordEncodingDialogHelper;
|
||||
import com.keepassdroid.fileselect.BrowserDialog;
|
||||
import com.keepassdroid.fingerprint.FingerPrintAnimatedVector;
|
||||
import com.keepassdroid.fingerprint.FingerPrintHelper;
|
||||
import com.keepassdroid.intents.Intents;
|
||||
import com.keepassdroid.settings.PrefsUtil;
|
||||
import com.keepassdroid.utils.EmptyUtils;
|
||||
import com.keepassdroid.utils.Interaction;
|
||||
import com.keepassdroid.utils.MenuUtil;
|
||||
import com.keepassdroid.utils.UriUtil;
|
||||
import com.keepassdroid.utils.Util;
|
||||
import com.keepassdroid.view.FingerPrintDialog;
|
||||
import com.keepassdroid.view.KeyFileHelper;
|
||||
import com.kunzisoft.keepass.KeePass;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -80,10 +80,6 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
private static final String KEY_LAUNCH_IMMEDIATELY = "launchImmediately";
|
||||
private static final String VIEW_INTENT = "android.intent.action.VIEW";
|
||||
|
||||
private static final int FILE_BROWSE = 256;
|
||||
public static final int GET_CONTENT = 257;
|
||||
private static final int OPEN_DOC = 258;
|
||||
|
||||
private Uri mDbUri = null;
|
||||
private Uri mKeyUri = null;
|
||||
private boolean mRememberKeyfile;
|
||||
@@ -96,10 +92,19 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
private int mode;
|
||||
private static final String PREF_KEY_VALUE_PREFIX = "valueFor_"; // key is a combination of db file name and this prefix
|
||||
private static final String PREF_KEY_IV_PREFIX = "ivFor_"; // key is a combination of db file name and this prefix
|
||||
private View fingerprintView;
|
||||
private TextView confirmationView;
|
||||
|
||||
private View fingerprintContainerView;
|
||||
private View fingerprintImageView;
|
||||
private FingerPrintAnimatedVector fingerPrintAnimatedVector;
|
||||
private TextView fingerprintTextView;
|
||||
private TextView filenameView;
|
||||
private EditText passwordView;
|
||||
private Button confirmButton;
|
||||
private EditText keyFileView;
|
||||
private Button confirmButtonView;
|
||||
private CheckBox checkboxPasswordView;
|
||||
private CheckBox checkboxKeyfileView;
|
||||
|
||||
private KeyFileHelper keyFileHelper;
|
||||
|
||||
public static void Launch(
|
||||
Activity act,
|
||||
@@ -116,6 +121,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
}
|
||||
|
||||
Uri uri = UriUtil.parseDefaultFile(fileName);
|
||||
assert uri != null;
|
||||
String scheme = uri.getScheme();
|
||||
|
||||
if (!EmptyUtils.isNullOrEmpty(scheme) && scheme.equalsIgnoreCase("file")) {
|
||||
@@ -140,49 +146,30 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
keyFileHelper.onActivityResultCallback(requestCode, resultCode, data,
|
||||
new KeyFileHelper.KeyFileCallback() {
|
||||
@Override
|
||||
public void onKeyFileResultCallback(Uri uri) {
|
||||
if(uri != null) {
|
||||
keyFileView.setText(uri.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
switch (requestCode) {
|
||||
case KeePass.EXIT_NORMAL:
|
||||
setEditText(R.id.password, "");
|
||||
setEmptyViews();
|
||||
App.getDB().clear();
|
||||
break;
|
||||
|
||||
case KeePass.EXIT_LOCK:
|
||||
setResult(KeePass.EXIT_LOCK);
|
||||
setEditText(R.id.password, "");
|
||||
setEmptyViews();
|
||||
finish();
|
||||
App.getDB().clear();
|
||||
break;
|
||||
case FILE_BROWSE:
|
||||
if (resultCode == RESULT_OK) {
|
||||
String filename = data.getDataString();
|
||||
if (filename != null) {
|
||||
EditText fn = (EditText) findViewById(R.id.pass_keyfile);
|
||||
fn.setText(filename);
|
||||
mKeyUri = UriUtil.parseDefaultFile(filename);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GET_CONTENT:
|
||||
case OPEN_DOC:
|
||||
if (resultCode == RESULT_OK) {
|
||||
if (data != null) {
|
||||
Uri uri = data.getData();
|
||||
if (uri != null) {
|
||||
if (requestCode == GET_CONTENT) {
|
||||
uri = UriUtil.translate(this, uri);
|
||||
}
|
||||
String path = uri.toString();
|
||||
if (path != null) {
|
||||
EditText fn = (EditText) findViewById(R.id.pass_keyfile);
|
||||
fn.setText(path);
|
||||
|
||||
}
|
||||
mKeyUri = uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -204,10 +191,45 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
|
||||
confirmButton = (Button) findViewById(R.id.pass_ok);
|
||||
fingerprintView = findViewById(R.id.fingerprint);
|
||||
confirmationView = (TextView) findViewById(R.id.fingerprint_label);
|
||||
confirmButtonView = (Button) findViewById(R.id.pass_ok);
|
||||
fingerprintContainerView = findViewById(R.id.fingerprint_container);
|
||||
fingerprintImageView = findViewById(R.id.fingerprint_image);
|
||||
fingerprintTextView = (TextView) findViewById(R.id.fingerprint_label);
|
||||
filenameView = (TextView) findViewById(R.id.filename);
|
||||
passwordView = (EditText) findViewById(R.id.password);
|
||||
keyFileView = (EditText) findViewById(R.id.pass_keyfile);
|
||||
checkboxPasswordView = (CheckBox) findViewById(R.id.password_checkbox);
|
||||
checkboxKeyfileView = (CheckBox) findViewById(R.id.keyfile_checkox);
|
||||
|
||||
passwordView.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
checkboxPasswordView.setChecked(true);
|
||||
}
|
||||
});
|
||||
keyFileView.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
checkboxKeyfileView.setChecked(true);
|
||||
}
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
fingerPrintAnimatedVector = new FingerPrintAnimatedVector(this,
|
||||
(ImageView) fingerprintImageView);
|
||||
}
|
||||
|
||||
new InitTask().execute(i);
|
||||
}
|
||||
@@ -219,8 +241,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
// If the application was shutdown make sure to clear the password field, if it
|
||||
// was saved in the instance state
|
||||
if (App.isShutdown()) {
|
||||
TextView password = (TextView) findViewById(R.id.password);
|
||||
password.setText("");
|
||||
setEmptyViews();
|
||||
}
|
||||
|
||||
// Clear the shutdown flag
|
||||
@@ -230,13 +251,23 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
initForFingerprint();
|
||||
checkAvailability();
|
||||
if (fingerPrintAnimatedVector != null) {
|
||||
fingerPrintAnimatedVector.startScan();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setEmptyViews() {
|
||||
passwordView.setText("");
|
||||
keyFileView.setText("");
|
||||
checkboxPasswordView.setChecked(false);
|
||||
checkboxKeyfileView.setChecked(false);
|
||||
}
|
||||
|
||||
private void retrieveSettings() {
|
||||
String defaultFilename = prefs.getString(KEY_DEFAULT_FILENAME, "");
|
||||
if (!EmptyUtils.isNullOrEmpty(mDbUri.getPath()) && UriUtil.equalsDefaultfile(mDbUri, defaultFilename)) {
|
||||
CheckBox checkbox = (CheckBox) findViewById(R.id.default_database);
|
||||
CompoundButton checkbox = (CompoundButton) findViewById(R.id.default_database);
|
||||
checkbox.setChecked(true);
|
||||
}
|
||||
}
|
||||
@@ -251,14 +282,12 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
|
||||
private void populateView() {
|
||||
String db = (mDbUri == null) ? "" : mDbUri.toString();
|
||||
setEditText(R.id.filename, db);
|
||||
if (!db.isEmpty())
|
||||
filenameView.setText(db);
|
||||
|
||||
String key = (mKeyUri == null) ? "" : mKeyUri.toString();
|
||||
setEditText(R.id.pass_keyfile, key);
|
||||
}
|
||||
|
||||
private void errorMessage(int resId) {
|
||||
Toast.makeText(this, resId, Toast.LENGTH_LONG).show();
|
||||
if (!key.isEmpty())
|
||||
keyFileView.setText(key);
|
||||
}
|
||||
|
||||
// fingerprint related code here
|
||||
@@ -287,7 +316,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
if ( !fingerprintMustBeConfigured ) {
|
||||
final boolean validInput = s.length() > 0;
|
||||
// encrypt or decrypt mode based on how much input or not
|
||||
confirmationView.setText(validInput ? R.string.store_with_fingerprint : R.string.scanning_fingerprint);
|
||||
fingerprintTextView.setText(validInput ? R.string.store_with_fingerprint : R.string.scanning_fingerprint);
|
||||
mode = validInput ? toggleMode(Cipher.ENCRYPT_MODE) : toggleMode(Cipher.DECRYPT_MODE);
|
||||
}
|
||||
}
|
||||
@@ -304,7 +333,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
// errorCode = 5
|
||||
// errString = "Fingerprint operation canceled."
|
||||
//onFingerprintException();
|
||||
//confirmationView.setText(errString);
|
||||
//fingerprintTextView.setText(errString);
|
||||
// true false fingerprint readings are handled otherwise with the toast messages, see below in code
|
||||
}
|
||||
|
||||
@@ -314,7 +343,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
final CharSequence helpString) {
|
||||
|
||||
onFingerprintException(new Exception("onAuthenticationHelp"));
|
||||
confirmationView.setText(helpString);
|
||||
fingerprintTextView.setText(helpString);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -370,6 +399,12 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& fingerPrintAnimatedVector != null) {
|
||||
fingerPrintAnimatedVector.stopScan();
|
||||
}
|
||||
|
||||
// stop listening when we go in background
|
||||
if (fingerPrintHelper != null) {
|
||||
fingerPrintHelper.stopListening();
|
||||
@@ -377,42 +412,50 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
}
|
||||
|
||||
private void setFingerPrintVisibility(int vis) {
|
||||
fingerprintView.setVisibility(vis);
|
||||
confirmationView.setVisibility(vis);
|
||||
fingerprintContainerView.setVisibility(vis);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
private void checkAvailability() {
|
||||
|
||||
// fingerprint not supported (by API level or hardware) so keep option hidden
|
||||
if (!fingerPrintHelper.isFingerprintSupported(FingerprintManagerCompat.from(this))) {
|
||||
// or manually disable
|
||||
if (!PrefsUtil.isFingerprintEnable(getApplicationContext())
|
||||
|| !fingerPrintHelper.isFingerprintSupported(FingerprintManagerCompat.from(this))) {
|
||||
setFingerPrintVisibility(View.GONE);
|
||||
}
|
||||
// fingerprint is available but not configured show icon but in disabled state with some information
|
||||
else if (!fingerPrintHelper.hasEnrolledFingerprints()) {
|
||||
|
||||
setFingerPrintVisibility(View.VISIBLE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
fingerprintView.setAlpha(0.3f);
|
||||
}
|
||||
// This happens when no fingerprints are registered. Listening won't start
|
||||
confirmationView.setText(R.string.configure_fingerprint);
|
||||
}
|
||||
// finally fingerprint available and configured so we can use it
|
||||
else {
|
||||
fingerprintMustBeConfigured = false;
|
||||
// show explanations
|
||||
fingerprintContainerView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
FingerPrintDialog fingerPrintDialog = new FingerPrintDialog();
|
||||
fingerPrintDialog.show(getSupportFragmentManager(), "fingerprintDialog");
|
||||
}
|
||||
});
|
||||
setFingerPrintVisibility(View.VISIBLE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
fingerprintView.setAlpha(1f);
|
||||
|
||||
if (!fingerPrintHelper.hasEnrolledFingerprints()) {
|
||||
fingerprintImageView.setAlpha(0.3f);
|
||||
// This happens when no fingerprints are registered. Listening won't start
|
||||
fingerprintTextView.setText(R.string.configure_fingerprint);
|
||||
}
|
||||
// fingerprint available but no stored password found yet for this DB so show info don't listen
|
||||
if (prefsNoBackup.getString(getPreferenceKeyValue(), null) == null) {
|
||||
confirmationView.setText(R.string.no_password_stored);
|
||||
}
|
||||
// all is set here so we can confirm to user and start listening for fingerprints
|
||||
// finally fingerprint available and configured so we can use it
|
||||
else {
|
||||
confirmationView.setText(R.string.scanning_fingerprint);
|
||||
// listen for decryption by default
|
||||
toggleMode(Cipher.DECRYPT_MODE);
|
||||
fingerprintMustBeConfigured = false;
|
||||
fingerprintImageView.setAlpha(1f);
|
||||
|
||||
// fingerprint available but no stored password found yet for this DB so show info don't listen
|
||||
if (prefsNoBackup.getString(getPreferenceKeyValue(), null) == null) {
|
||||
fingerprintTextView.setText(R.string.no_password_stored);
|
||||
}
|
||||
// all is set here so we can confirm to user and start listening for fingerprints
|
||||
else {
|
||||
fingerprintTextView.setText(R.string.scanning_fingerprint);
|
||||
// listen for decryption by default
|
||||
toggleMode(Cipher.DECRYPT_MODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,15 +470,15 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
.putString(getPreferenceKeyIvSpec(), ivSpec)
|
||||
.apply();
|
||||
// and remove visual input to reset UI
|
||||
confirmButton.performClick();
|
||||
confirmationView.setText(R.string.encrypted_value_stored);
|
||||
confirmButtonView.performClick();
|
||||
fingerprintTextView.setText(R.string.encrypted_value_stored);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDecryptedResult(final String value) {
|
||||
// on decrypt enter it for the purchase/login action
|
||||
passwordView.setText(value);
|
||||
confirmButton.performClick();
|
||||
confirmButtonView.performClick();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
@@ -482,8 +525,8 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
private class OkClickHandler implements View.OnClickListener {
|
||||
|
||||
public void onClick(View view) {
|
||||
String pass = getEditText(R.id.password);
|
||||
String key = getEditText(R.id.pass_keyfile);
|
||||
String pass = passwordView.getText().toString();
|
||||
String key = keyFileView.getText().toString();
|
||||
loadDatabase(pass, key);
|
||||
}
|
||||
}
|
||||
@@ -497,10 +540,6 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
private void loadDatabase(
|
||||
String pass,
|
||||
Uri keyfile) {
|
||||
if (pass.length() == 0 && (keyfile == null || keyfile.toString().length() == 0)) {
|
||||
errorMessage(R.string.error_nopass);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear before we load
|
||||
Database db = App.getDB();
|
||||
@@ -509,6 +548,13 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
// Clear the shutdown flag
|
||||
App.clearShutdown();
|
||||
|
||||
if (!checkboxPasswordView.isChecked()) {
|
||||
pass = "";
|
||||
}
|
||||
if (!checkboxKeyfileView.isChecked()) {
|
||||
keyfile = null;
|
||||
}
|
||||
|
||||
Handler handler = new Handler();
|
||||
LoadDB task = new LoadDB(db, PasswordActivity.this, mDbUri, pass, keyfile, new AfterLoad(handler, db));
|
||||
ProgressTask pt = new ProgressTask(PasswordActivity.this, task, R.string.loading_database);
|
||||
@@ -519,15 +565,6 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
return Util.getEditText(this, resId);
|
||||
}
|
||||
|
||||
private void setEditText(
|
||||
int resId,
|
||||
String str) {
|
||||
TextView te = (TextView) findViewById(resId);
|
||||
if (te != null) {
|
||||
te.setText(str);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
@@ -554,7 +591,7 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
|
||||
private Database db;
|
||||
|
||||
public AfterLoad(
|
||||
AfterLoad(
|
||||
Handler handler,
|
||||
Database db) {
|
||||
super(handler);
|
||||
@@ -654,69 +691,15 @@ public class PasswordActivity extends LockingActivity implements FingerPrintHelp
|
||||
confirmButton.setOnClickListener(new OkClickHandler());
|
||||
|
||||
if (password != null) {
|
||||
TextView tv_password = (TextView) findViewById(R.id.password);
|
||||
tv_password.setText(password);
|
||||
passwordView.setText(password);
|
||||
}
|
||||
|
||||
CheckBox defaultCheck = (CheckBox) findViewById(R.id.default_database);
|
||||
CompoundButton defaultCheck = (CompoundButton) findViewById(R.id.default_database);
|
||||
defaultCheck.setOnCheckedChangeListener(new DefaultCheckChange());
|
||||
|
||||
View browse = findViewById(R.id.browse_button);
|
||||
browse.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
if (StorageAF.useStorageFramework(PasswordActivity.this)) {
|
||||
Intent i = new Intent(StorageAF.ACTION_OPEN_DOCUMENT);
|
||||
i.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
i.setType("*/*");
|
||||
startActivityForResult(i, OPEN_DOC);
|
||||
} else {
|
||||
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
i.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
i.setType("*/*");
|
||||
|
||||
try {
|
||||
startActivityForResult(i, GET_CONTENT);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
lookForOpenIntentsFilePicker();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void lookForOpenIntentsFilePicker() {
|
||||
if (Interaction.isIntentAvailable(PasswordActivity.this, Intents.OPEN_INTENTS_FILE_BROWSE)) {
|
||||
Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE);
|
||||
|
||||
// Get file path parent if possible
|
||||
try {
|
||||
if (mDbUri != null && mDbUri.toString().length() > 0) {
|
||||
if (mDbUri.getScheme().equals("file")) {
|
||||
File keyfile = new File(mDbUri.getPath());
|
||||
File parent = keyfile.getParentFile();
|
||||
if (parent != null) {
|
||||
i.setData(Uri.parse("file://" + parent.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
try {
|
||||
startActivityForResult(i, FILE_BROWSE);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
showBrowserDialog();
|
||||
}
|
||||
} else {
|
||||
showBrowserDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private void showBrowserDialog() {
|
||||
BrowserDialog browserDialog = new BrowserDialog(PasswordActivity.this);
|
||||
browserDialog.show();
|
||||
}
|
||||
});
|
||||
View browseView = findViewById(R.id.browse_button);
|
||||
keyFileHelper = new KeyFileHelper(PasswordActivity.this);
|
||||
browseView.setOnClickListener(keyFileHelper.getOpenFileOnClickViewListener());
|
||||
|
||||
retrieveSettings();
|
||||
|
||||
|
||||
@@ -1,156 +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 2 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.keepassdroid;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.database.edit.FileOnFinish;
|
||||
import com.keepassdroid.database.edit.OnFinish;
|
||||
import com.keepassdroid.database.edit.SetPassword;
|
||||
import com.keepassdroid.utils.EmptyUtils;
|
||||
import com.keepassdroid.utils.UriUtil;
|
||||
|
||||
public class SetPasswordDialog extends DialogFragment {
|
||||
|
||||
private final static String FINISH_TAG = "FINISH_TAG";
|
||||
|
||||
private byte[] masterKey;
|
||||
private Uri mKeyfile;
|
||||
private FileOnFinish mFinish;
|
||||
private View rootView;
|
||||
|
||||
public byte[] getKey() {
|
||||
return masterKey;
|
||||
}
|
||||
|
||||
public Uri keyfile() {
|
||||
return mKeyfile;
|
||||
}
|
||||
|
||||
public static SetPasswordDialog newInstance(FileOnFinish finish) {
|
||||
SetPasswordDialog setPasswordDialog = new SetPasswordDialog();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(FINISH_TAG, finish);
|
||||
setPasswordDialog.setArguments(args);
|
||||
|
||||
return setPasswordDialog;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
|
||||
if(getArguments() != null && getArguments().containsKey(FINISH_TAG)) {
|
||||
mFinish = (FileOnFinish) getArguments().getSerializable(FINISH_TAG);
|
||||
}
|
||||
|
||||
rootView = inflater.inflate(R.layout.set_password, null);
|
||||
builder.setView(rootView)
|
||||
// Add action buttons
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
TextView passView = (TextView) rootView.findViewById(R.id.pass_password);
|
||||
String pass = passView.getText().toString();
|
||||
TextView passConfView = (TextView) rootView.findViewById(R.id.pass_conf_password);
|
||||
String confpass = passConfView.getText().toString();
|
||||
|
||||
// Verify that passwords match
|
||||
if ( ! pass.equals(confpass) ) {
|
||||
// Passwords do not match
|
||||
Toast.makeText(getContext(), R.string.error_pass_match, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
TextView keyfileView = (TextView) rootView.findViewById(R.id.pass_keyfile);
|
||||
Uri keyfile = UriUtil.parseDefaultFile(keyfileView.getText().toString());
|
||||
mKeyfile = keyfile;
|
||||
|
||||
// Verify that a password or keyfile is set
|
||||
if ( pass.length() == 0 && EmptyUtils.isNullOrEmpty(keyfile)) {
|
||||
Toast.makeText(getContext(), R.string.error_nopass, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
SetPassword sp = new SetPassword(getContext(), App.getDB(), pass, keyfile, new AfterSave(mFinish, new Handler()));
|
||||
final ProgressTask pt = new ProgressTask(getContext(), sp, R.string.saving_database);
|
||||
boolean valid = sp.validatePassword(getContext(), new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
pt.run();
|
||||
}
|
||||
});
|
||||
|
||||
if (valid) {
|
||||
pt.run();
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
SetPasswordDialog.this.getDialog().cancel();
|
||||
if ( mFinish != null ) {
|
||||
mFinish.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private class AfterSave extends OnFinish {
|
||||
private FileOnFinish mFinish;
|
||||
|
||||
public AfterSave(FileOnFinish finish, Handler handler) {
|
||||
super(finish, handler);
|
||||
mFinish = finish;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mSuccess ) {
|
||||
if ( mFinish != null ) {
|
||||
mFinish.setFilename(mKeyfile);
|
||||
}
|
||||
dismiss();
|
||||
} else {
|
||||
displayMessage(getContext());
|
||||
}
|
||||
super.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.keepassdroid;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public class UnavailableFeatureDialog extends DialogFragment {
|
||||
|
||||
private static final String MIN_REQUIRED_VERSION_ARG = "MIN_REQUIRED_VERSION_ARG";
|
||||
private int minVersionRequired = Build.VERSION_CODES.M;
|
||||
|
||||
public static UnavailableFeatureDialog getInstance(int minVersionRequired) {
|
||||
UnavailableFeatureDialog fragment = new UnavailableFeatureDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(MIN_REQUIRED_VERSION_ARG, minVersionRequired);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
if (getArguments() != null && getArguments().containsKey(MIN_REQUIRED_VERSION_ARG))
|
||||
minVersionRequired = getArguments().getInt(MIN_REQUIRED_VERSION_ARG);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setMessage(getString(R.string.unavailable_feature_text, Build.VERSION.SDK_INT, minVersionRequired))
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) { }
|
||||
});
|
||||
return builder.create();
|
||||
}
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
throws InvalidKeyFileException, IOException {
|
||||
assert(key != null);
|
||||
|
||||
byte[] fKey;
|
||||
byte[] fKey = new byte[]{};
|
||||
|
||||
if ( key.length() > 0 && keyInputStream != null) {
|
||||
return getCompositeKey(key, keyInputStream);
|
||||
@@ -137,8 +137,6 @@ public class PwDatabaseV4 extends PwDatabase {
|
||||
fKey = getPasswordKey(key);
|
||||
} else if ( keyInputStream != null) {
|
||||
fKey = getFileKey(keyInputStream);
|
||||
} else {
|
||||
throw new IllegalArgumentException( "Key cannot be empty." );
|
||||
}
|
||||
|
||||
MessageDigest md;
|
||||
|
||||
@@ -19,20 +19,14 @@
|
||||
*/
|
||||
package com.keepassdroid.database.edit;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.keepassdroid.Database;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.PwDatabaseV3;
|
||||
import com.keepassdroid.database.PwEncryptionAlgorithm;
|
||||
import com.keepassdroid.utils.UriUtil;
|
||||
|
||||
public class CreateDB extends RunnableOnFinish {
|
||||
|
||||
private final int DEFAULT_ENCRYPTION_ROUNDS = 300;
|
||||
|
||||
private String mFilename;
|
||||
private boolean mDontSave;
|
||||
@@ -57,7 +51,6 @@ public class CreateDB extends RunnableOnFinish {
|
||||
|
||||
// Set Database state
|
||||
db.pm = pm;
|
||||
Uri.Builder b = new Uri.Builder();
|
||||
db.mUri = UriUtil.parseDefaultFile(mFilename);
|
||||
db.setLoaded();
|
||||
App.clearShutdown();
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
*/
|
||||
package com.keepassdroid.database.edit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.net.Uri;
|
||||
@@ -32,6 +29,9 @@ import com.keepassdroid.database.exception.InvalidKeyFileException;
|
||||
import com.keepassdroid.dialog.PasswordEncodingDialogHelper;
|
||||
import com.keepassdroid.utils.UriUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class SetPassword extends RunnableOnFinish {
|
||||
|
||||
private String mPassword;
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
*/
|
||||
package com.keepassdroid.fileselect;
|
||||
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
@@ -34,6 +34,7 @@ import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.Menu;
|
||||
@@ -43,17 +44,16 @@ import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.keepassdroid.AssignMasterKeyDialog;
|
||||
import com.keepassdroid.CreateFileDialog;
|
||||
import com.keepassdroid.GroupActivity;
|
||||
import com.keepassdroid.PasswordActivity;
|
||||
import com.keepassdroid.ProgressTask;
|
||||
import com.keepassdroid.SetPasswordDialog;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.compat.ContentResolverCompat;
|
||||
import com.keepassdroid.compat.StorageAF;
|
||||
@@ -67,19 +67,25 @@ import com.keepassdroid.utils.Interaction;
|
||||
import com.keepassdroid.utils.MenuUtil;
|
||||
import com.keepassdroid.utils.UriUtil;
|
||||
import com.keepassdroid.utils.Util;
|
||||
import com.keepassdroid.view.AssignPasswordHelper;
|
||||
import com.keepassdroid.view.FileNameView;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URLDecoder;
|
||||
|
||||
public class FileSelectActivity extends StylishActivity {
|
||||
public class FileSelectActivity extends StylishActivity implements
|
||||
CreateFileDialog.DefinePathDialogListener ,
|
||||
AssignMasterKeyDialog.AssignPasswordDialogListener {
|
||||
|
||||
private static final String TAG = "FileSelectActivity";
|
||||
|
||||
private static final int MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE = 111;
|
||||
private ListView mList;
|
||||
private ListAdapter mAdapter;
|
||||
private BaseAdapter mAdapter;
|
||||
|
||||
private static final int CMENU_CLEAR = Menu.FIRST;
|
||||
|
||||
@@ -91,18 +97,23 @@ public class FileSelectActivity extends StylishActivity {
|
||||
|
||||
private boolean recentMode = false;
|
||||
|
||||
private EditText openFileNameView;
|
||||
|
||||
private AssignPasswordHelper assignPasswordHelper;
|
||||
private Uri databaseUri;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
fileHistory = App.getFileHistory();
|
||||
|
||||
setContentView(R.layout.file_selection);
|
||||
if (fileHistory.hasRecentFiles()) {
|
||||
recentMode = true;
|
||||
setContentView(R.layout.file_selection);
|
||||
} else {
|
||||
setContentView(R.layout.file_selection_no_recent);
|
||||
}
|
||||
findViewById(R.id.file_listtop).setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(getString(R.string.app_name));
|
||||
@@ -111,22 +122,20 @@ public class FileSelectActivity extends StylishActivity {
|
||||
mList = (ListView)findViewById(R.id.file_list);
|
||||
|
||||
mList.setOnItemClickListener(
|
||||
new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
|
||||
{
|
||||
onListItemClick((ListView)parent, v, position, id);
|
||||
}
|
||||
}
|
||||
new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
|
||||
onListItemClick((ListView)parent, v, position, id);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Open button
|
||||
Button openButton = (Button) findViewById(R.id.open);
|
||||
View openButton = findViewById(R.id.open_database);
|
||||
openButton.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
String fileName = Util.getEditText(FileSelectActivity.this,
|
||||
R.id.file_filename);
|
||||
|
||||
try {
|
||||
PasswordActivity.Launch(FileSelectActivity.this, fileName);
|
||||
}
|
||||
@@ -138,80 +147,16 @@ public class FileSelectActivity extends StylishActivity {
|
||||
Toast.makeText(FileSelectActivity.this,
|
||||
R.string.FileNotFound, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Create button
|
||||
Button createButton = (Button) findViewById(R.id.create);
|
||||
View createButton = findViewById(R.id.create_database);
|
||||
createButton.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
String filename = Util.getEditText(FileSelectActivity.this,
|
||||
R.id.file_filename);
|
||||
|
||||
// Make sure file name exists
|
||||
if (filename.length() == 0) {
|
||||
Toast
|
||||
.makeText(FileSelectActivity.this,
|
||||
R.string.error_filename_required,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to create the file
|
||||
File file = new File(filename);
|
||||
try {
|
||||
if (file.exists()) {
|
||||
Toast.makeText(FileSelectActivity.this,
|
||||
R.string.error_database_exists,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
File parent = file.getParentFile();
|
||||
|
||||
if ( parent == null || (parent.exists() && ! parent.isDirectory()) ) {
|
||||
Toast.makeText(FileSelectActivity.this,
|
||||
R.string.error_invalid_path,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! parent.exists() ) {
|
||||
// Create parent dircetory
|
||||
if ( ! parent.mkdirs() ) {
|
||||
Toast.makeText(FileSelectActivity.this,
|
||||
R.string.error_could_not_create_parent,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(
|
||||
FileSelectActivity.this,
|
||||
getText(R.string.error_file_not_create) + " "
|
||||
+ e.getLocalizedMessage(),
|
||||
Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// Prep an object to collect a password once the database has
|
||||
// been created
|
||||
CollectPassword password = new CollectPassword(
|
||||
new LaunchGroupActivity(filename));
|
||||
|
||||
// Create the new database
|
||||
CreateDB create = new CreateDB(FileSelectActivity.this, filename, password, true);
|
||||
ProgressTask createTask = new ProgressTask(
|
||||
FileSelectActivity.this, create,
|
||||
R.string.progress_create);
|
||||
createTask.run();
|
||||
|
||||
CreateFileDialog createFileDialog = new CreateFileDialog();
|
||||
createFileDialog.show(getSupportFragmentManager(), "createFileDialog");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
View browseButton = findViewById(R.id.browse_button);
|
||||
@@ -222,7 +167,9 @@ public class FileSelectActivity extends StylishActivity {
|
||||
Intent i = new Intent(StorageAF.ACTION_OPEN_DOCUMENT);
|
||||
i.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
i.setType("*/*");
|
||||
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
||||
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|
|
||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION|
|
||||
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
||||
startActivityForResult(i, OPEN_DOC);
|
||||
}
|
||||
else {
|
||||
@@ -242,7 +189,6 @@ public class FileSelectActivity extends StylishActivity {
|
||||
}
|
||||
|
||||
private void lookForOpenIntentsFilePicker() {
|
||||
|
||||
if (Interaction.isIntentAvailable(FileSelectActivity.this, Intents.OPEN_INTENTS_FILE_BROWSE)) {
|
||||
Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE);
|
||||
i.setData(Uri.parse("file://" + Util.getEditText(FileSelectActivity.this, R.id.file_filename)));
|
||||
@@ -251,7 +197,6 @@ public class FileSelectActivity extends StylishActivity {
|
||||
} catch (ActivityNotFoundException e) {
|
||||
showBrowserDialog();
|
||||
}
|
||||
|
||||
} else {
|
||||
showBrowserDialog();
|
||||
}
|
||||
@@ -263,6 +208,14 @@ public class FileSelectActivity extends StylishActivity {
|
||||
}
|
||||
});
|
||||
|
||||
// Set the initial value of the filename
|
||||
openFileNameView = (EditText) findViewById(R.id.file_filename);
|
||||
String defaultPath = Environment.getExternalStorageDirectory().getAbsolutePath()
|
||||
+ getString(R.string.database_file_path_default)
|
||||
+ getString(R.string.database_file_name_default)
|
||||
+ getString(R.string.database_file_extension_default);
|
||||
openFileNameView.setText(defaultPath);
|
||||
|
||||
fillData();
|
||||
|
||||
registerForContextMenu(mList);
|
||||
@@ -273,7 +226,9 @@ public class FileSelectActivity extends StylishActivity {
|
||||
|
||||
if (fileName.length() > 0) {
|
||||
Uri dbUri = UriUtil.parseDefaultFile(fileName);
|
||||
String scheme = dbUri.getScheme();
|
||||
String scheme = null;
|
||||
if (dbUri!=null)
|
||||
scheme = dbUri.getScheme();
|
||||
|
||||
if (!EmptyUtils.isNullOrEmpty(scheme) && scheme.equalsIgnoreCase("file")) {
|
||||
String path = dbUri.getPath();
|
||||
@@ -297,12 +252,135 @@ public class FileSelectActivity extends StylishActivity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create file for database
|
||||
* @return If not created, return false
|
||||
*/
|
||||
private boolean createDatabaseFile(Uri path) {
|
||||
|
||||
String pathString = URLDecoder.decode(path.getPath());
|
||||
// Make sure file name exists
|
||||
if (pathString.length() == 0) {
|
||||
Log.e(TAG, getString(R.string.error_filename_required));
|
||||
Toast.makeText(FileSelectActivity.this,
|
||||
R.string.error_filename_required,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to create the file
|
||||
File file = new File(pathString);
|
||||
try {
|
||||
if (file.exists()) {
|
||||
Log.e(TAG, getString(R.string.error_database_exists) + " " + file);
|
||||
Toast.makeText(FileSelectActivity.this,
|
||||
R.string.error_database_exists,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
File parent = file.getParentFile();
|
||||
|
||||
if ( parent == null || (parent.exists() && ! parent.isDirectory()) ) {
|
||||
Log.e(TAG, getString(R.string.error_invalid_path) + " " + file);
|
||||
Toast.makeText(FileSelectActivity.this,
|
||||
R.string.error_invalid_path,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! parent.exists() ) {
|
||||
// Create parent directory
|
||||
if ( ! parent.mkdirs() ) {
|
||||
Log.e(TAG, getString(R.string.error_could_not_create_parent) + " " + parent);
|
||||
Toast.makeText(FileSelectActivity.this,
|
||||
R.string.error_could_not_create_parent,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, getString(R.string.error_could_not_create_parent) + " " + e.getLocalizedMessage());
|
||||
e.printStackTrace();
|
||||
Toast.makeText(
|
||||
FileSelectActivity.this,
|
||||
getText(R.string.error_file_not_create) + " "
|
||||
+ e.getLocalizedMessage(),
|
||||
Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDefinePathDialogPositiveClick(Uri pathFile) {
|
||||
databaseUri = pathFile;
|
||||
if(createDatabaseFile(pathFile)) {
|
||||
AssignMasterKeyDialog assignMasterKeyDialog = new AssignMasterKeyDialog();
|
||||
assignMasterKeyDialog.show(getSupportFragmentManager(), "passwordDialog");
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDefinePathDialogNegativeClick(Uri pathFile) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAssignKeyDialogPositiveClick(
|
||||
boolean masterPasswordChecked, String masterPassword,
|
||||
boolean keyFileChecked, Uri keyFile) {
|
||||
|
||||
String databaseFilename = databaseUri.getPath();
|
||||
|
||||
// Prep an object to collect a password once the database has
|
||||
// been created
|
||||
FileOnFinish launchActivityOnFinish = new FileOnFinish(
|
||||
new LaunchGroupActivity(databaseFilename));
|
||||
AssignPasswordOnFinish assignPasswordOnFinish =
|
||||
new AssignPasswordOnFinish(launchActivityOnFinish);
|
||||
|
||||
// Create the new database
|
||||
CreateDB create = new CreateDB(FileSelectActivity.this,
|
||||
databaseFilename, assignPasswordOnFinish, true);
|
||||
|
||||
ProgressTask createTask = new ProgressTask(
|
||||
FileSelectActivity.this, create,
|
||||
R.string.progress_create);
|
||||
createTask.run();
|
||||
assignPasswordHelper =
|
||||
new AssignPasswordHelper(this,
|
||||
masterPassword, keyFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAssignKeyDialogNegativeClick(
|
||||
boolean masterPasswordChecked, String masterPassword,
|
||||
boolean keyFileChecked, Uri keyFile) {
|
||||
|
||||
}
|
||||
|
||||
private class AssignPasswordOnFinish extends FileOnFinish {
|
||||
|
||||
AssignPasswordOnFinish(FileOnFinish fileOnFinish) {
|
||||
super(fileOnFinish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (mSuccess) {
|
||||
assignPasswordHelper.assignPasswordInDatabase(mOnFinish);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LaunchGroupActivity extends FileOnFinish {
|
||||
private Uri mUri;
|
||||
|
||||
public LaunchGroupActivity(String filename) {
|
||||
LaunchGroupActivity(String filename) {
|
||||
super(null);
|
||||
|
||||
mUri = UriUtil.parseDefaultFile(filename);
|
||||
}
|
||||
|
||||
@@ -311,61 +389,19 @@ public class FileSelectActivity extends StylishActivity {
|
||||
if (mSuccess) {
|
||||
// Add to recent files
|
||||
fileHistory.createFile(mUri, getFilename());
|
||||
|
||||
mAdapter.notifyDataSetChanged();
|
||||
GroupActivity.Launch(FileSelectActivity.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CollectPassword extends FileOnFinish {
|
||||
|
||||
public CollectPassword(FileOnFinish finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
SetPasswordDialog dialog = SetPasswordDialog.newInstance(mOnFinish);
|
||||
dialog.show(getSupportFragmentManager(), "passwordDialog");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void fillData() {
|
||||
// Set the initial value of the filename
|
||||
EditText filename = (EditText) findViewById(R.id.file_filename);
|
||||
filename.setText(Environment.getExternalStorageDirectory().getAbsolutePath() + getString(R.string.default_file_path));
|
||||
|
||||
mAdapter = new ArrayAdapter<String>(this, R.layout.file_row, R.id.file_filename, fileHistory.getDbList());
|
||||
mList.setAdapter(mAdapter);
|
||||
mAdapter = new ArrayAdapter<>(FileSelectActivity.this, R.layout.file_row, R.id.file_filename, fileHistory.getDbList());
|
||||
mList.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
|
||||
new AsyncTask<Integer, Void, Void>() {
|
||||
String fileName;
|
||||
String keyFile;
|
||||
protected Void doInBackground(Integer... args) {
|
||||
int position = args[0];
|
||||
fileName = fileHistory.getDatabaseAt(position);
|
||||
keyFile = fileHistory.getKeyfileAt(position);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Void v) {
|
||||
try {
|
||||
PasswordActivity.Launch(FileSelectActivity.this, fileName, keyFile);
|
||||
}
|
||||
catch (ContentFileNotFoundException e) {
|
||||
Toast.makeText(FileSelectActivity.this, R.string.file_not_found_content, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
Toast.makeText(FileSelectActivity.this, R.string.FileNotFound, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}.execute(position);
|
||||
new OpenFileHistoryAsyncTask(this, fileHistory).execute(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -409,8 +445,7 @@ public class FileSelectActivity extends StylishActivity {
|
||||
}
|
||||
|
||||
if (filename != null) {
|
||||
EditText fn = (EditText) findViewById(R.id.file_filename);
|
||||
fn.setText(filename);
|
||||
openFileNameView.setText(filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,25 +552,65 @@ public class FileSelectActivity extends StylishActivity {
|
||||
|
||||
TextView tv = (TextView) acmi.targetView;
|
||||
String filename = tv.getText().toString();
|
||||
new AsyncTask<String, Void, Void>() {
|
||||
protected java.lang.Void doInBackground(String... args) {
|
||||
String filename = args[0];
|
||||
fileHistory.deleteFile(Uri.parse(args[0]));
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Void v) {
|
||||
refreshList();
|
||||
}
|
||||
}.execute(filename);
|
||||
new DeleteFileHistoryAsyncTask(fileHistory, mAdapter).execute(filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void refreshList() {
|
||||
((BaseAdapter) mAdapter).notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private static class OpenFileHistoryAsyncTask extends AsyncTask<Integer, Void, Void> {
|
||||
|
||||
private WeakReference<Activity> weakActivity;
|
||||
private RecentFileHistory fileHistory;
|
||||
private String fileName;
|
||||
private String keyFile;
|
||||
|
||||
OpenFileHistoryAsyncTask(Activity activity, RecentFileHistory fileHistory) {
|
||||
this.weakActivity = new WeakReference<>(activity);
|
||||
this.fileHistory = fileHistory;
|
||||
}
|
||||
|
||||
protected Void doInBackground(Integer... args) {
|
||||
int position = args[0];
|
||||
fileName = fileHistory.getDatabaseAt(position);
|
||||
keyFile = fileHistory.getKeyfileAt(position);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Void v) {
|
||||
try {
|
||||
PasswordActivity.Launch(weakActivity.get(), fileName, keyFile);
|
||||
}
|
||||
catch (ContentFileNotFoundException e) {
|
||||
Toast.makeText(weakActivity.get(), R.string.file_not_found_content, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
Toast.makeText(weakActivity.get(), R.string.FileNotFound, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class DeleteFileHistoryAsyncTask extends AsyncTask<String, Void, Void> {
|
||||
|
||||
private RecentFileHistory fileHistory;
|
||||
private BaseAdapter adapter;
|
||||
|
||||
DeleteFileHistoryAsyncTask(RecentFileHistory fileHistory, BaseAdapter adapter) {
|
||||
this.fileHistory = fileHistory;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
protected java.lang.Void doInBackground(String... args) {
|
||||
fileHistory.deleteFile(Uri.parse(args[0]));
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Void v) {
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2017 Brian 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 2 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.keepassdroid.fingerprint;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Animatable2;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public class FingerPrintAnimatedVector {
|
||||
|
||||
private AnimatedVectorDrawable scanFingerprint;
|
||||
|
||||
public FingerPrintAnimatedVector(Context context, ImageView imageView) {
|
||||
scanFingerprint = (AnimatedVectorDrawable) context.getDrawable(R.drawable.scan_fingerprint);
|
||||
imageView.setImageDrawable(scanFingerprint);
|
||||
}
|
||||
|
||||
public void startScan() {
|
||||
scanFingerprint.registerAnimationCallback(new Animatable2.AnimationCallback() {
|
||||
public void onAnimationEnd(Drawable drawable) {
|
||||
scanFingerprint.start();
|
||||
}
|
||||
});
|
||||
scanFingerprint.start();
|
||||
}
|
||||
|
||||
public void stopScan() {
|
||||
scanFingerprint.stop();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.keepassdroid.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.EditTextPreference;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
import android.widget.Toast;
|
||||
@@ -35,28 +35,26 @@ public class MainPreferenceFragment extends PreferenceFragmentCompat implements
|
||||
preference.setOnPreferenceClickListener(this);
|
||||
|
||||
preference = findPreference(getString(R.string.db_key));
|
||||
Database db = App.getDB();
|
||||
if (!(db.Loaded() && db.pm.appSettingsEnabled())) {
|
||||
Preference dbSettings = findPreference(getString(R.string.db_key));
|
||||
dbSettings.setEnabled(false);
|
||||
} else {
|
||||
preference.setOnPreferenceClickListener(this);
|
||||
}
|
||||
preference.setOnPreferenceClickListener(this);
|
||||
|
||||
EditTextPreference fixDatabaseRoundPref = (EditTextPreference)
|
||||
getPreferenceScreen().findPreference(getString(R.string.roundsFix_key));
|
||||
fixDatabaseRoundPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
try {
|
||||
Long.valueOf(newValue.toString());
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
Toast.makeText(getContext(), R.string.error_rounds_not_number, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Database db = App.getDB();
|
||||
if (!(db.Loaded())) {
|
||||
preference.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayPreferenceDialog(Preference preference) {
|
||||
// Try if the preference is one of our custom Preferences
|
||||
if (preference instanceof RoundsPreference) {
|
||||
DialogFragment dialogFragment = RoundsFixPreferenceDialogFragmentCompat.newInstance(preference.getKey());
|
||||
dialogFragment.setTargetFragment(this, 0);
|
||||
dialogFragment.show(getFragmentManager(), null);
|
||||
}
|
||||
// Could not be handled here. Try with the super method.
|
||||
else {
|
||||
super.onDisplayPreferenceDialog(preference);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,11 +20,16 @@
|
||||
package com.keepassdroid.settings;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.keepassdroid.UnavailableFeatureDialog;
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.keepassdroid.Database;
|
||||
import com.keepassdroid.app.App;
|
||||
@@ -98,28 +103,44 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat {
|
||||
}
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
// False if under Marshmallow
|
||||
SwitchPreference preference = (SwitchPreference) findPreference(getString(R.string.fingerprint_enable_key));
|
||||
preference.setDefaultValue(false);
|
||||
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
((SwitchPreference) preference).setChecked(false);
|
||||
UnavailableFeatureDialog.getInstance(Build.VERSION_CODES.M)
|
||||
.show(getFragmentManager(), "unavailableFeatureDialog");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NESTED_SCREEN_DB_KEY:
|
||||
setPreferencesFromResource(R.xml.db_preferences, rootKey);
|
||||
|
||||
Database db = App.getDB();
|
||||
Preference algorithmPref = findPreference(getString(R.string.algorithm_key));
|
||||
Preference roundPref = findPreference(getString(R.string.rounds_key));
|
||||
|
||||
if (!(db.Loaded() && db.pm.appSettingsEnabled())) {
|
||||
algorithmPref.setEnabled(false);
|
||||
roundPref.setEnabled(false);
|
||||
}
|
||||
|
||||
if (db.Loaded() && db.pm.appSettingsEnabled()) {
|
||||
|
||||
Preference rounds = findPreference(getString(R.string.rounds_key));
|
||||
rounds.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
|
||||
roundPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
setRounds(App.getDB(), preference);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
setRounds(db, rounds);
|
||||
|
||||
Preference algorithm = findPreference(getString(R.string.algorithm_key));
|
||||
setAlgorithm(db, algorithm);
|
||||
|
||||
setRounds(db, roundPref);
|
||||
setAlgorithm(db, algorithmPref);
|
||||
} else {
|
||||
Log.e(getClass().getName(), "Database isn't ready");
|
||||
}
|
||||
@@ -131,6 +152,20 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayPreferenceDialog(Preference preference) {
|
||||
// Try if the preference is one of our custom Preferences
|
||||
if (preference instanceof RoundsPreference) {
|
||||
DialogFragment dialogFragment = RoundsPreferenceDialogFragmentCompat.newInstance(preference.getKey());
|
||||
dialogFragment.setTargetFragment(this, 0);
|
||||
dialogFragment.show(getFragmentManager(), null);
|
||||
}
|
||||
// Could not be handled here. Try with the super method.
|
||||
else {
|
||||
super.onDisplayPreferenceDialog(preference);
|
||||
}
|
||||
}
|
||||
|
||||
private void setRounds(Database db, Preference rounds) {
|
||||
rounds.setSummary(Long.toString(db.pm.getNumRounds()));
|
||||
}
|
||||
|
||||
@@ -25,10 +25,46 @@ import android.preference.PreferenceManager;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class PrefsUtil {
|
||||
|
||||
public static float getListTextSize(Context ctx) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
return Float.parseFloat(prefs.getString(ctx.getString(R.string.list_size_key), ctx.getString(R.string.list_size_default)));
|
||||
|
||||
}
|
||||
|
||||
public static int getDefaultPasswordLength(Context ctx) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
return prefs.getInt(ctx.getString(R.string.password_length_key),
|
||||
Integer.parseInt(ctx.getString(R.string.default_password_length)));
|
||||
}
|
||||
|
||||
public static Set<String> getDefaultPasswordCharacters(Context ctx) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
return prefs.getStringSet(ctx.getString(R.string.list_password_generator_options_key),
|
||||
new HashSet<>(Arrays.asList(
|
||||
ctx.getResources()
|
||||
.getStringArray(R.array.list_password_generator_options_default_values))));
|
||||
}
|
||||
|
||||
public static boolean isClipboardNotificationsEnable(Context ctx) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
return prefs.getBoolean(ctx.getString(R.string.clipboard_notifications_key),
|
||||
ctx.getResources().getBoolean(R.bool.clipboard_notifications_default));
|
||||
}
|
||||
|
||||
public static boolean isLockDatabaseWhenScreenShutOffEnable(Context ctx) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
return prefs.getBoolean(ctx.getString(R.string.lock_database_screen_off_key),
|
||||
ctx.getResources().getBoolean(R.bool.lock_database_screen_off_default));
|
||||
}
|
||||
|
||||
public static boolean isFingerprintEnable(Context ctx) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
return prefs.getBoolean(ctx.getString(R.string.fingerprint_enable_key),
|
||||
ctx.getResources().getBoolean(R.bool.fingerprint_enable_default));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.keepassdroid.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.DialogPreference;
|
||||
import android.support.v7.preference.PreferenceDialogFragmentCompat;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public class RoundsFixPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
|
||||
|
||||
private TextView mRoundsView;
|
||||
|
||||
public static RoundsFixPreferenceDialogFragmentCompat newInstance(
|
||||
String key) {
|
||||
final RoundsFixPreferenceDialogFragmentCompat
|
||||
fragment = new RoundsFixPreferenceDialogFragmentCompat();
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putString(ARG_KEY, key);
|
||||
fragment.setArguments(b);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDialogClosed(boolean positiveResult) {
|
||||
if ( positiveResult ) {
|
||||
long rounds;
|
||||
try {
|
||||
String strRounds = mRoundsView.getText().toString();
|
||||
rounds = Long.valueOf(strRounds);
|
||||
} catch (NumberFormatException e) {
|
||||
Toast.makeText(getContext(), R.string.error_rounds_not_number, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
DialogPreference preference = getPreference();
|
||||
if (preference instanceof RoundsPreference) {
|
||||
RoundsPreference roundsPreference = (RoundsPreference) preference;
|
||||
// This allows the client to ignore the user value.
|
||||
if (roundsPreference.callChangeListener(rounds)) {
|
||||
// Save the value
|
||||
roundsPreference.setRounds(rounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View view) {
|
||||
super.onBindDialogView(view);
|
||||
|
||||
TextView textDescriptionView = (TextView) view.findViewById(R.id.rounds_explanation);
|
||||
mRoundsView = (TextView) view.findViewById(R.id.rounds);
|
||||
|
||||
DialogPreference preference = getPreference();
|
||||
if (preference instanceof RoundsPreference) {
|
||||
textDescriptionView.setText(((RoundsPreference) preference).getExplanations());
|
||||
long numRounds = ((RoundsPreference) preference).getRounds();
|
||||
mRoundsView.setText(String.valueOf(numRounds));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,112 +19,91 @@
|
||||
*/
|
||||
package com.keepassdroid.settings;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.preference.DialogPreference;
|
||||
import android.content.res.TypedArray;
|
||||
import android.support.v7.preference.DialogPreference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kunzisoft.keepass.R;
|
||||
import com.keepassdroid.Database;
|
||||
import com.keepassdroid.ProgressTask;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.edit.OnFinish;
|
||||
import com.keepassdroid.database.edit.SaveDB;
|
||||
|
||||
public class RoundsPreference extends DialogPreference {
|
||||
|
||||
private PwDatabase mPM;
|
||||
private TextView mRoundsView;
|
||||
|
||||
@Override
|
||||
protected View onCreateDialogView() {
|
||||
View view = super.onCreateDialogView();
|
||||
|
||||
mRoundsView = (TextView) view.findViewById(R.id.rounds);
|
||||
|
||||
Database db = App.getDB();
|
||||
mPM = db.pm;
|
||||
long numRounds = mPM.getNumRounds();
|
||||
mRoundsView.setText(Long.toString(numRounds));
|
||||
|
||||
return view;
|
||||
}
|
||||
private long mRounds;
|
||||
private String explanations;
|
||||
|
||||
public RoundsPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public RoundsPreference(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public RoundsPreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.dialogPreferenceStyle);
|
||||
}
|
||||
public RoundsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, defStyleAttr);
|
||||
}
|
||||
public RoundsPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.RoundsDialog,
|
||||
0, 0);
|
||||
try {
|
||||
explanations = a.getString(R.styleable.RoundsDialog_description);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
public RoundsPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
@Override
|
||||
public int getDialogLayoutResource() {
|
||||
return R.layout.pref_dialog_rounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDialogClosed(boolean positiveResult) {
|
||||
super.onDialogClosed(positiveResult);
|
||||
public String getExplanations() {
|
||||
return explanations;
|
||||
}
|
||||
|
||||
if ( positiveResult ) {
|
||||
int rounds;
|
||||
|
||||
try {
|
||||
String strRounds = mRoundsView.getText().toString();
|
||||
rounds = Integer.parseInt(strRounds);
|
||||
} catch (NumberFormatException e) {
|
||||
Toast.makeText(getContext(), R.string.error_rounds_not_number, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( rounds < 1 ) {
|
||||
rounds = 1;
|
||||
}
|
||||
|
||||
long oldRounds = mPM.getNumRounds();
|
||||
try {
|
||||
mPM.setNumRounds(rounds);
|
||||
} catch (NumberFormatException e) {
|
||||
Toast.makeText(getContext(), R.string.error_rounds_too_large, Toast.LENGTH_LONG).show();
|
||||
mPM.setNumRounds(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
Handler handler = new Handler();
|
||||
SaveDB save = new SaveDB(getContext(), App.getDB(), new AfterSave(getContext(), handler, oldRounds));
|
||||
ProgressTask pt = new ProgressTask(getContext(), save, R.string.saving_database);
|
||||
pt.run();
|
||||
|
||||
}
|
||||
public void setExplanations(String explanations) {
|
||||
this.explanations = explanations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class AfterSave extends OnFinish {
|
||||
private long mOldRounds;
|
||||
private Context mCtx;
|
||||
|
||||
public AfterSave(Context ctx, Handler handler, long oldRounds) {
|
||||
super(handler);
|
||||
|
||||
mCtx = ctx;
|
||||
mOldRounds = oldRounds;
|
||||
}
|
||||
public long getRounds() {
|
||||
return mRounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mSuccess ) {
|
||||
OnPreferenceChangeListener listner = getOnPreferenceChangeListener();
|
||||
if ( listner != null ) {
|
||||
listner.onPreferenceChange(RoundsPreference.this, null);
|
||||
}
|
||||
} else {
|
||||
displayMessage(mCtx);
|
||||
mPM.setNumRounds(mOldRounds);
|
||||
}
|
||||
|
||||
super.run();
|
||||
}
|
||||
|
||||
}
|
||||
public void setRounds(long rounds) {
|
||||
this.mRounds = rounds;
|
||||
// Save to Shared Preferences
|
||||
persistLong(rounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object onGetDefaultValue(TypedArray a, int index) {
|
||||
// Default value from attribute. Fallback value is set to 0.
|
||||
return a.getInt(index, 0);
|
||||
}
|
||||
@Override
|
||||
protected void onSetInitialValue(boolean restorePersistedValue,
|
||||
Object defaultValue) {
|
||||
// Read the value. Use the default value if it is not possible.
|
||||
long rounds;
|
||||
if (!restorePersistedValue) {
|
||||
rounds = 100000;
|
||||
if (defaultValue instanceof String) {
|
||||
rounds = Long.parseLong((String) defaultValue);
|
||||
}
|
||||
if (defaultValue instanceof Integer) {
|
||||
rounds = (Integer) defaultValue;
|
||||
}
|
||||
try {
|
||||
rounds = (long) defaultValue;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
rounds = getPersistedLong(mRounds);
|
||||
}
|
||||
|
||||
setRounds(rounds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.keepassdroid.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.preference.DialogPreference;
|
||||
import android.support.v7.preference.PreferenceDialogFragmentCompat;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.keepassdroid.Database;
|
||||
import com.keepassdroid.ProgressTask;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.database.PwDatabase;
|
||||
import com.keepassdroid.database.edit.OnFinish;
|
||||
import com.keepassdroid.database.edit.SaveDB;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public class RoundsPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
|
||||
|
||||
private PwDatabase mPM;
|
||||
private TextView mRoundsView;
|
||||
|
||||
public static RoundsPreferenceDialogFragmentCompat newInstance(
|
||||
String key) {
|
||||
final RoundsPreferenceDialogFragmentCompat
|
||||
fragment = new RoundsPreferenceDialogFragmentCompat();
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putString(ARG_KEY, key);
|
||||
fragment.setArguments(b);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDialogClosed(boolean positiveResult) {
|
||||
if ( positiveResult ) {
|
||||
long rounds;
|
||||
|
||||
try {
|
||||
String strRounds = mRoundsView.getText().toString();
|
||||
rounds = Long.parseLong(strRounds);
|
||||
} catch (NumberFormatException e) {
|
||||
Toast.makeText(getContext(), R.string.error_rounds_not_number, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( rounds < 1 ) {
|
||||
rounds = 1;
|
||||
}
|
||||
|
||||
long oldRounds = mPM.getNumRounds();
|
||||
try {
|
||||
mPM.setNumRounds(rounds);
|
||||
} catch (NumberFormatException e) {
|
||||
Toast.makeText(getContext(), R.string.error_rounds_too_large, Toast.LENGTH_LONG).show();
|
||||
mPM.setNumRounds(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
Handler handler = new Handler();
|
||||
SaveDB save = new SaveDB(getContext(), App.getDB(), new AfterSave(getContext(), handler, oldRounds));
|
||||
ProgressTask pt = new ProgressTask(getContext(), save, R.string.saving_database);
|
||||
pt.run();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View view) {
|
||||
super.onBindDialogView(view);
|
||||
|
||||
mRoundsView = (TextView) view.findViewById(R.id.rounds);
|
||||
|
||||
// Get the time from the related Preference
|
||||
Database db = App.getDB();
|
||||
mPM = db.pm;
|
||||
long numRounds = mPM.getNumRounds();
|
||||
|
||||
DialogPreference preference = getPreference();
|
||||
if (preference instanceof RoundsPreference) {
|
||||
numRounds = ((RoundsPreference) preference).getRounds();
|
||||
}
|
||||
|
||||
mRoundsView.setText(String.valueOf(numRounds));
|
||||
}
|
||||
|
||||
private class AfterSave extends OnFinish {
|
||||
private long mOldRounds;
|
||||
private Context mCtx;
|
||||
|
||||
public AfterSave(Context ctx, Handler handler, long oldRounds) {
|
||||
super(handler);
|
||||
|
||||
mCtx = ctx;
|
||||
mOldRounds = oldRounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mSuccess ) {
|
||||
|
||||
} else {
|
||||
displayMessage(mCtx);
|
||||
mPM.setNumRounds(mOldRounds);
|
||||
}
|
||||
|
||||
super.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,8 +97,8 @@ public class SettingsActivity extends StylishActivity implements MainPreferenceF
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
getFragmentManager().popBackStack();
|
||||
toolbar.setTitle(R.string.settings);
|
||||
}
|
||||
toolbar.setTitle(R.string.settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,9 +9,9 @@ import com.kunzisoft.keepass.R;
|
||||
|
||||
public class Stylish {
|
||||
|
||||
private static String stylishPrefKey;
|
||||
protected static String stylishPrefKey;
|
||||
|
||||
private static String themeString;
|
||||
protected static String themeString;
|
||||
|
||||
public static void init(Context context) {
|
||||
stylishPrefKey = context.getString(R.string.setting_style_key);
|
||||
@@ -23,7 +23,7 @@ public class Stylish {
|
||||
themeString = styleString;
|
||||
}
|
||||
|
||||
static @StyleRes int getThemeId(Context context) {
|
||||
public static @StyleRes int getThemeId(Context context) {
|
||||
|
||||
if (themeString.equals(context.getString(R.string.list_style_name_night)))
|
||||
return R.style.KeepassDXStyle_Night;
|
||||
|
||||
@@ -19,12 +19,6 @@
|
||||
*/
|
||||
package com.keepassdroid.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.keepassdroid.database.exception.SamsungClipboardException;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
@@ -33,6 +27,12 @@ import android.net.Uri;
|
||||
import android.text.ClipboardManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.keepassdroid.database.exception.SamsungClipboardException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class Util {
|
||||
public static String getClipboard(Context context) {
|
||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
@@ -75,14 +75,6 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setEditText(Activity act, int resId, String str) {
|
||||
TextView te = (TextView) act.findViewById(resId);
|
||||
|
||||
if (te != null) {
|
||||
te.setText(str);
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyStream(InputStream in, OutputStream out) throws IOException {
|
||||
byte[] buf = new byte[1024];
|
||||
int read;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.keepassdroid.view;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.keepassdroid.ProgressTask;
|
||||
import com.keepassdroid.app.App;
|
||||
import com.keepassdroid.database.edit.FileOnFinish;
|
||||
import com.keepassdroid.database.edit.OnFinish;
|
||||
import com.keepassdroid.database.edit.SetPassword;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
public class AssignPasswordHelper {
|
||||
|
||||
private Context context;
|
||||
|
||||
private String masterPassword;
|
||||
private Uri keyfile;
|
||||
|
||||
public AssignPasswordHelper(Context context,
|
||||
String masterPassword,
|
||||
Uri keyfile) {
|
||||
this.context = context;
|
||||
this.masterPassword = masterPassword;
|
||||
this.keyfile = keyfile;
|
||||
}
|
||||
|
||||
public void assignPasswordInDatabase(FileOnFinish fileOnFinish) {
|
||||
SetPassword sp = new SetPassword(context, App.getDB(), masterPassword, keyfile, new AfterSave(fileOnFinish, new Handler()));
|
||||
final ProgressTask pt = new ProgressTask(context, sp, R.string.saving_database);
|
||||
boolean valid = sp.validatePassword(context, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
pt.run();
|
||||
}
|
||||
});
|
||||
|
||||
if (valid) {
|
||||
pt.run();
|
||||
}
|
||||
}
|
||||
|
||||
private class AfterSave extends OnFinish {
|
||||
private FileOnFinish mFinish;
|
||||
|
||||
public AfterSave(FileOnFinish finish, Handler handler) {
|
||||
super(finish, handler);
|
||||
mFinish = finish;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( mSuccess ) {
|
||||
if ( mFinish != null ) {
|
||||
mFinish.setFilename(keyfile);
|
||||
}
|
||||
} else {
|
||||
displayMessage(context);
|
||||
}
|
||||
super.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 2 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.keepassdroid.view;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.keepassdroid.fingerprint.FingerPrintAnimatedVector;
|
||||
import com.kunzisoft.keepass.R;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public class FingerPrintDialog extends DialogFragment {
|
||||
|
||||
private FingerPrintAnimatedVector fingerPrintAnimatedVector;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
|
||||
View rootView = inflater.inflate(R.layout.fingerprint_dialog, null);
|
||||
|
||||
View fingerprintSettingWayTextView = rootView.findViewById(R.id.fingerprint_setting_way_text);
|
||||
fingerprintSettingWayTextView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
startActivity(new Intent(android.provider.Settings.ACTION_SECURITY_SETTINGS));
|
||||
}
|
||||
});
|
||||
|
||||
fingerPrintAnimatedVector =
|
||||
new FingerPrintAnimatedVector(getContext(),
|
||||
(ImageView) rootView.findViewById(R.id.fingerprint_image));
|
||||
|
||||
builder.setView(rootView)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
|
||||
}
|
||||
});
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
fingerPrintAnimatedVector.startScan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
fingerPrintAnimatedVector.stopScan();
|
||||
}
|
||||
}
|
||||
178
app/src/main/java/com/keepassdroid/view/KeyFileHelper.java
Normal file
178
app/src/main/java/com/keepassdroid/view/KeyFileHelper.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2017 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 2 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.keepassdroid.view;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.View;
|
||||
|
||||
import com.keepassdroid.compat.StorageAF;
|
||||
import com.keepassdroid.fileselect.BrowserDialog;
|
||||
import com.keepassdroid.intents.Intents;
|
||||
import com.keepassdroid.utils.Interaction;
|
||||
import com.keepassdroid.utils.UriUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
|
||||
public class KeyFileHelper {
|
||||
|
||||
public static final int GET_CONTENT = 25745;
|
||||
private static final int OPEN_DOC = 25845;
|
||||
private static final int FILE_BROWSE = 25645;
|
||||
|
||||
private Activity activity;
|
||||
private Fragment fragment;
|
||||
private Uri mDbUri;
|
||||
|
||||
public KeyFileHelper(Activity context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public KeyFileHelper(Activity context, Uri mDbUri) {
|
||||
this.activity = context;
|
||||
this.fragment = null;
|
||||
this.mDbUri = mDbUri;
|
||||
}
|
||||
|
||||
public KeyFileHelper(Fragment context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public KeyFileHelper(Fragment context, Uri mDbUri) {
|
||||
this.activity = context.getActivity();
|
||||
this.fragment = context;
|
||||
this.mDbUri = mDbUri;
|
||||
}
|
||||
|
||||
public View.OnClickListener getOpenFileOnClickViewListener() {
|
||||
return new View.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
if (StorageAF.useStorageFramework(activity)) {
|
||||
Intent i = new Intent(StorageAF.ACTION_OPEN_DOCUMENT);
|
||||
i.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
i.setType("*/*");
|
||||
if(fragment != null)
|
||||
fragment.startActivityForResult(i, OPEN_DOC);
|
||||
else
|
||||
activity.startActivityForResult(i, OPEN_DOC);
|
||||
} else {
|
||||
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
i.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
i.setType("*/*");
|
||||
|
||||
try {
|
||||
if(fragment != null)
|
||||
fragment.startActivityForResult(i, GET_CONTENT);
|
||||
else
|
||||
activity.startActivityForResult(i, GET_CONTENT);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
lookForOpenIntentsFilePicker();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void lookForOpenIntentsFilePicker() {
|
||||
if (Interaction.isIntentAvailable(activity, Intents.OPEN_INTENTS_FILE_BROWSE)) {
|
||||
Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE);
|
||||
|
||||
// Get file path parent if possible
|
||||
try {
|
||||
if (mDbUri != null && mDbUri.toString().length() > 0) {
|
||||
if (mDbUri.getScheme().equals("file")) {
|
||||
File keyfile = new File(mDbUri.getPath());
|
||||
File parent = keyfile.getParentFile();
|
||||
if (parent != null) {
|
||||
i.setData(Uri.parse("file://" + parent.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
try {
|
||||
if(fragment != null)
|
||||
fragment.startActivityForResult(i, FILE_BROWSE);
|
||||
else
|
||||
activity.startActivityForResult(i, FILE_BROWSE);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
showBrowserDialog();
|
||||
}
|
||||
} else {
|
||||
showBrowserDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private void showBrowserDialog() {
|
||||
BrowserDialog browserDialog = new BrowserDialog(activity);
|
||||
browserDialog.show();
|
||||
}
|
||||
|
||||
|
||||
public void onActivityResultCallback(
|
||||
int requestCode,
|
||||
int resultCode,
|
||||
Intent data,
|
||||
KeyFileCallback keyFileCallback) {
|
||||
|
||||
switch (requestCode) {
|
||||
case FILE_BROWSE:
|
||||
if (resultCode == RESULT_OK) {
|
||||
String filename = data.getDataString();
|
||||
Uri keyUri = null;
|
||||
if (filename != null) {
|
||||
keyUri = UriUtil.parseDefaultFile(filename);
|
||||
}
|
||||
if (keyFileCallback != null)
|
||||
keyFileCallback.onKeyFileResultCallback(keyUri);
|
||||
}
|
||||
break;
|
||||
case GET_CONTENT:
|
||||
case OPEN_DOC:
|
||||
if (resultCode == RESULT_OK) {
|
||||
if (data != null) {
|
||||
Uri uri = data.getData();
|
||||
if (uri != null) {
|
||||
if (requestCode == GET_CONTENT) {
|
||||
uri = UriUtil.translate(activity, uri);
|
||||
}
|
||||
if (keyFileCallback != null)
|
||||
keyFileCallback.onKeyFileResultCallback(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public interface KeyFileCallback {
|
||||
void onKeyFileResultCallback(Uri uri);
|
||||
}
|
||||
|
||||
}
|
||||
39
app/src/main/res/animator-v23/scan.xml
Normal file
39
app/src/main/res/animator-v23/scan.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:ordering="sequentially">
|
||||
|
||||
<objectAnimator
|
||||
android:propertyName="pathData"
|
||||
android:valueFrom="@string/clip_path_scan_top"
|
||||
android:valueTo="@string/clip_path_scan_bottom"
|
||||
android:valueType="pathType"
|
||||
android:duration="800"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in" />
|
||||
|
||||
<objectAnimator
|
||||
android:propertyName="pathData"
|
||||
android:valueFrom="@string/clip_path_scan_bottom"
|
||||
android:valueTo="@string/clip_path_scan_top"
|
||||
android:valueType="pathType"
|
||||
android:startOffset="50"
|
||||
android:duration="500"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in" />
|
||||
|
||||
</set>
|
||||
65
app/src/main/res/drawable-v23/fingerprint.xml
Normal file
65
app/src/main/res/drawable-v23/fingerprint.xml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="@dimen/fingerprint_width"
|
||||
android:height="@dimen/fingerprint_height"
|
||||
android:viewportWidth="@integer/fingerprint_viewport_width"
|
||||
android:viewportHeight="@integer/fingerprint_viewport_height">
|
||||
|
||||
<group
|
||||
android:name="fingerprint"
|
||||
android:pivotX="@integer/fingerprint_viewport_center"
|
||||
android:pivotY="@integer/fingerprint_viewport_center">
|
||||
|
||||
<path
|
||||
android:name="ridge_1"
|
||||
android:pathData="@string/path_ridge_1"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_2"
|
||||
android:pathData="@string/path_ridge_2"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_3"
|
||||
android:pathData="@string/path_ridge_3"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_4"
|
||||
android:pathData="@string/path_ridge_4"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_5"
|
||||
android:pathData="@string/path_ridge_5"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
</group>
|
||||
|
||||
</vector>
|
||||
109
app/src/main/res/drawable-v23/fingerprint_scan.xml
Normal file
109
app/src/main/res/drawable-v23/fingerprint_scan.xml
Normal file
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="@dimen/fingerprint_width"
|
||||
android:height="@dimen/fingerprint_height"
|
||||
android:viewportWidth="@integer/fingerprint_viewport_width"
|
||||
android:viewportHeight="@integer/fingerprint_viewport_height">
|
||||
|
||||
<group
|
||||
android:name="fingerprint">
|
||||
|
||||
<path
|
||||
android:name="ridge_1"
|
||||
android:pathData="@string/path_ridge_1"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_2"
|
||||
android:pathData="@string/path_ridge_2"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_3"
|
||||
android:pathData="@string/path_ridge_3"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_4"
|
||||
android:pathData="@string/path_ridge_4"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_5"
|
||||
android:pathData="@string/path_ridge_5"
|
||||
android:strokeColor="@color/fingerprint_ridge"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
</group>
|
||||
|
||||
<!-- we overlay the above with a duplicate of the fingerprint which is colored differently
|
||||
and uses a clip to only reveal portions at a time. -->
|
||||
<group
|
||||
android:name="fingerprint_scan">
|
||||
|
||||
<clip-path
|
||||
android:name="scan_clip"
|
||||
android:pathData="@string/clip_path_scan_top" />
|
||||
|
||||
<path
|
||||
android:name="ridge_1"
|
||||
android:pathData="@string/path_ridge_1"
|
||||
android:strokeColor="@color/fingerprint_ridge_scan"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_2"
|
||||
android:pathData="@string/path_ridge_2"
|
||||
android:strokeColor="@color/fingerprint_ridge_scan"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_3"
|
||||
android:pathData="@string/path_ridge_3"
|
||||
android:strokeColor="@color/fingerprint_ridge_scan"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_4"
|
||||
android:pathData="@string/path_ridge_4"
|
||||
android:strokeColor="@color/fingerprint_ridge_scan"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
<path
|
||||
android:name="ridge_5"
|
||||
android:pathData="@string/path_ridge_5"
|
||||
android:strokeColor="@color/fingerprint_ridge_scan"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeWidth="@integer/fingerprint_stroke_width" />
|
||||
|
||||
</group>
|
||||
|
||||
</vector>
|
||||
12
app/src/main/res/drawable-v23/lock_open.xml
Normal file
12
app/src/main/res/drawable-v23/lock_open.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:drawable="@drawable/circle"
|
||||
/>
|
||||
<item
|
||||
android:drawable="@drawable/ic_lock_open_white_24dp"
|
||||
android:bottom="12dp"
|
||||
android:left="12dp"
|
||||
android:right="12dp"
|
||||
android:top="12dp"/>
|
||||
</layer-list>
|
||||
26
app/src/main/res/drawable-v23/scan_fingerprint.xml
Normal file
26
app/src/main/res/drawable-v23/scan_fingerprint.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<animated-vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:drawable="@drawable/fingerprint_scan">
|
||||
|
||||
<target
|
||||
android:name="scan_clip"
|
||||
android:animation="@animator/scan" />
|
||||
|
||||
</animated-vector>
|
||||
6
app/src/main/res/drawable/circle.xml
Normal file
6
app/src/main/res/drawable/circle.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid
|
||||
android:color="@color/green"/>
|
||||
</shape>
|
||||
10
app/src/main/res/drawable/ic_database_plus_white_24dp.xml
Normal file
10
app/src/main/res/drawable/ic_database_plus_white_24dp.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<!-- drawable/database_plus.xml -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M9,3C4.58,3 1,4.79 1,7C1,9.21 4.58,11 9,11C13.42,11 17,9.21 17,7C17,4.79 13.42,3 9,3M1,9V12C1,14.21 4.58,16 9,16C13.42,16 17,14.21 17,12V9C17,11.21 13.42,13 9,13C4.58,13 1,11.21 1,9M1,14V17C1,19.21 4.58,21 9,21C10.41,21 11.79,20.81 13,20.46V17.46C11.79,17.81 10.41,18 9,18C4.58,18 1,16.21 1,14M18,14V17H15V19H18V22H20V19H23V17H20V14" />
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_lock_open_white_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_lock_open_white_24dp.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h1.9c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/ic_open_folder_white_24dp.xml
Normal file
10
app/src/main/res/drawable/ic_open_folder_white_24dp.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<!-- drawable/folder_open.xml -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" />
|
||||
</vector>
|
||||
BIN
app/src/main/res/drawable/type_assword.png
Normal file
BIN
app/src/main/res/drawable/type_assword.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
136
app/src/main/res/layout-v23/fingerprint_dialog.xml
Normal file
136
app/src/main/res/layout-v23/fingerprint_dialog.xml
Normal file
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/default_margin">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
android:text="@string/fingerprint_quick_unlock_title"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.WarningTextStyle"
|
||||
android:text="@string/chapter_1"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_setting_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="5dp"
|
||||
style="@style/KeepassDXStyle.TextAppearance.TinyText"
|
||||
android:text="@string/fingerprint_setting_text"/>
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_setting_way_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.TinyText"
|
||||
android:textColor="?attr/colorAccent"
|
||||
android:text="@string/fingerprint_setting_way_text"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="12dp">
|
||||
<TextView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.WarningTextStyle"
|
||||
android:text="@string/chapter_2"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.TinyText"
|
||||
android:padding="5dp"
|
||||
android:text="@string/fingerprint_type_password_text"/>
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="38dp"
|
||||
android:src="@drawable/type_assword"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="12dp">
|
||||
<TextView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.WarningTextStyle"
|
||||
android:text="@string/chapter_3" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.TinyText"
|
||||
android:padding="5dp"
|
||||
android:text="@string/fingerprint_scan_to_store"/>
|
||||
</LinearLayout>
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/fingerprint_image"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:elevation="4dp"
|
||||
android:src="@drawable/fingerprint"
|
||||
android:background="@drawable/circle"
|
||||
android:backgroundTint="?attr/colorAccent"
|
||||
tools:targetApi="lollipop" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
android:text="@string/usage" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.TinyText"
|
||||
android:padding="5dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/fingerprint_scan_to_open"/>
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:elevation="4dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/lock_open"
|
||||
android:background="@drawable/circle"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
tools:targetApi="lollipop" />
|
||||
</LinearLayout>
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
29
app/src/main/res/layout-v23/fingerprint_show.xml
Normal file
29
app/src/main/res/layout-v23/fingerprint_show.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/fingerprint_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:visibility="gone">
|
||||
<!-- added these 2 fingerprint related views -->
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/fingerprint_image"
|
||||
android:layout_width="38dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_margin="4dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:elevation="4dp"
|
||||
android:src="@drawable/fingerprint"
|
||||
android:background="@drawable/circle"
|
||||
android:backgroundTint="?attr/colorAccent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@+id/fingerprint_image"
|
||||
android:gravity="center_vertical|end"
|
||||
android:text="@string/entry_and_or"
|
||||
android:textColor="?attr/colorAccent" />
|
||||
</RelativeLayout>
|
||||
78
app/src/main/res/layout/file_creation.xml
Normal file
78
app/src/main/res/layout/file_creation.xml
Normal file
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/default_margin">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/browse_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="6dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignBottom="@+id/folder_path_input_layout"
|
||||
android:src="@drawable/ic_folder_white_24dp"
|
||||
android:tint="?attr/colorAccentCompat" />
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/folder_path_input_layout"
|
||||
android:layout_toLeftOf="@id/browse_button"
|
||||
android:layout_toStartOf="@id/browse_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/folder_path"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/path"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/filename_input_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toLeftOf="@+id/file_types"
|
||||
android:layout_toStartOf="@+id/file_types">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/filename"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/file_name"
|
||||
android:text="@string/database_file_name_default"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.v7.widget.AppCompatSpinner
|
||||
android:id="@+id/file_types"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/filename_input_layout"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@@ -17,32 +17,47 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/toolbar_default" />
|
||||
|
||||
<com.keepassdroid.view.FileNameView android:id="@+id/file_select"
|
||||
android:layout_marginBottom="@dimen/default_margin"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView android:id="@+id/file_listtop"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_marginStart="@dimen/default_margin"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:layout_marginEnd="@dimen/default_margin"
|
||||
android:layout_width="match_parent"
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/toolbar_default" />
|
||||
|
||||
<com.keepassdroid.view.FileNameView android:id="@+id/file_select"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView android:id="@+id/file_listtop"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_marginStart="@dimen/default_margin"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:layout_marginEnd="@dimen/default_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
android:text="@string/open_recent" />
|
||||
|
||||
<ListView android:id="@+id/file_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/create_database"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
android:text="@string/open_recent" />
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:src="@drawable/ic_database_plus_white_24dp"
|
||||
style="@style/KeepassDXStyle.Fab"/>
|
||||
|
||||
<ListView android:id="@+id/file_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
@@ -17,62 +17,76 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<TextView android:id="@+id/label_warning"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="20sp"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView android:id="@+id/label_open_by_filename"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
android:text="@string/enter_filename"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/browse_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/file_filename"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_below="@id/label_open_by_filename"
|
||||
android:padding="6dp"
|
||||
android:src="@drawable/ic_folder_white_24dp"
|
||||
android:tint="?attr/colorAccentCompat" />
|
||||
|
||||
<android.support.v7.widget.AppCompatEditText
|
||||
android:id="@+id/file_filename"
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/filename_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/label_open_by_filename"
|
||||
android:inputType="textUri"
|
||||
android:layout_toLeftOf="@+id/browse_button"
|
||||
android:layout_toStartOf="@+id/browse_button"
|
||||
android:maxLines="1" />
|
||||
android:layout_marginBottom="32dp">
|
||||
|
||||
<android.support.v7.widget.AppCompatButton android:id="@+id/open"
|
||||
android:layout_margin="@dimen/button_margin"
|
||||
android:text="@string/menu_open"
|
||||
android:layout_below="@id/file_filename"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_toLeftOf="@+id/create"
|
||||
android:layout_toStartOf="@+id/create"
|
||||
android:width="100sp"/>
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/default_margin"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_marginStart="@dimen/default_margin"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:layout_marginEnd="@dimen/default_margin"
|
||||
android:layout_marginBottom="12dp">
|
||||
|
||||
<android.support.v7.widget.AppCompatButton android:id="@+id/create"
|
||||
android:layout_margin="@dimen/button_margin"
|
||||
android:text="@string/menu_create"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_below="@id/file_filename"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:width="100sp"/>
|
||||
</RelativeLayout>
|
||||
<TextView android:id="@+id/label_warning"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="20sp"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView android:id="@+id/label_open_by_filename"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
android:text="@string/enter_filename"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/browse_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/file_filename"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_below="@id/label_open_by_filename"
|
||||
android:padding="6dp"
|
||||
android:src="@drawable/ic_folder_white_24dp"
|
||||
android:tint="?attr/colorAccentCompat" />
|
||||
|
||||
<android.support.v7.widget.AppCompatEditText
|
||||
android:id="@+id/file_filename"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/label_open_by_filename"
|
||||
android:inputType="textUri"
|
||||
android:layout_toLeftOf="@+id/browse_button"
|
||||
android:layout_toStartOf="@+id/browse_button"
|
||||
android:maxLines="1" />
|
||||
</RelativeLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/open_database"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/filename_container"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginLeft="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginRight="24dp"
|
||||
app:fabSize="mini"
|
||||
app:layout_anchor="@id/filename_container"
|
||||
app:layout_anchorGravity="bottom|start"
|
||||
android:src="@drawable/ic_open_folder_white_24dp" />
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
||||
7
app/src/main/res/layout/fingerprint_show.xml
Normal file
7
app/src/main/res/layout/fingerprint_show.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/fingerprint_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:visibility="gone" />
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -35,7 +36,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:maxLines="3"
|
||||
android:hint="@string/hint_generated_password" />
|
||||
android:hint="@string/hint_generated_password"
|
||||
tools:ignore="TextFields" />
|
||||
|
||||
<Button android:id="@+id/generate_password_button"
|
||||
android:layout_margin="@dimen/button_margin"
|
||||
@@ -71,7 +73,7 @@
|
||||
android:maxLines="1"
|
||||
android:maxLength="3"
|
||||
android:inputType="number"
|
||||
android:text="@integer/default_password_length"
|
||||
android:text="@string/default_password_length"
|
||||
android:hint="@string/hint_length"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatSeekBar android:id="@+id/seekbar_length"
|
||||
@@ -83,59 +85,176 @@
|
||||
android:layout_alignTop="@+id/length"
|
||||
android:layout_toEndOf="@+id/length"
|
||||
android:layout_toRightOf="@+id/length"
|
||||
app:min="1"
|
||||
android:progress="@integer/default_password_length"
|
||||
android:max="64"/>
|
||||
app:min="@string/min_password_length"
|
||||
android:progress="@string/default_password_length"
|
||||
android:max="@string/max_password_length"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/RelativeLayout"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginEnd="20dp">
|
||||
|
||||
<CheckBox android:id="@+id/cb_uppercase"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/uppercase"
|
||||
android:checked="true" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/cb_uppercase"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/uppercase"
|
||||
android:checked="true" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="end"
|
||||
android:layout_toEndOf="@+id/cb_uppercase"
|
||||
android:layout_toRightOf="@+id/cb_uppercase"
|
||||
android:text="@string/visual_uppercase" />
|
||||
</RelativeLayout>
|
||||
|
||||
<CheckBox android:id="@+id/cb_lowercase"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/lowercase"
|
||||
android:checked="true" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/cb_lowercase"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/lowercase"
|
||||
android:checked="true" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="end"
|
||||
android:layout_toEndOf="@+id/cb_lowercase"
|
||||
android:layout_toRightOf="@+id/cb_lowercase"
|
||||
android:text="@string/visual_lowercase" />
|
||||
</RelativeLayout>
|
||||
|
||||
<CheckBox android:id="@+id/cb_digits"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/digits"
|
||||
android:checked="true" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/cb_digits"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/digits"
|
||||
android:checked="true" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="end"
|
||||
android:layout_toEndOf="@+id/cb_digits"
|
||||
android:layout_toRightOf="@+id/cb_digits"
|
||||
android:text="@string/visual_digits" />
|
||||
</RelativeLayout>
|
||||
|
||||
<CheckBox android:id="@+id/cb_minus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/minus" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/cb_minus"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/minus" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="end"
|
||||
android:layout_toEndOf="@+id/cb_minus"
|
||||
android:layout_toRightOf="@+id/cb_minus"
|
||||
android:text="@string/visual_minus" />
|
||||
</RelativeLayout>
|
||||
|
||||
<CheckBox android:id="@+id/cb_underline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/underline" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/cb_underline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/underline" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="end"
|
||||
android:layout_toEndOf="@+id/cb_underline"
|
||||
android:layout_toRightOf="@+id/cb_underline"
|
||||
android:text="@string/visual_underline" />
|
||||
</RelativeLayout>
|
||||
|
||||
<CheckBox android:id="@+id/cb_space"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/space" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/cb_space"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/space" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="end"
|
||||
android:layout_toEndOf="@+id/cb_space"
|
||||
android:layout_toRightOf="@+id/cb_space"
|
||||
android:text="@string/visual_space" />
|
||||
</RelativeLayout>
|
||||
|
||||
<CheckBox android:id="@+id/cb_specials"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/special" />
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/cb_specials"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/special" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="end"
|
||||
android:layout_toEndOf="@+id/cb_specials"
|
||||
android:layout_toRightOf="@+id/cb_specials"
|
||||
android:text="@string/visual_special" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/cb_brackets"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/brackets"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="end"
|
||||
android:layout_toEndOf="@+id/cb_brackets"
|
||||
android:layout_toRightOf="@+id/cb_brackets"
|
||||
android:text="@string/visual_brackets" />
|
||||
</RelativeLayout>
|
||||
|
||||
<CheckBox android:id="@+id/cb_brackets"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/brackets" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
@@ -59,60 +59,44 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@+id/toolbar"
|
||||
android:layout_above="@+id/pass_ok">
|
||||
android:layout_below="@+id/toolbar">
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/default_margin">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/password_label"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/entry_and_or" />
|
||||
|
||||
<include
|
||||
layout="@layout/fingerprint_show" />
|
||||
|
||||
<!-- Password Input -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/password_container"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/password_input_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/password_label"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Title"
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:id="@+id/password_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/entry_and_or" />
|
||||
android:layout_alignParentBottom="true"
|
||||
android:paddingBottom="20dp"
|
||||
android:gravity="center_vertical" />
|
||||
|
||||
<!-- added these 2 fingerprint related views -->
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/fingerprint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/margin_small"
|
||||
android:layout_marginRight="@dimen/margin_small"
|
||||
android:layout_below="@id/password_label"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:src="@drawable/ic_fp_40px"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/fingerprint"
|
||||
android:layout_below="@+id/password_label"
|
||||
android:layout_toLeftOf="@id/fingerprint"
|
||||
android:layout_toStartOf="@id/fingerprint"
|
||||
android:gravity="center_vertical|end"
|
||||
android:text="@string/entry_and_or"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<!-- Password Input -->
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/password_input_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/fingerprint_label"
|
||||
android:layout_toRightOf="@+id/password_checkbox"
|
||||
android:layout_toEndOf="@+id/password_checkbox"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:passwordToggleTint="?attr/colorAccent">
|
||||
|
||||
@@ -120,12 +104,25 @@
|
||||
android:id="@+id/password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/hint_login_pass"
|
||||
android:hint="@string/password"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- File Input -->
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:id="@+id/keyfile_checkox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:paddingBottom="20dp"
|
||||
android:gravity="center_vertical" />
|
||||
|
||||
<!-- File Input -->
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/browse_button"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -133,36 +130,37 @@
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@+id/password_input_layout"
|
||||
android:padding="12dp"
|
||||
android:src="@drawable/ic_folder_white_24dp"
|
||||
android:tint="?attr/colorAccentCompat" />
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/input_entry_keyfile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/password_input_layout"
|
||||
android:layout_toLeftOf="@id/browse_button"
|
||||
android:layout_toStartOf="@id/browse_button" >
|
||||
android:layout_toEndOf="@+id/keyfile_checkox"
|
||||
android:layout_toRightOf="@+id/keyfile_checkox"
|
||||
android:layout_toLeftOf="@+id/browse_button"
|
||||
android:layout_toStartOf="@+id/browse_button">
|
||||
|
||||
<android.support.v7.widget.AppCompatEditText
|
||||
android:id="@+id/pass_keyfile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:hint="@string/entry_keyfile"
|
||||
android:inputType="text"
|
||||
android:hint="@string/entry_keyfile" />
|
||||
android:maxLines="1" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:id="@+id/default_database"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/password_container"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/default_checkbox" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
|
||||
@@ -17,21 +17,25 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/edit"
|
||||
android:padding="20dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include
|
||||
android:id="@+id/toolbar"
|
||||
layout="@layout/toolbar_default" />
|
||||
|
||||
<com.keepassdroid.view.FileNameView android:id="@+id/file_select"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/toolbar" />
|
||||
|
||||
<!-- Small hack because I need to include a list since this is a list activity -->
|
||||
<ListView android:id="@+id/file_list"
|
||||
android:layout_width="0sp"
|
||||
android:layout_height="0sp" />
|
||||
</RelativeLayout>
|
||||
<android.support.v7.widget.AppCompatTextView
|
||||
android:layout_marginBottom="8dp"
|
||||
android:id="@+id/rounds_explanation"
|
||||
android:gravity="center"
|
||||
android:text="@string/rounds_explaination"
|
||||
style="@style/KeepassDXStyle.TextAppearance.SmallTitle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"/>
|
||||
<android.support.v7.widget.AppCompatEditText
|
||||
android:id="@+id/rounds"
|
||||
android:hint="@string/rounds_hint"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:digits="0123456789"
|
||||
android:inputType="number"/>
|
||||
</LinearLayout>
|
||||
@@ -17,27 +17,109 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:padding="@dimen/default_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<EditText android:id="@+id/pass_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"
|
||||
android:hint="@string/hint_pass"/>
|
||||
<EditText android:id="@+id/pass_conf_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/pass_password"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"
|
||||
android:hint="@string/hint_conf_pass"/>
|
||||
<EditText android:id="@+id/pass_keyfile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/pass_conf_password"
|
||||
android:maxLines="1"
|
||||
android:hint="@string/hint_keyfile"/>
|
||||
</RelativeLayout>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:padding="@dimen/default_margin"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/card_view_master_password"
|
||||
android:layout_margin="4dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="4dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:id="@+id/password_checkbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/password"/>
|
||||
|
||||
<!-- Password Input -->
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/password_input_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:passwordToggleTint="?attr/colorAccent">
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/pass_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"
|
||||
android:hint="@string/hint_pass"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/password_repeat_input_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:passwordToggleTint="?attr/colorAccent">
|
||||
<EditText android:id="@+id/pass_conf_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"
|
||||
android:hint="@string/hint_conf_pass"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:id="@+id/card_view_key_file"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
app:cardCornerRadius="4dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:id="@+id/keyfile_checkox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/entry_keyfile"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/browse_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:padding="12dp"
|
||||
android:src="@drawable/ic_folder_white_24dp"
|
||||
android:tint="?attr/colorAccentCompat" />
|
||||
|
||||
<android.support.v7.widget.AppCompatEditText
|
||||
android:id="@+id/pass_keyfile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toLeftOf="@+id/browse_button"
|
||||
android:layout_toStartOf="@+id/browse_button"
|
||||
android:hint="@string/hint_keyfile"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"/>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<string name="entry_confpassword">Confirma contrasenya:</string>
|
||||
<string name="entry_created">Creada: </string>
|
||||
<string name="entry_expires">Expira: </string>
|
||||
<string name="entry_keyfile">Arxiu clau (opcional)</string>
|
||||
<string name="entry_keyfile">Arxiu clau</string>
|
||||
<string name="entry_modified">Modificada: </string>
|
||||
<string name="entry_password">Contrasenya:</string>
|
||||
<string name="entry_save">Guarda</string>
|
||||
@@ -80,7 +80,7 @@
|
||||
<string name="error_invalid_db">Base de dades invàlida.</string>
|
||||
<string name="error_invalid_path">Camí invàlid.</string>
|
||||
<string name="error_no_name">És necessari un nom.</string>
|
||||
<string name="error_nopass">És necessaria una contrasenya o un arxiu clau.</string>
|
||||
<string name="error_nokeyfile">És necessaria una contrasenya o un arxiu clau.</string>
|
||||
<string name="error_out_of_memory">El telèfon sha quedat sense memòria processant la teva base de dades. Potser és massa gran pel teu telèfon.</string>
|
||||
<string name="error_pass_gen_type">Has de seleccionar almenys un tipus de generador de contrasenyes</string>
|
||||
<string name="error_pass_match">Les contrasenyes no coincideixen.</string>
|
||||
@@ -99,7 +99,7 @@
|
||||
<string name="hint_keyfile">arxiu clau</string>
|
||||
<string name="hint_length">longitud</string>
|
||||
<string name="hint_pass">contrasenya</string>
|
||||
<string name="hint_login_pass">Contrasenya</string>
|
||||
<string name="password">Contrasenya</string>
|
||||
<string name="hint_title">nom</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">usuari</string>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<string name="entry_confpassword">Potvrďte heslo:</string>
|
||||
<string name="entry_created">Vytvořeno: </string>
|
||||
<string name="entry_expires">Vyprší: </string>
|
||||
<string name="entry_keyfile">Klíčový soubor (nepovinné)</string>
|
||||
<string name="entry_keyfile">Klíčový soubor</string>
|
||||
<string name="entry_modified">Změněno: </string>
|
||||
<string name="entry_not_found">Vstupní data nenalezena.</string>
|
||||
<string name="entry_password">Heslo:</string>
|
||||
@@ -86,7 +86,7 @@
|
||||
<string name="error_invalid_db">Chybná databáze.</string>
|
||||
<string name="error_invalid_path">Chybná cesta.</string>
|
||||
<string name="error_no_name">Jméno je povinné.</string>
|
||||
<string name="error_nopass">Heslo nebo klíčový soubor jsou povinné.</string>
|
||||
<string name="error_nokeyfile">Heslo nebo klíčový soubor jsou povinné.</string>
|
||||
<string name="error_out_of_memory">Přístroj má málo paměti pro zpracování databáze. Možná je příliš velká pro Váš přístroj.</string>
|
||||
<string name="error_pass_gen_type">Minimálně jeden typ generování hesla musí být zvolen</string>
|
||||
<string name="error_pass_match">Hesla se neshodují.</string>
|
||||
@@ -108,7 +108,7 @@
|
||||
<string name="hint_keyfile">klíčový soubor</string>
|
||||
<string name="hint_length">délka</string>
|
||||
<string name="hint_pass">heslo</string>
|
||||
<string name="hint_login_pass">Heslo</string>
|
||||
<string name="password">Heslo</string>
|
||||
<string name="hint_title">název</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">uživatelské jméno</string>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<string name="entry_confpassword">Bekræft adgangskode:</string>
|
||||
<string name="entry_created">Oprettet: </string>
|
||||
<string name="entry_expires">Udløber: </string>
|
||||
<string name="entry_keyfile">Nøglefil (valgfri)</string>
|
||||
<string name="entry_keyfile">Nøglefil</string>
|
||||
<string name="entry_modified">Ændret: </string>
|
||||
<string name="entry_not_found">Data for posten blev ikke fundet.</string>
|
||||
<string name="entry_password">Adgangskode:</string>
|
||||
@@ -85,7 +85,7 @@
|
||||
<string name="error_invalid_db">Ugyldig database.</string>
|
||||
<string name="error_invalid_path">Ugyldig sti.</string>
|
||||
<string name="error_no_name">Et navn er påkrævet.</string>
|
||||
<string name="error_nopass">En adgangskode eller nøglefil er påkrævet.</string>
|
||||
<string name="error_nokeyfile">En adgangskode eller nøglefil er påkrævet.</string>
|
||||
<string name="error_out_of_memory">Telefonen løb tør for hukommelse under analysen af din database. Den kan være for stor til, at din telefon kan håndtere den.</string>
|
||||
<string name="error_pass_gen_type">Mindst én adgangskode-genererings-type skal vælges</string>
|
||||
<string name="error_pass_match">Adgangskoder matcher ikke.</string>
|
||||
@@ -107,7 +107,7 @@
|
||||
<string name="hint_keyfile">nøglefil</string>
|
||||
<string name="hint_length">længde</string>
|
||||
<string name="hint_pass">adgangskode</string>
|
||||
<string name="hint_login_pass">Adgangskode</string>
|
||||
<string name="password">Adgangskode</string>
|
||||
<string name="hint_title">navn</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">brugernavn</string>
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<string name="entry_confpassword">Passwort wiederholen:</string>
|
||||
<string name="entry_created">Erstelldatum:</string>
|
||||
<string name="entry_expires">Ablaufdatum:</string>
|
||||
<string name="entry_keyfile">Schlüsseldatei (optional)</string>
|
||||
<string name="entry_keyfile">Schlüsseldatei</string>
|
||||
<string name="entry_modified">Änderungsdatum:</string>
|
||||
<string name="entry_not_found">Eintrag wurde nicht gefunden.</string>
|
||||
<string name="entry_password">Passwort:</string>
|
||||
@@ -89,7 +89,7 @@
|
||||
<string name="error_invalid_db">Ungültige Datenbank.</string>
|
||||
<string name="error_invalid_path">Ungültiger Pfad.</string>
|
||||
<string name="error_no_name">Ein Name wird benötigt.</string>
|
||||
<string name="error_nopass">Ein Passwort oder eine Schlüsseldatei wird benötigt.</string>
|
||||
<string name="error_nokeyfile">Ein Passwort oder eine Schlüsseldatei wird benötigt.</string>
|
||||
<string name="error_out_of_memory">Der Speicher Ihres Smartphones reicht nicht aus, um die Datenbank zu analysieren. Sie ist wahrscheinlich zu groß.</string>
|
||||
<string name="error_pass_gen_type">Mindestens ein Passwort-Generierungstyp muss ausgewählt werden.</string>
|
||||
<string name="error_pass_match">Die Passwörter stimmen nicht überein.</string>
|
||||
@@ -112,7 +112,7 @@
|
||||
<string name="hint_keyfile">Schlüsseldatei</string>
|
||||
<string name="hint_length">Länge</string>
|
||||
<string name="hint_pass">Passwort</string>
|
||||
<string name="hint_login_pass">Passwort</string>
|
||||
<string name="password">Passwort</string>
|
||||
<string name="hint_title">Name</string>
|
||||
<string name="hint_url">URL-Adresse</string>
|
||||
<string name="hint_username">Benutzername</string>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<string name="entry_confpassword">Επιβεβαίωση κωδικού πρόσβασης:</string>
|
||||
<string name="entry_created">Δημιουργήθηκε: </string>
|
||||
<string name="entry_expires">Λήγει: </string>
|
||||
<string name="entry_keyfile">Αρχείο Κλειδιού (προαιρετικό)</string>
|
||||
<string name="entry_keyfile">Αρχείο Κλειδιού</string>
|
||||
<string name="entry_modified">Τροποποιήθηκε: </string>
|
||||
<string name="entry_not_found">Δεν βρέθηκαν δεδομένα εγγραφών.</string>
|
||||
<string name="entry_password">Κωδικός Πρόσβασης:</string>
|
||||
@@ -83,7 +83,7 @@
|
||||
<string name="error_invalid_db">Μη έγκυρη βάση δεδομένων.</string>
|
||||
<string name="error_invalid_path">Μη έγκυρη διαδρομή.</string>
|
||||
<string name="error_no_name">Απαιτείται ένα όνομα.</string>
|
||||
<string name="error_nopass">Απαιτείται ο κωδικός πρόσβασης ή ένα αρχείο κλειδιού.</string>
|
||||
<string name="error_nokeyfile">Απαιτείται ο κωδικός πρόσβασης ή ένα αρχείο κλειδιού.</string>
|
||||
<string name="error_out_of_memory">Το τηλέφωνο ξέμεινε από μνήμη κατά τη διάρκεια προσπέλασης της βάσης δεδομένων σας. Μπορεί να είναι πολύ μεγάλη για το τηλέφωνο σας.</string>
|
||||
<string name="error_pass_gen_type">Πρέπει να επιλεγεί τουλάχιστον ένας τύπος δημιουργίας κωδικού πρόσβασης</string>
|
||||
<string name="error_pass_match">Οι κωδικοί δεν ταιριάζουν.</string>
|
||||
@@ -105,7 +105,7 @@
|
||||
<string name="hint_keyfile">αρχείο κλειδιού</string>
|
||||
<string name="hint_length">μήκος</string>
|
||||
<string name="hint_pass">κωδικός</string>
|
||||
<string name="hint_login_pass">Κωδικός Πρόσβασης</string>
|
||||
<string name="password">Κωδικός Πρόσβασης</string>
|
||||
<string name="hint_title">όνομα</string>
|
||||
<string name="hint_url">διεύθυνση url</string>
|
||||
<string name="hint_username">όνομα χρήστη</string>
|
||||
|
||||
@@ -60,7 +60,7 @@ Spanish translation by José I. Paños. Updated by David García-Abad (23-09-201
|
||||
<string name="entry_confpassword">Confirmar contraseña:</string>
|
||||
<string name="entry_created">Creación: </string>
|
||||
<string name="entry_expires">Caducidad: </string>
|
||||
<string name="entry_keyfile">Archivo de clave (opcional)</string>
|
||||
<string name="entry_keyfile">Archivo de clave</string>
|
||||
<string name="entry_modified">Modificación: </string>
|
||||
<string name="entry_password">Contraseña:</string>
|
||||
<string name="entry_save">Guardar</string>
|
||||
@@ -79,7 +79,7 @@ Spanish translation by José I. Paños. Updated by David García-Abad (23-09-201
|
||||
<string name="error_invalid_db">Base de datos no válida.</string>
|
||||
<string name="error_invalid_path">Ruta no válida.</string>
|
||||
<string name="error_no_name">Se necesita un nombre.</string>
|
||||
<string name="error_nopass">Se necesita una contraseña o un archivo de clave.</string>
|
||||
<string name="error_nokeyfile">Se necesita una contraseña o un archivo de clave.</string>
|
||||
<string name="error_out_of_memory">El dispositivo se quedó sin memory mientras analizada la base de datos. Puede ser demasiado grande para este dispositivo.</string>
|
||||
<string name="error_pass_gen_type">Debe seleccionar al menos un tipo de generación de contraseñas</string>
|
||||
<string name="error_pass_match">Las contraseñas no coinciden.</string>
|
||||
@@ -97,7 +97,7 @@ Spanish translation by José I. Paños. Updated by David García-Abad (23-09-201
|
||||
<string name="hint_group_name">Nombre de grupo</string>
|
||||
<string name="hint_keyfile">archivo clave</string>
|
||||
<string name="hint_length">longitud</string>
|
||||
<string name="hint_login_pass">Contraseña</string>
|
||||
<string name="password">Contraseña</string>
|
||||
<string name="hint_pass">contraseña</string>
|
||||
<string name="hint_title">nombre</string>
|
||||
<string name="hint_url">url</string>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<string name="entry_confpassword">Pasahitza berretsi:</string>
|
||||
<string name="entry_created">Sortua: </string>
|
||||
<string name="entry_expires">Iraungitzen da: </string>
|
||||
<string name="entry_keyfile">Gako fitxategia (aukerazkoa)</string>
|
||||
<string name="entry_keyfile">Gako fitxategia</string>
|
||||
<string name="entry_modified">Aldatua: </string>
|
||||
<string name="entry_not_found">Sarreraren datuak ez aurkituak.</string>
|
||||
<string name="entry_password">Pasahitza:</string>
|
||||
@@ -85,7 +85,7 @@
|
||||
<string name="error_invalid_db">Datubase baliogabea.</string>
|
||||
<string name="error_invalid_path">Fitxategirako bide baliogabea.</string>
|
||||
<string name="error_no_name">Izen bat behar da.</string>
|
||||
<string name="error_nopass">Pasahitz edo gako fitxategi bat beharrezkoak dira.</string>
|
||||
<string name="error_nokeyfile">Pasahitz edo gako fitxategi bat beharrezkoak dira.</string>
|
||||
<string name="error_out_of_memory">Telefonoa memoriarik gabe gelditu da zure datubasea arakatzean. Handiegia izan daiteke zure telefonorako.</string>
|
||||
<string name="error_pass_gen_type">Pasahitza sortzeko mota bat gutxienez aukeratu behar da</string>
|
||||
<string name="error_pass_match">Pasahitzak ez datoz bat.</string>
|
||||
@@ -107,7 +107,7 @@
|
||||
<string name="hint_keyfile">gako fitxategia</string>
|
||||
<string name="hint_length">luzera</string>
|
||||
<string name="hint_pass">pasahitza</string>
|
||||
<string name="hint_login_pass">Pasahitza</string>
|
||||
<string name="password">Pasahitza</string>
|
||||
<string name="hint_title">izena</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">erabiltzaile izena</string>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<string name="entry_confpassword">Vahvista salasana:</string>
|
||||
<string name="entry_created">Luotu: </string>
|
||||
<string name="entry_expires">Vanhenee: </string>
|
||||
<string name="entry_keyfile">Avaintiedosto (valinnainen)</string>
|
||||
<string name="entry_keyfile">Avaintiedosto</string>
|
||||
<string name="entry_modified">Muokattu: </string>
|
||||
<string name="entry_not_found">Tietueen tietoja ei löytynyt.</string>
|
||||
<string name="entry_password">Salasana:</string>
|
||||
@@ -83,7 +83,7 @@
|
||||
<string name="error_invalid_db">Viallinen salasanatietokanta.</string>
|
||||
<string name="error_invalid_path">Viallinen hakemistopolku.</string>
|
||||
<string name="error_no_name">Nimi puuttuu.</string>
|
||||
<string name="error_nopass">Salasana tai avaintiedosto puuttuu.</string>
|
||||
<string name="error_nokeyfile">Salasana tai avaintiedosto puuttuu.</string>
|
||||
<string name="error_out_of_memory">Puhelimesta loppui muisti salasanatietokantaa avatessa. Tietokanta voi olla liian suuri tälle puhelinmallille.</string>
|
||||
<string name="error_pass_gen_type">Vähintään yksi salasanagenerointitapa täytyy olla valittuna.</string>
|
||||
<string name="error_pass_match">Salasanat eivät täsmää.</string>
|
||||
@@ -105,7 +105,7 @@
|
||||
<string name="hint_keyfile">avaintiedosto</string>
|
||||
<string name="hint_length">pituus</string>
|
||||
<string name="hint_pass">salasana</string>
|
||||
<string name="hint_login_pass">Salasana</string>
|
||||
<string name="password">Salasana</string>
|
||||
<string name="hint_title">nimi</string>
|
||||
<string name="hint_url">url-osoite</string>
|
||||
<string name="hint_username">käyttäjänimi</string>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<string name="entry_confpassword">Confirmer mot de passe</string>
|
||||
<string name="entry_created">Créé</string>
|
||||
<string name="entry_expires">Expire</string>
|
||||
<string name="entry_keyfile">Clé (facultative)</string>
|
||||
<string name="entry_keyfile">Fichier clé</string>
|
||||
<string name="entry_modified">Modifié</string>
|
||||
<string name="entry_not_found">Entry data not found.</string>
|
||||
<string name="entry_password">Mot de passe</string>
|
||||
@@ -86,12 +86,12 @@
|
||||
<string name="error_invalid_db">Base de données invalide.</string>
|
||||
<string name="error_invalid_path">Chemin invalide.</string>
|
||||
<string name="error_no_name">Le nom est obligatoire.</string>
|
||||
<string name="error_nopass">Un mot de passe ou clé de fichier est requis.</string>
|
||||
<string name="error_nokeyfile">Un fichier clé est requis.</string>
|
||||
<string name="error_out_of_memory">Votre appareil ne dispose pas de suffisamment de mémoire pour ouvrir votre base de données. Elle est probablement trop grosse pour votre appareil.</string>
|
||||
<string name="error_pass_gen_type">Au moins un type de génération de mot de passe doit être sélectionné</string>
|
||||
<string name="error_pass_match">Les mots de passe ne correspondent pas.</string>
|
||||
<string name="error_rounds_not_number">La série doit être un nombre.</string>
|
||||
<string name="error_rounds_too_large">Rounds too big. Setting to 2147483648.</string>
|
||||
<string name="error_rounds_too_large">Niveau trop gros. Paramètres à 2147483648.</string>
|
||||
<string name="error_string_key">A field name is required for each string.</string>
|
||||
<string name="error_title_required">Le titre est obligatoire.</string>
|
||||
<string name="error_wrong_length">Entrez un entier positif pour la longueur du champ</string>
|
||||
@@ -109,7 +109,7 @@
|
||||
<string name="hint_keyfile">clé de fichier</string>
|
||||
<string name="hint_length">longueur</string>
|
||||
<string name="hint_pass">mot de passe</string>
|
||||
<string name="hint_login_pass">Mot de passe</string>
|
||||
<string name="password">Mot de passe</string>
|
||||
<string name="hint_title">nom</string>
|
||||
<string name="hint_url">URL</string>
|
||||
<string name="hint_username">nom d\'utilisateur</string>
|
||||
@@ -172,6 +172,9 @@
|
||||
<string name="rounds">Niveau du chiffrement</string>
|
||||
<string name="rounds_explaination">Un niveau de chiffrement supérieur assure une protection supplémentaire contre les attaques de force brute, mais peut considérablement ralentir l\'ouverture et l\'enregistrement.</string>
|
||||
<string name="rounds_hint">niveaux</string>
|
||||
<string name="rounds_fix_title">Résolution de la base de données</string>
|
||||
<string name="rounds_fix">Clé de niveau de chiffrement avant corruption</string>
|
||||
<string name="rounds_fix_explanation">Si votre base de données a été corrompue par KeePassDroid version 2.2.0.0 à 2.2.0.6, entrez le niveau de chiffrement utilisé précédemment et cela vous permettra d\'ouvrir votre base.</string>
|
||||
<string name="saving_database">Enregistrement de la base de données…</string>
|
||||
<string name="space">Espace</string>
|
||||
<string name="search_label">Rechercher</string>
|
||||
@@ -191,6 +194,8 @@
|
||||
<string name="warning_password_encoding">Le format .kdb ne supporte que le jeu de caractère Latin1. Votre mot de passe doit contenir des caractères en dehors de ce jeu. Tous les caractères non-Latin1 sont convertis en un même caractère, ce qui diminue la sécurité de votre mot de passe. Le changement de votre mot de passe est recommandé.</string>
|
||||
<string name="warning_read_only">Votre carte SD est actuellement en lecture seule. Vous ne pourrez pas enregistrer les changements dans la base de données.</string>
|
||||
<string name="warning_unmounted">Votre carte SD n\'est actuellement pas montée sur votre appareil. Vous ne pourrez pas charger ou créer votre base de données.</string>
|
||||
<string name="warning_empty_password">Voulez-vous vraiment utiliser une chaine de caractères vide comme mot de passe ?</string>
|
||||
<string name="warning_no_encryption_key">Etes-vous sûr de ne vouloir utiliser aucune clé de chiffrement.</string>
|
||||
<string name="version_label">Version\u00A0:</string>
|
||||
<string name="configure_fingerprint">Reconnaissance d\'empreinte digitale non configuré pour cet appareil</string>
|
||||
<string name="scanning_fingerprint">Attente d\'une reconnaissance d\'empreinte digitale</string>
|
||||
@@ -199,6 +204,32 @@
|
||||
<string name="fingerprint_error">Problème d\'empreinte digitale</string>
|
||||
<string name="store_with_fingerprint">Utiliser l\'empreinte digitale pour stocker le mot de passe</string>
|
||||
<string name="no_password_stored">Pas de mot de passe encore stocké pour cette base de données</string>
|
||||
<string name="history">Historique</string>
|
||||
<string name="appearance">Apparence</string>
|
||||
<string name="general">Générale</string>
|
||||
<string name="password_size_title">Taille de mot de passe</string>
|
||||
<string name="password_size_summary">Définir la taille par défaut du mot de passe généré</string>
|
||||
<string name="list_password_generator_options_title">Caractères de mot de passe</string>
|
||||
<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="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="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>
|
||||
<string name="fingerprint_setting_text">Définissez votre empreinte digitale personnelle pour votre appareil dans </string>
|
||||
<string name="fingerprint_setting_way_text">Paramètres -> Sécurité -> Empreinte digitale</string>
|
||||
<string name="fingerprint_type_password_text">Tapez votre mot de passe dans Keepass DX</string>
|
||||
<string name="fingerprint_scan_to_store">Scannez votre empreinte digitale pour stocker votre mot de passe maître en toute sécurité</string>
|
||||
<string name="fingerprint_scan_to_open">Il suffit de scanner votre empreinte digitale dans Keepass DX lorsque le champ mot de passe est vide pour ouvrir la base de données</string>
|
||||
<string name="usage">Usage</string>
|
||||
<string name="fingerprint">Empreinte digitale</string>
|
||||
<string name="fingerprint_enable_title">Écoute d\'empreintes digitales</string>
|
||||
<string name="fingerprint_enable_summary">Activer l\'ouverture de la base de données par empreinte digitale</string>
|
||||
<string name="unavailable_feature_text">Impossible de démarrer cette fonctionnalité\nVotre version Android %1$d n\'est pas la version minimale %2$d requise</string>
|
||||
<string name="file_name">Nom de fichier</string>
|
||||
<string name="path">Chemin</string>
|
||||
<string name="assign_master_key">Assigner une clé maître</string>
|
||||
<string name="create_keepass_file">Créer un fichier keepass</string>
|
||||
|
||||
<string-array name="clipboard_timeout_options">
|
||||
<item>30 secondes</item>
|
||||
@@ -218,7 +249,5 @@
|
||||
<item>Light Theme</item>
|
||||
<item>Night Theme</item>
|
||||
</string-array>
|
||||
<string name="history">Historique</string>
|
||||
<string name="appearance">Apparence</string>
|
||||
<string name="general">Générale</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<string name="entry_confpassword">Jelszó megerősítése:</string>
|
||||
<string name="entry_created">Létrehozva:</string>
|
||||
<string name="entry_expires">Lejárat:</string>
|
||||
<string name="entry_keyfile">Kulcsfájl (opcionális)</string>
|
||||
<string name="entry_keyfile">Kulcsfájl</string>
|
||||
<string name="entry_modified">Módosítva:</string>
|
||||
<string name="entry_password">Jelszó:</string>
|
||||
<string name="entry_save">Mentés</string>
|
||||
@@ -79,7 +79,7 @@
|
||||
<string name="error_invalid_db">Érvénytelen adatbázis.</string>
|
||||
<string name="error_invalid_path">Érvénytelen útvonal.</string>
|
||||
<string name="error_no_name">Név szükséges.</string>
|
||||
<string name="error_nopass">Jelszóra vagy kulcsfájlra van szükség.</string>
|
||||
<string name="error_nokeyfile">Jelszóra vagy kulcsfájlra van szükség.</string>
|
||||
<string name="error_out_of_memory">A telefon memóriája megtelt az adatbázis feldolgozása közben. Lehet túl sok ez a telefonnak.</string>
|
||||
<string name="error_pass_gen_type">Legalább egy jelszógenerálási típust kell választania</string>
|
||||
<string name="error_pass_match">A jelszavak nem egyeznek meg.</string>
|
||||
@@ -102,7 +102,7 @@
|
||||
<string name="hint_keyfile">kulcsfájl</string>
|
||||
<string name="hint_length">hosszúság</string>
|
||||
<string name="hint_pass">jelszó</string>
|
||||
<string name="hint_login_pass">Jelszó</string>
|
||||
<string name="password">Jelszó</string>
|
||||
<string name="hint_title">név</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">felhasználónév</string>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<string name="entry_confpassword">Conferma password:</string>
|
||||
<string name="entry_created">Creato: </string>
|
||||
<string name="entry_expires">Scade: </string>
|
||||
<string name="entry_keyfile">File chiave (opzionale)</string>
|
||||
<string name="entry_keyfile">File chiave</string>
|
||||
<string name="entry_modified">Modificato: </string>
|
||||
<string name="entry_password">Password</string>
|
||||
<string name="entry_save">Salva</string>
|
||||
@@ -80,7 +80,7 @@
|
||||
<string name="error_invalid_db">Database non valido.</string>
|
||||
<string name="error_invalid_path">Percorso non valido.</string>
|
||||
<string name="error_no_name">E\' necessario un nome.</string>
|
||||
<string name="error_nopass">E\' necessaria una password o un file chiave.</string>
|
||||
<string name="error_nokeyfile">E\' necessaria una password o un file chiave.</string>
|
||||
<string name="error_out_of_memory">Il telefono ha esaurito la memoria durante l\'elaborazione del database. Potrebbe essere troppo grande per il tuo telefono.</string>
|
||||
<string name="error_pass_gen_type">Almeno un tipo di generazione password deve essere selezionato</string>
|
||||
<string name="error_pass_match">Le password non corrispondono.</string>
|
||||
@@ -98,7 +98,7 @@
|
||||
<string name="hint_group_name">Nome gruppo</string>
|
||||
<string name="hint_keyfile">file chiave</string>
|
||||
<string name="hint_length">lunghezza</string>
|
||||
<string name="hint_login_pass">Password</string>
|
||||
<string name="password">Password</string>
|
||||
<string name="hint_pass">password</string>
|
||||
<string name="hint_title">nome</string>
|
||||
<string name="hint_url">url</string>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
<string name="entry_confpassword">אשר סיסמה:</string>
|
||||
<string name="entry_created">תאריך יצירה: </string>
|
||||
<string name="entry_expires">פג תוקף: </string>
|
||||
<string name="entry_keyfile">קובץ מפתח (רשות)</string>
|
||||
<string name="entry_keyfile">קובץ מפתח</string>
|
||||
<string name="entry_modified">נערך לאחרונה: </string>
|
||||
<string name="entry_not_found">נתוני ערך לא נמצאו.</string>
|
||||
<string name="entry_password">סיסמה:</string>
|
||||
@@ -81,7 +81,7 @@
|
||||
<string name="error_invalid_db">מסד נתונים לא חוקי.</string>
|
||||
<string name="error_invalid_path">נתיב לא חוקי.</string>
|
||||
<string name="error_no_name">שם נדרש.</string>
|
||||
<string name="error_nopass">סיסמה או קובץ מפתח נדרשים.</string>
|
||||
<string name="error_nokeyfile">סיסמה או קובץ מפתח נדרשים.</string>
|
||||
<string name="error_out_of_memory">זיכרון המכשיר אזל בזמן ניתוח מסד הנתונים. יתכן והוא גדול מדי למכשירך.</string>
|
||||
<string name="error_pass_gen_type">לפחות סוג אחד ליצירת סיסמה צריך להיבחר</string>
|
||||
<string name="error_pass_match">הסיסמאות לא תואמות.</string>
|
||||
@@ -103,7 +103,7 @@
|
||||
<string name="hint_keyfile">קובץ המפתח</string>
|
||||
<string name="hint_length">אורך</string>
|
||||
<string name="hint_pass">סיסמה</string>
|
||||
<string name="hint_login_pass">סיסמה</string>
|
||||
<string name="password">סיסמה</string>
|
||||
<string name="hint_title">שם</string>
|
||||
<string name="hint_username">שם משתמש</string>
|
||||
<string name="install_from_market">התקן מחנות Play</string>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<string name="entry_confpassword">パスワードの確認:</string>
|
||||
<string name="entry_created">作成日: </string>
|
||||
<string name="entry_expires">有効期限: </string>
|
||||
<string name="entry_keyfile">キーファイル(オプション)</string>
|
||||
<string name="entry_keyfile">キーファイル</string>
|
||||
<string name="entry_modified">更新日: </string>
|
||||
<string name="entry_password">パスワード:</string>
|
||||
<string name="entry_save">保存</string>
|
||||
@@ -77,7 +77,7 @@
|
||||
<string name="error_invalid_db">無効なデータベースです。</string>
|
||||
<string name="error_invalid_path">パスが無効です。</string>
|
||||
<string name="error_no_name">タイトルは必須入力です。</string>
|
||||
<string name="error_nopass">パスワードかキーファイルが必要です。</string>
|
||||
<string name="error_nokeyfile">パスワードかキーファイルが必要です。</string>
|
||||
<string name="error_out_of_memory">データベース解析中にメモリ不足になりました。</string>
|
||||
<string name="error_pass_gen_type">少なくとも1つ以上のパスワード生成タイプを選択する必要があります。</string>
|
||||
<string name="error_pass_match">パスワードが一致しません</string>
|
||||
@@ -95,7 +95,7 @@
|
||||
<string name="hint_group_name">グループ名</string>
|
||||
<string name="hint_keyfile">キーファイル</string>
|
||||
<string name="hint_length">長さ</string>
|
||||
<string name="hint_login_pass">パスワード</string>
|
||||
<string name="password">パスワード</string>
|
||||
<string name="hint_pass">パスワード</string>
|
||||
<string name="hint_title">タイトル</string>
|
||||
<string name="hint_url">url</string>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<string name="hint_group_name">Grupės pavadinimas</string>
|
||||
<string name="hint_keyfile">rakto failas</string>
|
||||
<string name="hint_length">ilgis</string>
|
||||
<string name="hint_login_pass">Slaptažodis</string>
|
||||
<string name="password">Slaptažodis</string>
|
||||
<string name="hint_pass">slaptažodis</string>
|
||||
<string name="hint_title">pavadinimas</string>
|
||||
<string name="hint_url">url</string>
|
||||
@@ -102,7 +102,7 @@
|
||||
<string name="entry_not_found">Įrašo duomenys nerasti.</string>
|
||||
<string name="keyfile_is_empty">Rakto failas yra tuščias.</string>
|
||||
<string name="keyfile_does_not_exist">Rakto failas neegzistuoja.</string>
|
||||
<string name="entry_keyfile">Rakto failas (pasirinktinis)</string>
|
||||
<string name="entry_keyfile">Rakto failas</string>
|
||||
<string name="search_hint">Įrašo pavadinimas/aprašymas</string>
|
||||
<string name="menu_change_key">Pakeisti master raktą</string>
|
||||
<string name="entry_accessed">Naudota:</string>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<string name="entry_confpassword">Apstipriniet paroli:</string>
|
||||
<string name="entry_created">Izveidots:</string>
|
||||
<string name="entry_expires">Derīguma termiņš beidzas:</string>
|
||||
<string name="entry_keyfile">Atslēgas fails (pēc izvēles)</string>
|
||||
<string name="entry_keyfile">Atslēgas fails</string>
|
||||
<string name="entry_modified">Modificēts:</string>
|
||||
<string name="entry_password">Parole:</string>
|
||||
<string name="entry_save">Saglabāt</string>
|
||||
@@ -64,7 +64,7 @@
|
||||
<string name="error_invalid_db">Nederīga datu bāze.</string>
|
||||
<string name="error_invalid_path">Nederīgs ceļš.</string>
|
||||
<string name="error_no_name">Vajag ievadīt faila nosaukumu</string>
|
||||
<string name="error_nopass">Vajadzīga parole vai atslēgas fails.</string>
|
||||
<string name="error_nokeyfile">Vajadzīga parole vai atslēgas fails.</string>
|
||||
<string name="error_out_of_memory">Darbam ar datu bāzi, tālrunī nepietiek atmiņas.</string>
|
||||
<string name="error_pass_gen_type">Ir jāatlasa vismaz viens paroles ģenerēšanas tips</string>
|
||||
<string name="error_pass_match">Paroles nesakrīt.</string>
|
||||
@@ -86,7 +86,7 @@
|
||||
<string name="hint_keyfile">atslēgas fails</string>
|
||||
<string name="hint_length">garums</string>
|
||||
<string name="hint_pass">parole</string>
|
||||
<string name="hint_login_pass">Parole</string>
|
||||
<string name="password">Parole</string>
|
||||
<string name="hint_title">vārds</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">lietotājvārds</string>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<string name="entry_confpassword">Bevestig wachtwoord:</string>
|
||||
<string name="entry_created">Aangemaakt op: </string>
|
||||
<string name="entry_expires">Verloopt op: </string>
|
||||
<string name="entry_keyfile">Sleutelbestand (optioneel)</string>
|
||||
<string name="entry_keyfile">Sleutelbestand</string>
|
||||
<string name="entry_modified">Gewijzigd op: </string>
|
||||
<string name="entry_password">Wachtwoord:</string>
|
||||
<string name="entry_save">Opslaan</string>
|
||||
@@ -79,7 +79,7 @@
|
||||
<string name="error_invalid_db">Ongeldige database.</string>
|
||||
<string name="error_invalid_path">Ongeldige padnaam.</string>
|
||||
<string name="error_no_name">Een naam ontbreekt.</string>
|
||||
<string name="error_nopass">Een wachtwoord of sleutenbestand ontbreekt.</string>
|
||||
<string name="error_nokeyfile">Een wachtwoord of sleutenbestand ontbreekt.</string>
|
||||
<string name="error_out_of_memory">Onvoldoende vrij geheugen om de database te lezen. Misschien is de database te groot voor deze telefoon.</string>
|
||||
<string name="error_pass_gen_type">U moet minstens één type van wachtwoordgeneratie kiezen.</string>
|
||||
<string name="error_pass_match">Wachtwoorden zijn niet gelijk.</string>
|
||||
@@ -97,7 +97,7 @@
|
||||
<string name="hint_group_name">Groepnaam</string>
|
||||
<string name="hint_keyfile">sleutelbestand</string>
|
||||
<string name="hint_length">lengte</string>
|
||||
<string name="hint_login_pass">Wachtwoord</string>
|
||||
<string name="password">Wachtwoord</string>
|
||||
<string name="hint_pass">wachtwoord</string>
|
||||
<string name="hint_title">naam</string>
|
||||
<string name="hint_url">url</string>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<string name="entry_confpassword">Stadfest passordet:</string>
|
||||
<string name="entry_created">Laga: </string>
|
||||
<string name="entry_expires">Går ut: </string>
|
||||
<string name="entry_keyfile">Nøkkelfil (valfri)</string>
|
||||
<string name="entry_keyfile">Nøkkelfil</string>
|
||||
<string name="entry_modified">Endra: </string>
|
||||
<string name="entry_password">Passord:</string>
|
||||
<string name="entry_save">Lagra</string>
|
||||
@@ -77,7 +77,7 @@
|
||||
<string name="error_invalid_db">Ugyldig database.</string>
|
||||
<string name="error_invalid_path">Ugyldig stig.</string>
|
||||
<string name="error_no_name">Treng eit namn.</string>
|
||||
<string name="error_nopass">Treng eit passord eller ei nøkkelfil.</string>
|
||||
<string name="error_nokeyfile">Treng eit passord eller ei nøkkelfil.</string>
|
||||
<string name="error_out_of_memory">Telefonen gjekk tom for minne ved lesinga av databasen din. Databasen er kanskje for stor.</string>
|
||||
<string name="error_pass_gen_type">Du må velja minst éin passordlagingstype</string>
|
||||
<string name="error_pass_match">Passorda samsvarer ikkje.</string>
|
||||
@@ -95,7 +95,7 @@
|
||||
<string name="hint_group_name">Gruppenamn</string>
|
||||
<string name="hint_keyfile">nøkkelfil</string>
|
||||
<string name="hint_length">lengd</string>
|
||||
<string name="hint_login_pass">Passord</string>
|
||||
<string name="password">Passord</string>
|
||||
<string name="hint_pass">passord</string>
|
||||
<string name="hint_title">namn</string>
|
||||
<string name="hint_url">adresse</string>
|
||||
|
||||
@@ -56,7 +56,7 @@ along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
<string name="entry_confpassword">Potwierdź hasło:</string>
|
||||
<string name="entry_created">Utworzono: </string>
|
||||
<string name="entry_expires">Wygasa: </string>
|
||||
<string name="entry_keyfile">Plik klucza (opcjonalnie)</string>
|
||||
<string name="entry_keyfile">Plik klucza</string>
|
||||
<string name="entry_modified">Zmodyfikowano: </string>
|
||||
<string name="entry_password">Hasło</string>
|
||||
<string name="entry_save">Zapisz</string>
|
||||
@@ -75,7 +75,7 @@ along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
<string name="error_invalid_db">Nieprawidłowa baza danych.</string>
|
||||
<string name="error_invalid_path">Nieprawidłowa ścieżka dostępu.</string>
|
||||
<string name="error_no_name">Wymagana nazwa.</string>
|
||||
<string name="error_nopass">Wymagane hasło lub plik klucza.</string>
|
||||
<string name="error_nokeyfile">Wymagane hasło lub plik klucza.</string>
|
||||
<string name="error_out_of_memory">Podczas parsowania bazy danych zabrakło pamięci. Być może ta baza danych jest za duża dla Twojego urządzenia.</string>
|
||||
<string name="error_pass_gen_type">Przynajmniej jeden sposób generowania hasła musi być wybrany</string>
|
||||
<string name="error_pass_match">Hasła nie pasują do siebie.</string>
|
||||
@@ -93,7 +93,7 @@ along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
<string name="hint_group_name">Nazwa grupy</string>
|
||||
<string name="hint_keyfile">plik klucza</string>
|
||||
<string name="hint_length">długość</string>
|
||||
<string name="hint_login_pass">Hasło</string>
|
||||
<string name="password">Hasło</string>
|
||||
<string name="hint_pass">hasło</string>
|
||||
<string name="hint_title">nazwa</string>
|
||||
<string name="hint_url">url</string>
|
||||
@@ -150,7 +150,7 @@ along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
<string name="rounds">Złożoność szyfrowania</string>
|
||||
<string name="rounds_explaination">Większa złożoność szyfrowania zapewnia dodatkowe zabezpieczenie przed atakiem brute force, ale może spowolnić wczytywanie i zapisywanie bazy danych.</string>
|
||||
<string name="rounds_fix">Kluczowe rundy szyfrowania przed zniszczeniem</string>
|
||||
<string name="rounds_fix_explaination">Jeśli twoja baza danych została uszkodzona przez KeePassDroid w wersji 2.2.0.0 do 2.2.0.6, wprowadź liczbę rund użytych poprzednio, a to pozwoli ci otworzyć twoją bazę danych.</string>
|
||||
<string name="rounds_fix_explanation">Jeśli twoja baza danych została uszkodzona przez KeePassDroid w wersji 2.2.0.0 do 2.2.0.6, wprowadź liczbę rund użytych poprzednio, a to pozwoli ci otworzyć twoją bazę danych.</string>
|
||||
<string name="rounds_hint">złożoność</string>
|
||||
<string name="saving_database">Zapisywanie bazy danych…</string>
|
||||
<string name="space">Spacja</string>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<string name="entry_confpassword">Confirmar senha:</string>
|
||||
<string name="entry_created">Criado: </string>
|
||||
<string name="entry_expires">Expira: </string>
|
||||
<string name="entry_keyfile">Arquivo de chave (opcional)</string>
|
||||
<string name="entry_keyfile">Arquivo de chave</string>
|
||||
<string name="entry_modified">Modificado: </string>
|
||||
<string name="entry_password">Senha:</string>
|
||||
<string name="entry_save">Salvar</string>
|
||||
@@ -80,7 +80,7 @@
|
||||
<string name="error_invalid_db">Banco de dados inválido.</string>
|
||||
<string name="error_invalid_path">Caminho inválido.</string>
|
||||
<string name="error_no_name">É necessário um nome.</string>
|
||||
<string name="error_nopass">São necessários uma senha ou um arquivo de chaves.</string>
|
||||
<string name="error_nokeyfile">São necessários uma senha ou um arquivo de chaves.</string>
|
||||
<string name="error_out_of_memory">Foi atingida a capacidade máxima de memória do seu dispositivo ao carregar o banco de dados. O banco de dados pode ser muito grande para este dispositivo.</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>
|
||||
@@ -98,7 +98,7 @@
|
||||
<string name="hint_group_name">Nome do Grupo</string>
|
||||
<string name="hint_keyfile">arquivo de chave</string>
|
||||
<string name="hint_length">tamanho</string>
|
||||
<string name="hint_login_pass">Senha</string>
|
||||
<string name="password">Senha</string>
|
||||
<string name="hint_pass">senha</string>
|
||||
<string name="hint_title">nome</string>
|
||||
<string name="hint_url">url</string>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<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 (opcional)</string>
|
||||
<string name="entry_keyfile">Ficheiro chave</string>
|
||||
<string name="entry_modified">Modificado: </string>
|
||||
<string name="entry_not_found">Dados da entrada não encontrados.</string>
|
||||
<string name="entry_password">Palavra-passe:</string>
|
||||
@@ -86,7 +86,7 @@
|
||||
<string name="error_invalid_db">Base de dados inválida.</string>
|
||||
<string name="error_invalid_path">Caminho inválido.</string>
|
||||
<string name="error_no_name">É obrigatório introduzir um nome.</string>
|
||||
<string name="error_nopass">É obrigatório introduzir uma palavra-passe ou um ficheiro chave.</string>
|
||||
<string name="error_nokeyfile">É obrigatório introduzir uma palavra-passe ou um ficheiro chave.</string>
|
||||
<string name="error_out_of_memory">O dispositivo ficou sem memória ao analisar a base de dados. Poderá ser muito grande para o seu dispositivo.</string>
|
||||
<string name="error_pass_gen_type">Pelo menos um tipo de geração de palavra-passe deve ser selecionado</string>
|
||||
<string name="error_pass_match">As palavra-passe não coincidem.</string>
|
||||
@@ -109,7 +109,7 @@
|
||||
<string name="hint_keyfile">ficheiro chave</string>
|
||||
<string name="hint_length">comprimento</string>
|
||||
<string name="hint_pass">palavra-passe</string>
|
||||
<string name="hint_login_pass">Palavra-passe</string>
|
||||
<string name="password">Palavra-passe</string>
|
||||
<string name="hint_title">nome</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">nome de utilizador</string>
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<string name="error_invalid_db">Неверный формат базы</string>
|
||||
<string name="error_invalid_path">Путь указан неверно</string>
|
||||
<string name="error_no_name">Необходимо ввести имя файла</string>
|
||||
<string name="error_nopass">Необходим пароль или файл-ключ</string>
|
||||
<string name="error_nokeyfile">Необходим пароль или файл-ключ</string>
|
||||
<string name="error_out_of_memory">Недостаточно памяти для работы с базой</string>
|
||||
<string name="error_pass_gen_type">Выберите один или несколько типов символов</string>
|
||||
<string name="error_pass_match">Пароли не совпадают</string>
|
||||
@@ -105,7 +105,7 @@
|
||||
<string name="hint_keyfile">файл-ключ</string>
|
||||
<string name="hint_length">длина</string>
|
||||
<string name="hint_pass">пароль</string>
|
||||
<string name="hint_login_pass">пароль</string>
|
||||
<string name="password">пароль</string>
|
||||
<string name="hint_title">название</string>
|
||||
<string name="hint_url">ссылка</string>
|
||||
<string name="hint_username">логин</string>
|
||||
@@ -167,7 +167,7 @@
|
||||
<string name="rounds">Проходы шифрования</string>
|
||||
<string name="rounds_explaination">Больше проходов – выше стойкость базы к подбору пароля, но медленнее открытие и сохранение</string>
|
||||
<string name="rounds_fix">Проходы до поломки базы</string>
|
||||
<string name="rounds_fix_explaination">Если база была повреждена в KeePassDroid 2.2.0.0–2.2.0.6, введите ранее используемое количество проходов шифрования, чтобы открыть её</string>
|
||||
<string name="rounds_fix_explanation">Если база была повреждена в KeePassDroid 2.2.0.0–2.2.0.6, введите ранее используемое количество проходов шифрования, чтобы открыть её</string>
|
||||
<string name="rounds_hint">проходы</string>
|
||||
<string name="saving_database">Сохранение базы…</string>
|
||||
<string name="space">П р о б е л</string>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<string name="entry_confpassword">Potvrdiť heslo:</string>
|
||||
<string name="entry_created">Vytvorené: </string>
|
||||
<string name="entry_expires">Expirácia: </string>
|
||||
<string name="entry_keyfile">Súbor Keyfile (voliteľné)</string>
|
||||
<string name="entry_keyfile">Súbor Keyfile</string>
|
||||
<string name="entry_modified">Upravené: </string>
|
||||
<string name="entry_password">Heslo:</string>
|
||||
<string name="entry_save">Uložiť</string>
|
||||
@@ -77,7 +77,7 @@
|
||||
<string name="error_invalid_db">Chybná databáza.</string>
|
||||
<string name="error_invalid_path">Chybná cesta.</string>
|
||||
<string name="error_no_name">Vyžaduje sa meno.</string>
|
||||
<string name="error_nopass">Vyžaduje sa heslo, alebo súbor keyfile.</string>
|
||||
<string name="error_nokeyfile">Vyžaduje sa heslo, alebo súbor keyfile.</string>
|
||||
<string name="error_out_of_memory">Telefón vyčerpal pamäť pri analýze databázy. Možno je to príliš na Váš telefón.</string>
|
||||
<string name="error_pass_gen_type">Musí byť vybraý najmenej jeden typ generovania hesla</string>
|
||||
<string name="error_pass_match">Heslá sa nezhodujú.</string>
|
||||
@@ -95,7 +95,7 @@
|
||||
<string name="hint_group_name">Názov Skupiny</string>
|
||||
<string name="hint_keyfile">súbor keyfile</string>
|
||||
<string name="hint_length">dĺžka</string>
|
||||
<string name="hint_login_pass">Heslo</string>
|
||||
<string name="password">Heslo</string>
|
||||
<string name="hint_pass">heslo</string>
|
||||
<string name="hint_title">meno</string>
|
||||
<string name="hint_url">url</string>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<string name="entry_confpassword">Bekräfta lösenord:</string>
|
||||
<string name="entry_created">Skapad: </string>
|
||||
<string name="entry_expires">Upphör att gälla: </string>
|
||||
<string name="entry_keyfile">Nyckelfil (valfri)</string>
|
||||
<string name="entry_keyfile">Nyckelfil</string>
|
||||
<string name="entry_modified">Senast ändrad: </string>
|
||||
<string name="entry_password">Lösenord:</string>
|
||||
<string name="entry_save">Spara</string>
|
||||
@@ -84,7 +84,7 @@
|
||||
<string name="error_invalid_db">Ogiltig databas.</string>
|
||||
<string name="error_invalid_path">Ogiltig sökväg.</string>
|
||||
<string name="error_no_name">Ett namn krävs.</string>
|
||||
<string name="error_nopass">Ett lösenord eller en nyckelfil är ett krav.</string>
|
||||
<string name="error_nokeyfile">Ett lösenord eller en nyckelfil är ett krav.</string>
|
||||
<string name="error_out_of_memory">The phone ran out of memory while parsing your database. It may be too large for your phone.</string>
|
||||
<string name="error_pass_gen_type">At least one password generation type must be selected</string>
|
||||
<string name="error_pass_match">Lösenorden matchar inte.</string>
|
||||
@@ -106,7 +106,7 @@
|
||||
<string name="hint_keyfile">nyckelfil</string>
|
||||
<string name="hint_length">längd</string>
|
||||
<string name="hint_pass">lösenord</string>
|
||||
<string name="hint_login_pass">Lösenord</string>
|
||||
<string name="password">Lösenord</string>
|
||||
<string name="hint_title">namn</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">användarnamn</string>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<string name="entry_confpassword">Підтвердження паролю:</string>
|
||||
<string name="entry_created">Створено: </string>
|
||||
<string name="entry_expires">Закінчується: </string>
|
||||
<string name="entry_keyfile">Файл ключа (необов’язково)</string>
|
||||
<string name="entry_keyfile">Файл ключа</string>
|
||||
<string name="entry_modified">Змінено: </string>
|
||||
<string name="entry_password">Пароль:</string>
|
||||
<string name="entry_save">Зберегти</string>
|
||||
@@ -77,7 +77,7 @@
|
||||
<string name="error_invalid_db">Невірна база даних.</string>
|
||||
<string name="error_invalid_path">Невірний шлях.</string>
|
||||
<string name="error_no_name">Потрібне ім’я.</string>
|
||||
<string name="error_nopass">Необхідно пароль або файл ключа.</string>
|
||||
<string name="error_nokeyfile">Необхідно пароль або файл ключа.</string>
|
||||
<string name="error_out_of_memory">Телефону не вистачило пам’яті при аналізі вашої бази даних. Можливо база надто велика для вашог телефона.</string>
|
||||
<string name="error_pass_gen_type">Принаймні один тип генерації пароля необхідно вибрати.</string>
|
||||
<string name="error_pass_match">Паролі не співпадають.</string>
|
||||
@@ -95,7 +95,7 @@
|
||||
<string name="hint_group_name">Ім’я групи</string>
|
||||
<string name="hint_keyfile">файл-ключ</string>
|
||||
<string name="hint_length">довжина</string>
|
||||
<string name="hint_login_pass">Пароль</string>
|
||||
<string name="password">Пароль</string>
|
||||
<string name="hint_pass">пароль</string>
|
||||
<string name="hint_title">ім’я</string>
|
||||
<string name="hint_url">url</string>
|
||||
|
||||
10
app/src/main/res/values-v14/styles.xml
Normal file
10
app/src/main/res/values-v14/styles.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- For setting encapsulation -->
|
||||
<style name="KeepassDXStyle.Light" parent="KeepassDXStyle.Light.v21" >
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14</item>
|
||||
</style>
|
||||
<style name="KeepassDXStyle.Night" parent="KeepassDXStyle.Night.v21" >
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -2,9 +2,11 @@
|
||||
<resources>
|
||||
<!-- For elevation encapsulation -->
|
||||
<style name="KeepassDXStyle.Light" parent="KeepassDXStyle.Light.v21" >
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
|
||||
</style>
|
||||
<style name="KeepassDXStyle.Night" parent="KeepassDXStyle.Night.v21" >
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
|
||||
Copyright 2017 Jeremy Jamet / Kunzisoft.
|
||||
|
||||
This file is part of KeePass DX.
|
||||
|
||||
@@ -17,18 +17,6 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<EditText android:id="@+id/rounds"
|
||||
android:hint="@string/rounds_hint"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:inputType="number"/>
|
||||
<TextView android:id="@+id/rounds_explaination"
|
||||
android:text="@string/rounds_explaination"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_below="@id/rounds"/>
|
||||
</RelativeLayout>
|
||||
<resources>
|
||||
<bool name="fingerprint_enable_default" translatable="true">true</bool>
|
||||
</resources>
|
||||
51
app/src/main/res/values-v23/fingerprint.xml
Normal file
51
app/src/main/res/values-v23/fingerprint.xml
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<integer name="fingerprint_viewport_width">160</integer>
|
||||
<integer name="fingerprint_viewport_height">160</integer>
|
||||
<integer name="fingerprint_viewport_center">80</integer>
|
||||
<integer name="fingerprint_stroke_width">5</integer>
|
||||
<integer name="tick_cross_stroke_width">7</integer>
|
||||
<dimen name="fingerprint_width">80dp</dimen>
|
||||
<dimen name="fingerprint_height">80dp</dimen>
|
||||
|
||||
<!-- a pretty rough & ready re-draw of the fingerprint glyph from
|
||||
https://github.com/googlesamples/android-FingerprintDialog -->
|
||||
<string name="path_ridge_1">M56.2199243,45.3815903 C56.2199243,45.3815903 65.1913567,38.8543184 80.3604294,38.8543184 C95.5295022,38.8543184 103.720044,45.2851323 103.720044,45.2851323</string>
|
||||
<string name="path_ridge_2">M45.5181172,67.9181841 C49.9761548,62.7019025 59.122049,49.7790452 80.2279027,49.7790452 C101.333756,49.7790452 110.740506,62.0384399 114.937688,67.9181841</string>
|
||||
<string name="path_ridge_3">M51.7375623,107.718438 C51.7375623,107.718438 48.7129745,99.6302234 48.7129745,91.6334356 C48.7129745,81.3266864 55.9028711,60.2476586 80.4057228,60.2478671 C100.798248,60.2480407 112.457463,79.7942647 112.457463,88.386575 C112.457462,99.2963939 105.619846,103.039218 100.781849,102.18762 C95.9438519,101.336021 90.4490979,97.2187731 91.0639139,92.3178681 C91.67873,87.4169631 85.2177374,81.3265129 80.7504553,81.3266871 C73.0900115,81.3269859 69.8146331,85.3921834 69.8146329,92.2700585 C69.8146324,107.718437 83.7557525,121.02713 91.6787289,121.027128</string>
|
||||
<string name="path_ridge_4">M70.7357889,121.024995 C70.7357889,121.024995 57.4650216,106.018711 58.8888756,91.5596242 C60.5513085,74.6777941 73.9858126,70.313752 80.3788823,70.3807995 C86.771952,70.4478469 101.550994,76.8218704 101.550997,92.2895418</string>
|
||||
<string name="path_ridge_5">M80.1599645,91.1813411 C80.1599645,91.1813411 81.1144795,102.68333 86.7971146,107.529716 C93.2390527,113.023667 105.911091,112.342743 105.911091,112.342743</string>
|
||||
|
||||
<string name="path_tick">M52.2735573,79.0771904 C52.2735573,79.0771904 69.2403688,96.0440006 69.2403683,96.0440014 C69.2403679,96.0440021 109.820188,55.4641819 109.820188,55.4641819</string>
|
||||
|
||||
<string name="path_cross_1">M62,62 C62,62 80.5647617,80.5647617 80.564762,80.564762 C80.5647622,80.5647622 94.2921789,94.223714 98.5644262,98.5644262</string>
|
||||
<string name="path_cross_2">M98.5644262,62 C98.5644251,62 81.1979242,79.366503 81.1979229,79.3665033 C81.1979216,79.3665035 62,98.5644262 62,98.5644262</string>
|
||||
|
||||
<!-- a 'window' which is ¼ of the height of the viewport that we use as a clip during the 'scan'
|
||||
operation by animating it from the top to the bottom and back. -->
|
||||
<string name="clip_path_scan_top">M0 0 L160 0 L160 40 L0 40 Z</string>
|
||||
<string name="clip_path_scan_bottom">M0 120 L160 120 L160 160 L0 160 Z</string>
|
||||
|
||||
<color name="fingerprint_ridge">#deffffff</color>
|
||||
<color name="fingerprint_ridge_scan">#ffffffff</color>
|
||||
|
||||
<color name="circle_default">#ff607d8b</color>
|
||||
|
||||
</resources>
|
||||
@@ -58,7 +58,7 @@
|
||||
<string name="entry_confpassword">确认密码:</string>
|
||||
<string name="entry_created">创建:</string>
|
||||
<string name="entry_expires">失效时间:</string>
|
||||
<string name="entry_keyfile">密钥文件(可选)</string>
|
||||
<string name="entry_keyfile">密钥文件</string>
|
||||
<string name="entry_modified">修改时间:: </string>
|
||||
<string name="entry_password">密码:</string>
|
||||
<string name="entry_save">保存</string>
|
||||
@@ -77,7 +77,7 @@
|
||||
<string name="error_invalid_db">非法数据库。</string>
|
||||
<string name="error_invalid_path">非法路径。</string>
|
||||
<string name="error_no_name">用户名是必须的。</string>
|
||||
<string name="error_nopass">密码或者密钥文件是必须的。</string>
|
||||
<string name="error_nokeyfile">密码或者密钥文件是必须的。</string>
|
||||
<string name="error_out_of_memory">这款手机运行内存不足而不能解析数据库。这可能是数据库太大的缘故。</string>
|
||||
<string name="error_pass_gen_type">至少必须选择一个密码生成类型</string>
|
||||
<string name="error_pass_match">密码不匹配。</string>
|
||||
@@ -95,7 +95,7 @@
|
||||
<string name="hint_group_name">群组名</string>
|
||||
<string name="hint_keyfile">密钥文件</string>
|
||||
<string name="hint_length">长度</string>
|
||||
<string name="hint_login_pass">密码</string>
|
||||
<string name="password">密码</string>
|
||||
<string name="hint_pass">密码</string>
|
||||
<string name="hint_title">名称</string>
|
||||
<string name="hint_url">网址</string>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<string name="entry_confpassword">確認密碼:</string>
|
||||
<string name="entry_created">創建:</string>
|
||||
<string name="entry_expires">失效時間:</string>
|
||||
<string name="entry_keyfile">密鑰文件(可選)</string>
|
||||
<string name="entry_keyfile">密鑰文件</string>
|
||||
<string name="entry_modified">修改時間:: </string>
|
||||
<string name="entry_password">密碼:</string>
|
||||
<string name="entry_save">保存</string>
|
||||
@@ -77,7 +77,7 @@
|
||||
<string name="error_invalid_db">非法資料庫。</string>
|
||||
<string name="error_invalid_path">非法路徑。</string>
|
||||
<string name="error_no_name">用戶名是必須的。</string>
|
||||
<string name="error_nopass">密碼或者密鑰檔是必須的。</string>
|
||||
<string name="error_nokeyfile">密碼或者密鑰檔是必須的。</string>
|
||||
<string name="error_out_of_memory">這款手機運行記憶體不足而不能解析資料庫。這可能是資料庫太大的緣故。</string>
|
||||
<string name="error_pass_gen_type">至少必須選擇一個密碼生成類型</string>
|
||||
<string name="error_pass_match">密碼不匹配。</string>
|
||||
@@ -95,7 +95,7 @@
|
||||
<string name="hint_group_name">群組名</string>
|
||||
<string name="hint_keyfile">密鑰文件</string>
|
||||
<string name="hint_length">長度</string>
|
||||
<string name="hint_login_pass">密碼</string>
|
||||
<string name="password">密碼</string>
|
||||
<string name="hint_pass">密碼</string>
|
||||
<string name="hint_title">名稱</string>
|
||||
<string name="hint_url">網址</string>
|
||||
|
||||
@@ -8,4 +8,8 @@
|
||||
<attr name="iconPreferenceColor" format="reference|color" />
|
||||
|
||||
<attr name="textColorInverse" format="reference|color" />
|
||||
|
||||
<declare-styleable name="RoundsDialog">
|
||||
<attr name="description" format="string" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
@@ -21,7 +21,6 @@
|
||||
<string name="app_name" translatable="false">KeePass DX</string>
|
||||
|
||||
<string name="clipboard_error_url" translatable="false">http://code.google.com/p/android/issues/detail?id=35732</string>
|
||||
<string name="default_file_path" translatable="false">/keepass/keepass.kdbx</string>
|
||||
<string name="donate_url" translatable="false"><![CDATA[https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KM6QMDAXZM3UU]]></string>
|
||||
<string name="homepage" translatable="false">http://www.kunzisoft.com/KeepassDX</string>
|
||||
<string name="issues" translatable="false">https://github.com/Kunzisoft/KeePassDX/issues</string>
|
||||
@@ -29,8 +28,11 @@
|
||||
<string name="oi_filemanager_web" translatable="false">https://openintents.googlecode.com/files/FileManager-2.0.2.apk</string>
|
||||
|
||||
<!-- Password generator -->
|
||||
<integer name="default_password_length" translatable="false">8</integer>
|
||||
|
||||
<string name="password_length_key" translatable="false">password_length_key</string>
|
||||
<string name="min_password_length" translatable="false">1</string>
|
||||
<string name="default_password_length" translatable="false">14</string>
|
||||
<string name="max_password_length" translatable="false">64</string>
|
||||
|
||||
<!-- Preference settings -->
|
||||
<string name="algorithm_key" translatable="false">algorithm</string>
|
||||
<string name="app_key" translatable="false">app</string>
|
||||
@@ -51,6 +53,9 @@
|
||||
<string name="saf_key" translatable="false">storage_access_framework_key</string>
|
||||
<integer name="roundsFix_default" translatable="false">100000</integer>
|
||||
<string name="setting_style_key" translatable="false">setting_style_key</string>
|
||||
<string name="clipboard_notifications_key" translatable="false">clipboard_notifications_key</string>
|
||||
<string name="lock_database_screen_off_key" translatable="false">lock_database_screen_off_key</string>
|
||||
<string name="fingerprint_enable_key" translatable="true">fingerprint_enable_key</string>
|
||||
|
||||
<bool name="maskpass_default" translatable="false">true</bool>
|
||||
<bool name="keyfile_default" translatable="false">true</bool>
|
||||
@@ -58,7 +63,10 @@
|
||||
<bool name="omitbackup_default" translatable="false">true</bool>
|
||||
<bool name="recentfile_default" translatable="false">true</bool>
|
||||
<bool name="saf_default" translatable="false">false</bool>
|
||||
|
||||
<bool name="clipboard_notifications_default" translatable="false">true</bool>
|
||||
<bool name="lock_database_screen_off_default" translatable="false">true</bool>
|
||||
<bool name="fingerprint_enable_default" translatable="true">false</bool>
|
||||
|
||||
<string name="clipboard_timeout_default" translatable="false">300000</string>
|
||||
<string-array name="clipboard_timeout_values">
|
||||
<item translatable="false">30000</item>
|
||||
@@ -66,16 +74,75 @@
|
||||
<item translatable="false">300000</item>
|
||||
<item translatable="false">-1</item>
|
||||
</string-array>
|
||||
|
||||
<string name="list_size_default" translatable="false">18</string>
|
||||
<string-array name="list_size_values">
|
||||
<item translatable="false">14</item>
|
||||
<item translatable="false">18</item>
|
||||
<item translatable="false">26</item>
|
||||
</string-array>
|
||||
|
||||
<string name="list_style_name_light" translatable="false">KeepassDXStyle_Light</string>
|
||||
<string name="list_style_name_night" translatable="false">KeepassDXStyle_Night</string>
|
||||
<string-array name="list_style_values">
|
||||
<item translatable="false">@string/list_style_name_light</item>
|
||||
<item translatable="false">@string/list_style_name_night</item>
|
||||
</string-array>
|
||||
|
||||
<string name="list_password_generator_options_key" translatable="false">list_password_generator_options_key</string>
|
||||
<string name="value_password_uppercase" translatable="false">value_password_uppercase</string>
|
||||
<string name="value_password_lowercase" translatable="false">value_password_lowercase</string>
|
||||
<string name="value_password_digits" translatable="false">value_password_digits</string>
|
||||
<string name="value_password_minus" translatable="false">value_password_minus</string>
|
||||
<string name="value_password_underline" translatable="false">value_password_underline</string>
|
||||
<string name="value_password_space" translatable="false">value_password_space</string>
|
||||
<string name="value_password_special" translatable="false">value_password_special</string>
|
||||
<string name="value_password_brackets" translatable="false">value_password_brackets</string>
|
||||
<string name="visual_uppercase" translatable="false">A-Z</string>
|
||||
<string name="visual_lowercase" translatable="false">a-z</string>
|
||||
<string name="visual_digits" translatable="false">0-9</string>
|
||||
<string name="visual_minus" translatable="false">-</string>
|
||||
<string name="visual_underline" translatable="false">_</string>
|
||||
<string name="visual_space" translatable="false"> </string>
|
||||
<string name="visual_special" translatable="false">&\/,^@.#":%\\='$!*`;+</string>
|
||||
<string name="visual_brackets" translatable="false">[](){}<></string>
|
||||
<string-array name="list_password_generator_options_default_values">
|
||||
<item translatable="false">@string/value_password_uppercase</item>
|
||||
<item translatable="false">@string/value_password_lowercase</item>
|
||||
<item translatable="false">@string/value_password_digits</item>
|
||||
</string-array>
|
||||
<string-array name="list_password_generator_options_values">
|
||||
<item translatable="false">@string/value_password_uppercase</item>
|
||||
<item translatable="false">@string/value_password_lowercase</item>
|
||||
<item translatable="false">@string/value_password_digits</item>
|
||||
<item translatable="false">@string/value_password_minus</item>
|
||||
<item translatable="false">@string/value_password_underline</item>
|
||||
<item translatable="false">@string/value_password_space</item>
|
||||
<item translatable="false">@string/value_password_special</item>
|
||||
<item translatable="false">@string/value_password_brackets</item>
|
||||
</string-array>
|
||||
<string-array name="list_password_generator_options_entries">
|
||||
<item translatable="false">@string/uppercase</item>
|
||||
<item translatable="false">@string/lowercase</item>
|
||||
<item translatable="false">@string/digits</item>
|
||||
<item translatable="false">@string/minus</item>
|
||||
<item translatable="false">@string/underline</item>
|
||||
<item translatable="false">@string/space</item>
|
||||
<item translatable="false">@string/special</item>
|
||||
<item translatable="false">@string/brackets</item>
|
||||
</string-array>
|
||||
|
||||
<string name="chapter_1">I</string>
|
||||
<string name="chapter_2">II</string>
|
||||
<string name="chapter_3">III</string>
|
||||
<string name="chapter_4">IV</string>
|
||||
<string name="chapter_5">V</string>
|
||||
|
||||
<string name="database_file_path_default" translatable="false">/keepass/</string>
|
||||
<string name="database_file_name_default" translatable="false">keepass</string>
|
||||
<string name="database_file_extension_default" translatable="false">.kdbx</string>
|
||||
<string-array name="file_types">
|
||||
<item translatable="false">@string/database_file_extension_default</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<string name="entry_confpassword">Confirm password:</string>
|
||||
<string name="entry_created">Created: </string>
|
||||
<string name="entry_expires">Expires: </string>
|
||||
<string name="entry_keyfile">Key file (optional)</string>
|
||||
<string name="entry_keyfile">Key file</string>
|
||||
<string name="entry_modified">Modified: </string>
|
||||
<string name="entry_not_found">Entry data not found.</string>
|
||||
<string name="entry_password">Password:</string>
|
||||
@@ -85,7 +85,7 @@
|
||||
<string name="error_invalid_db">Invalid database.</string>
|
||||
<string name="error_invalid_path">Invalid path.</string>
|
||||
<string name="error_no_name">A name is required.</string>
|
||||
<string name="error_nopass">A password or a keyfile is required.</string>
|
||||
<string name="error_nokeyfile">A keyfile is required.</string>
|
||||
<string name="error_out_of_memory">The phone ran out of memory while parsing your database. It may be too large for your phone.</string>
|
||||
<string name="error_pass_gen_type">At least one password generation type must be selected</string>
|
||||
<string name="error_pass_match">Passwords do not match.</string>
|
||||
@@ -108,7 +108,7 @@
|
||||
<string name="hint_keyfile">key file</string>
|
||||
<string name="hint_length">length</string>
|
||||
<string name="hint_pass">password</string>
|
||||
<string name="hint_login_pass">Password</string>
|
||||
<string name="password">Password</string>
|
||||
<string name="hint_title">name</string>
|
||||
<string name="hint_url">url</string>
|
||||
<string name="hint_username">username</string>
|
||||
@@ -171,9 +171,9 @@
|
||||
<string name="root">Root</string>
|
||||
<string name="rounds">Encryption Rounds</string>
|
||||
<string name="rounds_explaination">Higher encryption rounds provide additional protection against brute force attacks, but can really slow down loading and saving.</string>
|
||||
<string name="rounds_fix_title">Fix of database encryption rounds</string>
|
||||
<string name="rounds_fix_title">Fix of database</string>
|
||||
<string name="rounds_fix">Key encryption rounds before corruption</string>
|
||||
<string name="rounds_fix_explaination">If your database was corrupted by KeePassDroid version 2.2.0.0 to 2.2.0.6, enter the number of rounds used previously and this will allow you to open your database.</string>
|
||||
<string name="rounds_fix_explanation">If your database was corrupted by KeePassDroid version 2.2.0.0 to 2.2.0.6, enter the number of rounds used previously and this will allow you to open your database.</string>
|
||||
<string name="rounds_hint">rounds</string>
|
||||
<string name="saving_database">Saving database…</string>
|
||||
<string name="space">Space</string>
|
||||
@@ -194,6 +194,8 @@
|
||||
<string name="warning_password_encoding">The .kdb format only supports the Latin1 character set. Your password may contain characters outside of this character set. All non-Latin1 charaters are converted to the same character, which reduces the security of your password. Changing your password is recommended.</string>
|
||||
<string name="warning_read_only">Your sd card is currently read-only. You may not be able to save changes to your database.</string>
|
||||
<string name="warning_unmounted">Your sd card is not currently mounted on your device. You will not be able to load or create your database.</string>
|
||||
<string name="warning_empty_password">Do you really want to use an empty string as password ?</string>
|
||||
<string name="warning_no_encryption_key">Are you sure you do not want to use any encryption key ?</string>
|
||||
<string name="version_label">Version:</string>
|
||||
<string name="configure_fingerprint">Fingerprint supported but not configured for device</string>
|
||||
<string name="scanning_fingerprint">Listening for fingerprints</string>
|
||||
@@ -205,6 +207,30 @@
|
||||
<string name="history">History</string>
|
||||
<string name="appearance">Appearance</string>
|
||||
<string name="general">General</string>
|
||||
<string name="password_size_title">Password size</string>
|
||||
<string name="password_size_summary">Set the default size of the generated password</string>
|
||||
<string name="list_password_generator_options_title">Password characters</string>
|
||||
<string name="list_password_generator_options_summary">Set the default password generator characters</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="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>
|
||||
<string name="fingerprint_quick_unlock_title">How to configure fingerprint for quick unlocking ?</string>
|
||||
<string name="fingerprint_setting_text">Set your personnal fingerprint for your device in </string>
|
||||
<string name="fingerprint_setting_way_text">Settings -> Security -> Fingerprint</string>
|
||||
<string name="fingerprint_type_password_text">Type your password in Keepass DX</string>
|
||||
<string name="fingerprint_scan_to_store">Scan your fingerprint to store your master password securely</string>
|
||||
<string name="fingerprint_scan_to_open">Just scan your fingerprint in Keepass DX when the password field is empty to open the database</string>
|
||||
<string name="usage">Usage</string>
|
||||
<string name="fingerprint">Fingerprint</string>
|
||||
<string name="fingerprint_enable_title">Fingerprint listening</string>
|
||||
<string name="fingerprint_enable_summary">Enable database opening by fingerprint</string>
|
||||
<string name="unavailable_feature_text">Can not start this feature\nYour Android version %1$d is not the minimum version %2$d required</string>
|
||||
<string name="file_name">File name</string>
|
||||
<string name="path">Path</string>
|
||||
<string name="assign_master_key">Assign a master key</string>
|
||||
<string name="create_keepass_file">Create a keepass file</string>
|
||||
|
||||
<string-array name="clipboard_timeout_options">
|
||||
<item>30 seconds</item>
|
||||
@@ -224,4 +250,5 @@
|
||||
<item>Light Theme</item>
|
||||
<item>Night Theme</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -20,12 +20,9 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
|
||||
<!-- For elevation encapsulation in V21-->
|
||||
<!-- For setting encapsulation -->
|
||||
<style name="KeepassDXStyle.Light.v21" parent="Theme.AppCompat.Light">
|
||||
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
|
||||
@@ -237,4 +234,34 @@
|
||||
<item name="android:textSize">16sp</item>
|
||||
</style>
|
||||
|
||||
<!-- File Picker Theme -->
|
||||
<style name="KeepassDXStyle.FilePickerStyle.Night" parent="Theme.AppCompat.DialogWhenLarge">
|
||||
<!-- You can override this in your sub theme -->
|
||||
<item name="nnf_toolbarTheme">@style/ThemeOverlay.AppCompat.ActionBar</item>
|
||||
<item name="nnf_separator_color">@color/nnf_dark_separator_color</item>
|
||||
<item name="nnf_save_icon_color">?attr/colorAccent</item>
|
||||
<item name="nnf_dir_icon_color">?attr/colorAccent</item>
|
||||
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
|
||||
<item name="colorPrimary">@color/green</item>
|
||||
<item name="colorPrimaryDark">@color/green_dark</item>
|
||||
<item name="colorAccent">@color/orange</item>
|
||||
</style>
|
||||
|
||||
<style name="KeepassDXStyle.FilePickerStyle.Light" parent="Theme.AppCompat.Light.DialogWhenLarge">
|
||||
<item name="nnf_toolbarTheme">@style/ThemeOverlay.AppCompat.ActionBar</item>
|
||||
<item name="nnf_separator_color">@color/nnf_light_separator_color</item>
|
||||
<item name="nnf_save_icon_color">?attr/colorAccent</item>
|
||||
<item name="nnf_dir_icon_color">?attr/colorAccent</item>
|
||||
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
|
||||
<item name="colorPrimary">@color/green</item>
|
||||
<item name="colorPrimaryDark">@color/green_dark</item>
|
||||
<item name="colorAccent">@color/orange</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -17,13 +17,33 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<PreferenceCategory
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/general">
|
||||
|
||||
<ListPreference
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:summary="@string/omitbackup_summary"
|
||||
android:defaultValue="@bool/omitbackup_default"
|
||||
android:title="@string/omitbackup_title"
|
||||
android:key="@string/omitbackup_key"/>
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:summary="@string/use_saf_summary"
|
||||
android:defaultValue="@bool/saf_default"
|
||||
android:title="@string/use_saf_title"
|
||||
android:key="@string/saf_key"/>
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:key="@string/clipboard_notifications_key"
|
||||
android:title="@string/clipboard_notifications_title"
|
||||
android:defaultValue="@bool/clipboard_notifications_default"
|
||||
android:summary="@string/clipboard_notifications_summary" />
|
||||
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/lock">
|
||||
<android.support.v7.preference.ListPreference
|
||||
android:key="@string/clipboard_timeout_key"
|
||||
android:title="@string/clipboard_timeout"
|
||||
android:summary="@string/clipboard_timeout_summary"
|
||||
@@ -31,7 +51,7 @@
|
||||
android:entryValues="@array/clipboard_timeout_values"
|
||||
android:dialogTitle="@string/clipboard_timeout"
|
||||
android:defaultValue="@string/clipboard_timeout_default"/>
|
||||
<ListPreference
|
||||
<android.support.v7.preference.ListPreference
|
||||
android:key="@string/app_timeout_key"
|
||||
android:title="@string/app_timeout"
|
||||
android:summary="@string/app_timeout_summary"
|
||||
@@ -39,52 +59,79 @@
|
||||
android:entryValues="@array/clipboard_timeout_values"
|
||||
android:dialogTitle="@string/app_timeout"
|
||||
android:defaultValue="@string/clipboard_timeout_default"/>
|
||||
<CheckBoxPreference
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:key="@string/lock_database_screen_off_key"
|
||||
android:title="@string/lock_database_screen_off_title"
|
||||
android:summary="@string/lock_database_screen_off_summary"
|
||||
android:defaultValue="@bool/lock_database_screen_off_default"/>
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/password">
|
||||
|
||||
<android.support.v7.preference.SeekBarPreference
|
||||
android:key="@string/password_length_key"
|
||||
android:title="@string/password_size_title"
|
||||
android:summary="@string/password_size_summary"
|
||||
android:defaultValue="@string/default_password_length"
|
||||
app:min="@string/min_password_length"
|
||||
android:max="@string/max_password_length" />
|
||||
|
||||
<android.support.v14.preference.MultiSelectListPreference
|
||||
android:key="@string/list_password_generator_options_key"
|
||||
android:title="@string/list_password_generator_options_title"
|
||||
android:summary="@string/list_password_generator_options_summary"
|
||||
android:entries="@array/list_password_generator_options_entries"
|
||||
android:entryValues="@array/list_password_generator_options_values"
|
||||
android:defaultValue="@array/list_password_generator_options_default_values"/>
|
||||
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:key="@string/maskpass_key"
|
||||
android:title="@string/maskpass_title"
|
||||
android:summary="@string/maskpass_summary"
|
||||
android:defaultValue="@bool/maskpass_default"/>
|
||||
<CheckBoxPreference
|
||||
android:summary="@string/omitbackup_summary"
|
||||
android:defaultValue="@bool/omitbackup_default"
|
||||
android:title="@string/omitbackup_title"
|
||||
android:key="@string/omitbackup_key"/>
|
||||
<CheckBoxPreference
|
||||
android:summary="@string/use_saf_summary"
|
||||
android:defaultValue="@bool/saf_default"
|
||||
android:title="@string/use_saf_title"
|
||||
android:key="@string/saf_key"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/history">
|
||||
|
||||
<CheckBoxPreference
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:summary="@string/recentfile_summary"
|
||||
android:defaultValue="@bool/recentfile_default"
|
||||
android:title="@string/recentfile_title"
|
||||
android:key="@string/recentfile_key"/>
|
||||
<CheckBoxPreference
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:key="@string/keyfile_key"
|
||||
android:title="@string/remember_keyfile_title"
|
||||
android:summary="@string/remember_keyfile_summary"
|
||||
android:dependency="@string/recentfile_key"
|
||||
android:defaultValue="@bool/keyfile_default"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/fingerprint">
|
||||
|
||||
<android.support.v14.preference.SwitchPreference
|
||||
android:key="@string/fingerprint_enable_key"
|
||||
android:title="@string/fingerprint_enable_title"
|
||||
android:summary="@string/fingerprint_enable_summary"
|
||||
android:defaultValue="@bool/fingerprint_enable_default"/>
|
||||
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/appearance">
|
||||
|
||||
<ListPreference
|
||||
<android.support.v7.preference.ListPreference
|
||||
android:title="@string/style_choose_title"
|
||||
android:summary="@string/style_choose_summary"
|
||||
android:key="@string/setting_style_key"
|
||||
android:defaultValue="@string/list_style_name_light"
|
||||
android:entries="@array/list_style_names"
|
||||
android:entryValues="@array/list_style_values" />
|
||||
<ListPreference
|
||||
<android.support.v7.preference.ListPreference
|
||||
android:key="@string/list_size_key"
|
||||
android:title="@string/list_size_title"
|
||||
android:summary="@string/list_size_summary"
|
||||
@@ -93,5 +140,5 @@
|
||||
android:dialogTitle="@string/list_size_summary"
|
||||
android:defaultValue="@string/list_size_default"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
</android.support.v7.preference.PreferenceScreen>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<PreferenceScreen
|
||||
<android.support.v7.preference.PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/general">
|
||||
|
||||
<Preference
|
||||
<android.support.v7.preference.Preference
|
||||
android:key="@string/algorithm_key"
|
||||
android:title="@string/algorithm"
|
||||
android:enabled="false"/>
|
||||
@@ -31,9 +31,8 @@
|
||||
android:key="@string/rounds_key"
|
||||
android:persistent="false"
|
||||
android:title="@string/rounds"
|
||||
android:dialogLayout="@layout/database_settings"
|
||||
android:positiveButtonText="@string/entry_save"
|
||||
android:negativeButtonText="@string/entry_cancel"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
</android.support.v7.preference.PreferenceScreen>
|
||||
|
||||
@@ -17,35 +17,32 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:custom="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<PreferenceCategory
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/application">
|
||||
<Preference
|
||||
<android.support.v7.preference.Preference
|
||||
android:key="@string/app_key"
|
||||
android:title="@string/menu_app_settings"
|
||||
android:icon="@drawable/ic_phone_android_white_24dp"
|
||||
android:persistent="false" />
|
||||
</PreferenceCategory>
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
<android.support.v7.preference.PreferenceCategory
|
||||
android:title="@string/database">
|
||||
<Preference
|
||||
<android.support.v7.preference.Preference
|
||||
android:key="@string/db_key"
|
||||
android:title="@string/menu_db_settings"
|
||||
android:icon="@drawable/ic_data_usage_white_24dp"
|
||||
android:persistent="false" />
|
||||
<!-- TODO change dialog android:summary="@string/rounds_fix_explaination" -->
|
||||
<EditTextPreference
|
||||
<com.keepassdroid.settings.RoundsPreference
|
||||
android:key="@string/roundsFix_key"
|
||||
android:title="@string/rounds_fix_title"
|
||||
android:summary="@string/rounds_fix"
|
||||
custom:description="@string/rounds_fix_explanation"
|
||||
android:defaultValue="@integer/roundsFix_default"
|
||||
android:icon="@drawable/ic_filter_tilt_shift_pref_24dp"
|
||||
android:numeric="integer"
|
||||
android:inputType="numberDecimal"
|
||||
android:digits="0123456789"/>
|
||||
</PreferenceCategory>
|
||||
android:icon="@drawable/ic_filter_tilt_shift_pref_24dp" />
|
||||
</android.support.v7.preference.PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
</android.support.v7.preference.PreferenceScreen>
|
||||
|
||||
BIN
art/TypePassword.png
Normal file
BIN
art/TypePassword.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
art/screen0.jpg
BIN
art/screen0.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 44 KiB |
BIN
art/screen1.jpg
BIN
art/screen1.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 47 KiB |
Reference in New Issue
Block a user