Compare commits
17
Commits
v1.0-beta1
...
v1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6a31ed789 | ||
|
|
9c272a0d4d | ||
|
|
3e626a37db | ||
|
|
e2150e3823 | ||
|
|
6480fef315 | ||
|
|
95df2ceb42 | ||
|
|
189698dddb | ||
|
|
438d5581aa | ||
|
|
7af78b11f5 | ||
|
|
5d68211ce9 | ||
|
|
a7e1a88dc8 | ||
|
|
3054032a37 | ||
|
|
79279630ba | ||
|
|
e019fb6db2 | ||
|
|
85bdecc573 | ||
|
|
21f3d93295 | ||
|
|
888e9d0e4a |
@@ -0,0 +1,7 @@
|
||||
language: android
|
||||
android:
|
||||
components:
|
||||
- android-28
|
||||
- build-tools-28.0.3
|
||||
script:
|
||||
- ./gradlew build test
|
||||
+18
-4
@@ -7,13 +7,23 @@ android {
|
||||
applicationId "com.beemdevelopment.aegis"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 28
|
||||
versionCode 18
|
||||
versionName "1.0-beta1"
|
||||
versionCode 19
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError true
|
||||
disable "MissingTranslation"
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests.all {
|
||||
useJUnitPlatform()
|
||||
|
||||
ignoreFailures false
|
||||
testLogging {
|
||||
events "passed", "skipped", "failed", "standardOut", "standardError"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,11 +70,15 @@ dependencies {
|
||||
implementation "com.github.topjohnwu.libsu:io:${libsuVersion}"
|
||||
implementation 'com.github.bumptech.glide:annotations:4.9.0'
|
||||
implementation 'com.github.bumptech.glide:glide:4.9.0'
|
||||
implementation ("com.github.bumptech.glide:recyclerview-integration:4.9.0") {
|
||||
implementation "com.mikepenz:iconics-core:3.2.5"
|
||||
implementation 'com.mikepenz:material-design-iconic-typeface:2.2.0.5@aar'
|
||||
implementation 'de.psdev.licensesdialog:licensesdialog:2.1.0'
|
||||
implementation("com.github.bumptech.glide:recyclerview-integration:4.9.0") {
|
||||
transitive = false
|
||||
}
|
||||
annotationProcessor 'androidx.annotation:annotation:1.1.0'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2'
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.beemdevelopment.aegis;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
tools:ignore="GoogleAppIndexingWarning"
|
||||
tools:replace="android:theme">
|
||||
<activity
|
||||
android:name=".ui.AboutActivity"
|
||||
android:label="@string/title_activity_about"></activity>
|
||||
<activity
|
||||
android:name=".ui.SelectEntriesActivity"
|
||||
android:label="Select entries" />
|
||||
@@ -26,12 +29,15 @@
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="otpauth" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
* {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
body {
|
||||
background-color: #%1$s;
|
||||
color: #%2$s;
|
||||
}
|
||||
ul {
|
||||
list-style-position: inside;
|
||||
padding: 0;
|
||||
padding-left: 5px;
|
||||
}
|
||||
li {
|
||||
padding-bottom: 8px;
|
||||
list-style-position: outside;
|
||||
margin-left: 1em;
|
||||
}
|
||||
h3 {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
<h3>Version 1.0</h3>
|
||||
<h4>New</h4>
|
||||
<ul>
|
||||
<li>New icon</li>
|
||||
<li>Overhaul of interaction with the entry list</li>
|
||||
<li>Persistent notification while the vault is unlocked</li>
|
||||
<li>Language override option</li>
|
||||
<li>Support for importing from FreeOTP+</li>
|
||||
<li>Ability to toggle password visibility during unlock</li>
|
||||
<li>Support for deeplinking otpauth URIs</li>
|
||||
</ul>
|
||||
<h4>Fixes</h4>
|
||||
<ul>
|
||||
<li>Bad overall performance and high battery usage</li>
|
||||
<li>Codes with an uneven number of digits are displayed incorrectly</li>
|
||||
<li>Crash when entering a large value for OTP period</li>
|
||||
</ul>
|
||||
</body>
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.beemdevelopment.aegis;
|
||||
|
||||
public enum CancelAction {
|
||||
KILL,
|
||||
CLOSE
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.beemdevelopment.aegis.encoding.Base64Exception;
|
||||
import com.beemdevelopment.aegis.otp.GoogleAuthInfo;
|
||||
import com.beemdevelopment.aegis.otp.OtpInfo;
|
||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||
import com.beemdevelopment.aegis.util.UUIDMap;
|
||||
|
||||
import org.json.JSONException;
|
||||
@@ -133,11 +134,34 @@ public class DatabaseEntry extends UUIDMap.Value {
|
||||
}
|
||||
|
||||
DatabaseEntry entry = (DatabaseEntry) o;
|
||||
return super.equals(entry)
|
||||
&& getName().equals(entry.getName())
|
||||
return super.equals(entry) && equivalates(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports whether this entry is equivalent to the given entry. The UUIDs of these
|
||||
* entries are ignored during the comparison, so they are not necessarily the same
|
||||
* instance.
|
||||
*/
|
||||
public boolean equivalates(DatabaseEntry entry) {
|
||||
return getName().equals(entry.getName())
|
||||
&& getIssuer().equals(entry.getIssuer())
|
||||
&& Objects.equals(getGroup(), entry.getGroup())
|
||||
&& getInfo().equals(entry.getInfo())
|
||||
&& Arrays.equals(getIcon(), entry.getIcon());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports whether this entry has its values set to the defaults.
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
return equivalates(getDefault());
|
||||
}
|
||||
|
||||
public static DatabaseEntry getDefault() {
|
||||
try {
|
||||
return new DatabaseEntry(new TotpInfo(null));
|
||||
} catch (OtpInfoException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,16 @@ import android.content.Context;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class FingerprintHelper {
|
||||
private FingerprintHelper() {
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public static FingerprintManager getManager(Context context) {
|
||||
if (isSupported() && PermissionHelper.granted(context, Manifest.permission.USE_FINGERPRINT)) {
|
||||
if (PermissionHelper.granted(context, Manifest.permission.USE_FINGERPRINT)) {
|
||||
FingerprintManager manager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
|
||||
if (manager != null && manager.isHardwareDetected() && manager.hasEnrolledFingerprints()) {
|
||||
return manager;
|
||||
@@ -20,6 +23,11 @@ public class FingerprintHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public static boolean isAvailable(Context context) {
|
||||
return getManager(context) != null;
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.beemdevelopment.aegis.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.beemdevelopment.aegis.Preferences;
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.Theme;
|
||||
import com.beemdevelopment.aegis.helpers.ThemeHelper;
|
||||
import com.beemdevelopment.aegis.ui.glide.GlideLicense;
|
||||
import com.mikepenz.iconics.Iconics;
|
||||
import com.mikepenz.iconics.context.IconicsLayoutInflater2;
|
||||
import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic;
|
||||
|
||||
import androidx.core.view.LayoutInflaterCompat;
|
||||
|
||||
import de.psdev.licensesdialog.LicenseResolver;
|
||||
import de.psdev.licensesdialog.LicensesDialog;
|
||||
import de.psdev.licensesdialog.licenses.License;
|
||||
|
||||
public class AboutActivity extends AegisActivity {
|
||||
|
||||
private static String GITHUB = "https://github.com/beemdevelopment/Aegis";
|
||||
private static String WEBSITE_ALEXANDER = "https://alexbakker.me";
|
||||
private static String GITHUB_MICHAEL = "https://github.com/michaelschattgen";
|
||||
|
||||
private static String MAIL_BEEMDEVELOPMENT = "beemdevelopment@gmail.com";
|
||||
private static String WEBSITE_BEEMDEVELOPMENT = "https://beem.dev/";
|
||||
private static String PLAYSTORE_BEEMDEVELOPMENT = "https://play.google.com/store/apps/details?id=com.beemdevelopment.aegis";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
LayoutInflaterCompat.setFactory2(getLayoutInflater(), new IconicsLayoutInflater2(getDelegate()));
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_about);
|
||||
|
||||
Iconics.init(getApplicationContext());
|
||||
Iconics.registerFont(new MaterialDesignIconic());
|
||||
|
||||
View btnLicenses = findViewById(R.id.btn_licenses);
|
||||
btnLicenses.setOnClickListener(v -> showLicenseDialog());
|
||||
|
||||
TextView appVersion = findViewById(R.id.app_version);
|
||||
appVersion.setText(getCurrentVersion());
|
||||
|
||||
View btnGithub = findViewById(R.id.btn_github);
|
||||
btnGithub.setOnClickListener(v -> openUrl(GITHUB));
|
||||
|
||||
View btnAlexander = findViewById(R.id.btn_alexander);
|
||||
btnAlexander.setOnClickListener(v -> openUrl(WEBSITE_ALEXANDER));
|
||||
|
||||
View btnMichael = findViewById(R.id.btn_michael);
|
||||
btnMichael.setOnClickListener(v -> openUrl(GITHUB_MICHAEL));
|
||||
|
||||
View btnMail = findViewById(R.id.btn_email);
|
||||
btnMail.setOnClickListener(v -> openMail(MAIL_BEEMDEVELOPMENT));
|
||||
|
||||
View btnWebsite = findViewById(R.id.btn_website);
|
||||
btnWebsite.setOnClickListener(v -> openUrl(WEBSITE_BEEMDEVELOPMENT));
|
||||
|
||||
View btnRate = findViewById(R.id.btn_rate);
|
||||
btnRate.setOnClickListener(v -> openUrl(PLAYSTORE_BEEMDEVELOPMENT ));
|
||||
|
||||
View btnChangelog = findViewById(R.id.btn_changelog);
|
||||
btnChangelog.setOnClickListener(v -> {
|
||||
ChangelogDialog.create().setTheme(getCurrentTheme()).show(getSupportFragmentManager(), "CHANGELOG_DIALOG");
|
||||
});
|
||||
}
|
||||
|
||||
private String getCurrentVersion() {
|
||||
try {
|
||||
return getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "Unknown version";
|
||||
}
|
||||
|
||||
private void openUrl(String url) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW);
|
||||
browserIntent.setData(Uri.parse(url));
|
||||
browserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
|
||||
private void openMail(String mailaddress) {
|
||||
Intent mailIntent = new Intent(Intent.ACTION_SENDTO);
|
||||
mailIntent.setData(Uri.parse("mailto:" + mailaddress));
|
||||
mailIntent.putExtra(Intent.EXTRA_EMAIL, mailaddress);
|
||||
mailIntent.putExtra(Intent.EXTRA_SUBJECT, R.string.app_name_full);
|
||||
|
||||
startActivity(Intent.createChooser(mailIntent, this.getString(R.string.email)));
|
||||
}
|
||||
|
||||
private void showLicenseDialog() {
|
||||
String stylesheet = getString(R.string.custom_notices_format_style);
|
||||
int backgroundColorResource = getCurrentTheme() == Theme.AMOLED ? R.attr.cardBackgroundFocused : R.attr.cardBackground;
|
||||
String backgroundColor = String.format("%06X", (0xFFFFFF & ThemeHelper.getThemeColor(backgroundColorResource, getTheme())));
|
||||
String textColor = String.format("%06X", (0xFFFFFF & ThemeHelper.getThemeColor(R.attr.primaryText, getTheme())));
|
||||
String licenseColor = String.format("%06X", (0xFFFFFF & ThemeHelper.getThemeColor(R.attr.cardBackgroundFocused, getTheme())));
|
||||
|
||||
stylesheet = String.format(stylesheet, backgroundColor, textColor, licenseColor);
|
||||
|
||||
LicenseResolver.registerLicense(new GlideLicense());
|
||||
new LicensesDialog.Builder(this)
|
||||
.setNotices(R.raw.notices)
|
||||
.setTitle(R.string.licenses)
|
||||
.setNoticesCssStyle(stylesheet)
|
||||
.setIncludeOwnLicense(true)
|
||||
.build()
|
||||
.show();
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import java.util.Locale;
|
||||
public abstract class AegisActivity extends AppCompatActivity implements AegisApplication.LockListener {
|
||||
private boolean _resumed;
|
||||
private AegisApplication _app;
|
||||
private Theme _currentTheme;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -89,6 +90,8 @@ public abstract class AegisActivity extends AppCompatActivity implements AegisAp
|
||||
}
|
||||
|
||||
protected void setPreferredTheme(Theme theme) {
|
||||
_currentTheme = theme;
|
||||
|
||||
switch (theme) {
|
||||
case LIGHT:
|
||||
setTheme(R.style.AppTheme);
|
||||
@@ -136,4 +139,8 @@ public abstract class AegisActivity extends AppCompatActivity implements AegisAp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Theme getCurrentTheme() {
|
||||
return _currentTheme;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.beemdevelopment.aegis.ui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
@@ -17,6 +18,7 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.CancelAction;
|
||||
import com.beemdevelopment.aegis.crypto.KeyStoreHandle;
|
||||
import com.beemdevelopment.aegis.crypto.KeyStoreHandleException;
|
||||
import com.beemdevelopment.aegis.db.DatabaseFileCredentials;
|
||||
@@ -39,11 +41,13 @@ import androidx.appcompat.app.AlertDialog;
|
||||
public class AuthActivity extends AegisActivity implements FingerprintUiHelper.Callback, SlotListTask.Callback {
|
||||
private EditText _textPassword;
|
||||
|
||||
private CancelAction _cancelAction;
|
||||
private SlotList _slots;
|
||||
private FingerprintUiHelper _fingerHelper;
|
||||
private FingerprintManager.CryptoObject _fingerCryptoObj;
|
||||
|
||||
@Override
|
||||
@SuppressLint("NewApi")
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_auth);
|
||||
@@ -69,11 +73,13 @@ public class AuthActivity extends AegisActivity implements FingerprintUiHelper.C
|
||||
|
||||
Intent intent = getIntent();
|
||||
_slots = (SlotList) intent.getSerializableExtra("slots");
|
||||
_cancelAction = (CancelAction) intent.getSerializableExtra("cancelAction");
|
||||
|
||||
// only show the fingerprint controls if the api version is new enough, permission is granted, a scanner is found and a fingerprint slot is found
|
||||
FingerprintManager manager = FingerprintHelper.getManager(this);
|
||||
if (manager != null && _slots.has(FingerprintSlot.class)) {
|
||||
if (_slots.has(FingerprintSlot.class) && FingerprintHelper.isSupported() && FingerprintHelper.isAvailable(this)) {
|
||||
boolean invalidated = false;
|
||||
FingerprintManager manager = FingerprintHelper.getManager(this);
|
||||
|
||||
try {
|
||||
// find a fingerprint slot with an id that matches an alias in the keystore
|
||||
for (FingerprintSlot slot : _slots.findAll(FingerprintSlot.class)) {
|
||||
@@ -144,10 +150,19 @@ public class AuthActivity extends AegisActivity implements FingerprintUiHelper.C
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// ignore back button presses
|
||||
switch (_cancelAction) {
|
||||
case KILL:
|
||||
finishAffinity();
|
||||
|
||||
case CLOSE:
|
||||
Intent intent = new Intent();
|
||||
setResult(RESULT_CANCELED, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("NewApi")
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
@@ -157,6 +172,7 @@ public class AuthActivity extends AegisActivity implements FingerprintUiHelper.C
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("NewApi")
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
@@ -166,6 +182,7 @@ public class AuthActivity extends AegisActivity implements FingerprintUiHelper.C
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("NewApi")
|
||||
public void onAuthenticated() {
|
||||
trySlots(FingerprintSlot.class, _fingerCryptoObj.getCipher());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.beemdevelopment.aegis.ui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.InflateException;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.Theme;
|
||||
import com.beemdevelopment.aegis.helpers.ThemeHelper;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class ChangelogDialog extends DialogFragment {
|
||||
private Theme _themeStyle;
|
||||
|
||||
public static ChangelogDialog create() {
|
||||
return new ChangelogDialog();
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final View customView;
|
||||
try {
|
||||
customView = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_web_view, null);
|
||||
} catch (InflateException e) {
|
||||
e.printStackTrace();
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(android.R.string.dialog_alert_title)
|
||||
.setMessage(getString(R.string.webview_error))
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
AlertDialog dialog = new AlertDialog.Builder(getActivity())
|
||||
.setTitle("Changelog")
|
||||
.setView(customView)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
|
||||
final WebView webView = customView.findViewById(R.id.web_view);
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
||||
try (InputStream html = getActivity().getAssets().open("changelog.html")) {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(html, "UTF-8"));
|
||||
String str;
|
||||
while ((str = in.readLine()) != null)
|
||||
buf.append(str);
|
||||
|
||||
in.close();
|
||||
String changelog = buf.toString();
|
||||
changelog = replaceStylesheet(changelog);
|
||||
webView.loadData(changelog, "text/html", "UTF-8");
|
||||
} catch (IOException e) {
|
||||
webView.loadData("<h1>Unable to load</h1><p>" + e.getLocalizedMessage() + "</p>", "text/html", "UTF-8");
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private String replaceStylesheet(String changelog) {
|
||||
int backgroundColorResource = _themeStyle == Theme.AMOLED ? R.attr.cardBackgroundFocused : R.attr.cardBackground;
|
||||
String backgroundColor = String.format("%06X", (0xFFFFFF & ThemeHelper.getThemeColor(backgroundColorResource, getContext().getTheme())));
|
||||
String textColor = String.format("%06X", (0xFFFFFF & ThemeHelper.getThemeColor(R.attr.primaryText, getContext().getTheme())));
|
||||
|
||||
return String.format(changelog, backgroundColor, textColor);
|
||||
}
|
||||
|
||||
public ChangelogDialog setTheme(Theme theme) {
|
||||
_themeStyle = theme;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Build;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
@@ -35,6 +36,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
@@ -178,6 +180,7 @@ public class Dialogs {
|
||||
showSecureDialog(dialog);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
public static void showFingerprintDialog(Activity activity, Dialogs.SlotListener listener) {
|
||||
View view = activity.getLayoutInflater().inflate(R.layout.dialog_fingerprint, null);
|
||||
TextView textFingerprint = view.findViewById(R.id.text_fingerprint);
|
||||
|
||||
@@ -133,51 +133,49 @@ public class EditEntryActivity extends AegisActivity {
|
||||
_advancedSettings = findViewById(R.id.expandableLayout);
|
||||
|
||||
// fill the fields with values if possible
|
||||
if (_origEntry != null) {
|
||||
if (_origEntry.hasIcon()) {
|
||||
Glide.with(this)
|
||||
.asDrawable()
|
||||
.load(_origEntry)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(false)
|
||||
.into(_iconView);
|
||||
_hasCustomIcon = true;
|
||||
} else {
|
||||
TextDrawable drawable = TextDrawableHelper.generate(_origEntry.getIssuer(), _origEntry.getName(), _iconView);
|
||||
_iconView.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
_textName.setText(_origEntry.getName());
|
||||
_textIssuer.setText(_origEntry.getIssuer());
|
||||
|
||||
OtpInfo info = _origEntry.getInfo();
|
||||
if (info instanceof TotpInfo) {
|
||||
_textPeriod.setText(Integer.toString(((TotpInfo) info).getPeriod()));
|
||||
_rowPeriod.setVisibility(View.VISIBLE);
|
||||
} else if (info instanceof HotpInfo) {
|
||||
_textCounter.setText(Long.toString(((HotpInfo) info).getCounter()));
|
||||
_rowCounter.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
_textDigits.setText(Integer.toString(info.getDigits()));
|
||||
|
||||
byte[] secretBytes = _origEntry.getInfo().getSecret();
|
||||
if (secretBytes != null) {
|
||||
char[] secretChars = Base32.encode(secretBytes);
|
||||
_textSecret.setText(secretChars, 0, secretChars.length);
|
||||
}
|
||||
|
||||
String type = _origEntry.getInfo().getType();
|
||||
_spinnerType.setSelection(getStringResourceIndex(R.array.otp_types_array, type), false);
|
||||
|
||||
String algo = _origEntry.getInfo().getAlgorithm(false);
|
||||
_spinnerAlgo.setSelection(getStringResourceIndex(R.array.otp_algo_array, algo), false);
|
||||
|
||||
String group = _origEntry.getGroup();
|
||||
setGroup(group);
|
||||
if (_origEntry.hasIcon()) {
|
||||
Glide.with(this)
|
||||
.asDrawable()
|
||||
.load(_origEntry)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(false)
|
||||
.into(_iconView);
|
||||
_hasCustomIcon = true;
|
||||
} else {
|
||||
TextDrawable drawable = TextDrawableHelper.generate(_origEntry.getIssuer(), _origEntry.getName(), _iconView);
|
||||
_iconView.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
_textName.setText(_origEntry.getName());
|
||||
_textIssuer.setText(_origEntry.getIssuer());
|
||||
|
||||
OtpInfo info = _origEntry.getInfo();
|
||||
if (info instanceof TotpInfo) {
|
||||
_textPeriod.setText(Integer.toString(((TotpInfo) info).getPeriod()));
|
||||
_rowPeriod.setVisibility(View.VISIBLE);
|
||||
} else if (info instanceof HotpInfo) {
|
||||
_textCounter.setText(Long.toString(((HotpInfo) info).getCounter()));
|
||||
_rowCounter.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
_textDigits.setText(Integer.toString(info.getDigits()));
|
||||
|
||||
byte[] secretBytes = _origEntry.getInfo().getSecret();
|
||||
if (secretBytes != null) {
|
||||
char[] secretChars = Base32.encode(secretBytes);
|
||||
_textSecret.setText(secretChars, 0, secretChars.length);
|
||||
}
|
||||
|
||||
String type = _origEntry.getInfo().getType();
|
||||
_spinnerType.setSelection(getStringResourceIndex(R.array.otp_types_array, type), false);
|
||||
|
||||
String algo = _origEntry.getInfo().getAlgorithm(false);
|
||||
_spinnerAlgo.setSelection(getStringResourceIndex(R.array.otp_algo_array, algo), false);
|
||||
|
||||
String group = _origEntry.getGroup();
|
||||
setGroup(group);
|
||||
|
||||
// update the icon if the text changed
|
||||
_textIssuer.addTextChangedListener(_iconChangeListener);
|
||||
_textName.addTextChangedListener(_iconChangeListener);
|
||||
@@ -331,7 +329,7 @@ public class EditEntryActivity extends AegisActivity {
|
||||
}
|
||||
|
||||
// close the activity if the entry has not been changed
|
||||
if (_origEntry != null && !_hasChangedIcon && _origEntry.equals(entry.get())) {
|
||||
if (!_hasChangedIcon && _origEntry.equals(entry.get())) {
|
||||
super.onBackPressed();
|
||||
return;
|
||||
}
|
||||
@@ -465,7 +463,6 @@ public class EditEntryActivity extends AegisActivity {
|
||||
throw new ParseException("Secret is not valid base32.");
|
||||
}
|
||||
|
||||
// set otp info
|
||||
OtpInfo info;
|
||||
try {
|
||||
switch (type.toLowerCase()) {
|
||||
@@ -494,14 +491,8 @@ public class EditEntryActivity extends AegisActivity {
|
||||
throw new ParseException("The entered info is incorrect: " + e.getMessage());
|
||||
}
|
||||
|
||||
// set database entry info
|
||||
DatabaseEntry entry;
|
||||
if (_origEntry == null) {
|
||||
entry = new DatabaseEntry(info);
|
||||
} else {
|
||||
entry = Cloner.clone(_origEntry);
|
||||
entry.setInfo(info);
|
||||
}
|
||||
DatabaseEntry entry = Cloner.clone(_origEntry);
|
||||
entry.setInfo(info);
|
||||
entry.setIssuer(_textIssuer.getText().toString());
|
||||
entry.setName(_textName.getText().toString());
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public class IntroActivity extends AppIntro2 implements DerivationTask.Callback
|
||||
|
||||
SliderPage homeSliderPage = new SliderPage();
|
||||
homeSliderPage.setTitle(getString(R.string.welcome));
|
||||
homeSliderPage.setImageDrawable(R.drawable.icon_foreground_white);
|
||||
homeSliderPage.setImageDrawable(R.drawable.app_icon);
|
||||
homeSliderPage.setTitleColor(getResources().getColor(R.color.primary_text_dark));
|
||||
homeSliderPage.setDescription(getString(R.string.app_description));
|
||||
homeSliderPage.setDescColor(getResources().getColor(R.color.primary_text_dark));
|
||||
@@ -83,7 +83,7 @@ public class IntroActivity extends AppIntro2 implements DerivationTask.Callback
|
||||
SliderPage endSliderPage = new SliderPage();
|
||||
endSliderPage.setTitle(getString(R.string.setup_completed));
|
||||
endSliderPage.setDescription(getString(R.string.setup_completed_description));
|
||||
endSliderPage.setImageDrawable(R.drawable.icon_foreground_white);
|
||||
endSliderPage.setImageDrawable(R.drawable.app_icon);
|
||||
endSliderPage.setBgColor(getResources().getColor(R.color.colorSecondary));
|
||||
_endSlide = AppIntroFragment.newInstance(endSliderPage);
|
||||
addSlide(_endSlide);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.beemdevelopment.aegis.ui;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
@@ -16,17 +15,15 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SubMenu;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.SearchView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
|
||||
import com.beemdevelopment.aegis.AegisApplication;
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.SortCategory;
|
||||
import com.beemdevelopment.aegis.CancelAction;
|
||||
import com.beemdevelopment.aegis.ViewMode;
|
||||
import com.beemdevelopment.aegis.db.DatabaseEntry;
|
||||
import com.beemdevelopment.aegis.db.DatabaseFileCredentials;
|
||||
@@ -38,7 +35,6 @@ import com.beemdevelopment.aegis.otp.GoogleAuthInfo;
|
||||
import com.beemdevelopment.aegis.otp.GoogleAuthInfoException;
|
||||
import com.beemdevelopment.aegis.ui.views.EntryListView;
|
||||
import com.getbase.floatingactionbutton.FloatingActionsMenu;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.ChecksumException;
|
||||
import com.google.zxing.FormatException;
|
||||
@@ -49,6 +45,7 @@ import com.google.zxing.RGBLuminanceSource;
|
||||
import com.google.zxing.Reader;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.mikepenz.iconics.context.IconicsContextWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -92,6 +89,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
_app = (AegisApplication) getApplication();
|
||||
_db = _app.getDatabaseManager();
|
||||
_loaded = false;
|
||||
@@ -231,9 +229,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||
|
||||
private void startEditProfileActivity(int requestCode, DatabaseEntry entry, boolean isNew) {
|
||||
Intent intent = new Intent(this, EditEntryActivity.class);
|
||||
if (entry != null) {
|
||||
intent.putExtra("entry", entry);
|
||||
}
|
||||
intent.putExtra("entry", entry != null ? entry : DatabaseEntry.getDefault());
|
||||
intent.putExtra("isNew", isNew);
|
||||
intent.putExtra("selectedGroup", _selectedGroup);
|
||||
intent.putExtra("groups", new ArrayList<>(_db.getGroups()));
|
||||
@@ -502,6 +498,11 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||
_entryListView.removeEntry(oldEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context newBase) {
|
||||
super.attachBaseContext(IconicsContextWrapper.wrap(newBase));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
_menu = menu;
|
||||
@@ -548,10 +549,16 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_settings:
|
||||
case R.id.action_settings: {
|
||||
Intent intent = new Intent(this, PreferencesActivity.class);
|
||||
startActivityForResult(intent, CODE_PREFERENCES);
|
||||
return true;
|
||||
}
|
||||
case R.id.action_about: {
|
||||
Intent intent = new Intent(this, AboutActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
case R.id.action_lock:
|
||||
_app.lock();
|
||||
return true;
|
||||
@@ -636,6 +643,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||
Intent intent = new Intent(this, AuthActivity.class);
|
||||
intent.putExtra("slots", _db.getFileHeader().getSlots());
|
||||
intent.putExtra("requiresUnlock", false);
|
||||
intent.putExtra("cancelAction", CancelAction.KILL);
|
||||
startActivityForResult(intent, CODE_DECRYPT);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.widget.Toast;
|
||||
|
||||
import com.beemdevelopment.aegis.AegisApplication;
|
||||
import com.beemdevelopment.aegis.BuildConfig;
|
||||
import com.beemdevelopment.aegis.CancelAction;
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.Theme;
|
||||
import com.beemdevelopment.aegis.ViewMode;
|
||||
@@ -284,7 +285,9 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||
SlotList slots = creds.getSlots();
|
||||
|
||||
if (!slots.has(FingerprintSlot.class)) {
|
||||
Dialogs.showFingerprintDialog(getActivity(), new RegisterFingerprintListener());
|
||||
if (FingerprintHelper.isSupported() && FingerprintHelper.isAvailable(getContext())) {
|
||||
Dialogs.showFingerprintDialog(getActivity(), new RegisterFingerprintListener());
|
||||
}
|
||||
} else {
|
||||
// remove the fingerprint slot
|
||||
FingerprintSlot slot = slots.find(FingerprintSlot.class);
|
||||
@@ -468,6 +471,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||
|
||||
Intent intent = new Intent(getActivity(), AuthActivity.class);
|
||||
intent.putExtra("slots", ((AegisImporter.EncryptedState) state).getSlots());
|
||||
intent.putExtra("cancelAction", CancelAction.CLOSE);
|
||||
startActivityForResult(intent, CODE_IMPORT_DECRYPT);
|
||||
} else {
|
||||
state.decrypt(getActivity(), new DatabaseImporter.DecryptListener() {
|
||||
@@ -669,8 +673,9 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||
boolean multiPassword = slots.findAll(PasswordSlot.class).size() > 1;
|
||||
boolean multiFinger = slots.findAll(FingerprintSlot.class).size() > 1;
|
||||
boolean showSlots = BuildConfig.DEBUG || multiPassword || multiFinger;
|
||||
boolean canUseFinger = FingerprintHelper.isSupported() && FingerprintHelper.isAvailable(getContext());
|
||||
_setPasswordPreference.setEnabled(!multiPassword);
|
||||
_fingerprintPreference.setEnabled(FingerprintHelper.getManager(getContext()) != null && !multiFinger);
|
||||
_fingerprintPreference.setEnabled(canUseFinger && !multiFinger);
|
||||
_fingerprintPreference.setChecked(slots.has(FingerprintSlot.class), true);
|
||||
_slotsPreference.setVisible(showSlots);
|
||||
} else {
|
||||
|
||||
@@ -43,7 +43,9 @@ public class SlotManagerActivity extends AegisActivity implements SlotAdapter.Li
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
findViewById(R.id.button_add_fingerprint).setOnClickListener(view -> {
|
||||
Dialogs.showFingerprintDialog(this ,this);
|
||||
if (FingerprintHelper.isSupported() && FingerprintHelper.isAvailable(this)) {
|
||||
Dialogs.showFingerprintDialog(this ,this);
|
||||
}
|
||||
});
|
||||
|
||||
findViewById(R.id.button_add_password).setOnClickListener(view -> {
|
||||
@@ -71,7 +73,7 @@ public class SlotManagerActivity extends AegisActivity implements SlotAdapter.Li
|
||||
// only show the fingerprint option if we can get an instance of the fingerprint manager
|
||||
// and if none of the slots in the collection has a matching alias in the keystore
|
||||
int visibility = View.VISIBLE;
|
||||
if (FingerprintHelper.getManager(this) != null) {
|
||||
if (FingerprintHelper.isSupported() && FingerprintHelper.isAvailable(this)) {
|
||||
try {
|
||||
KeyStoreHandle keyStore = new KeyStoreHandle();
|
||||
for (FingerprintSlot slot : _creds.getSlots().findAll(FingerprintSlot.class)) {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.beemdevelopment.aegis.ui.glide;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.beemdevelopment.aegis.R;
|
||||
|
||||
import de.psdev.licensesdialog.licenses.License;
|
||||
|
||||
public class GlideLicense extends License {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Glide License";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readSummaryTextFromResources(Context context) {
|
||||
return getContent(context, R.raw.glide_license);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readFullTextFromResources(Context context) {
|
||||
return getContent(context, R.raw.glide_license);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl() {
|
||||
return "https://github.com/bumptech/glide/blob/master/LICENSE";
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.beemdevelopment.aegis.ui.slides;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
@@ -70,6 +71,7 @@ public class CustomAuthenticatedSlide extends Fragment implements FingerprintUiH
|
||||
return EditTextHelper.getEditTextChars(_textPassword);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public Cipher getFingerCipher() {
|
||||
return _fingerCryptoObj.getCipher();
|
||||
}
|
||||
@@ -83,6 +85,7 @@ public class CustomAuthenticatedSlide extends Fragment implements FingerprintUiH
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("NewApi")
|
||||
public void onSlideSelected() {
|
||||
Intent intent = getActivity().getIntent();
|
||||
_cryptType = intent.getIntExtra("cryptType", CustomAuthenticationSlide.CRYPT_TYPE_INVALID);
|
||||
@@ -124,6 +127,7 @@ public class CustomAuthenticatedSlide extends Fragment implements FingerprintUiH
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressLint("NewApi")
|
||||
public void onSlideDeselected() {
|
||||
if (_fingerHelper != null) {
|
||||
_fingerAuthenticated = false;
|
||||
|
||||
+2
-2
@@ -1,5 +1,6 @@
|
||||
package com.beemdevelopment.aegis.ui.slides;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Bundle;
|
||||
@@ -34,8 +35,7 @@ public class CustomAuthenticationSlide extends Fragment implements ISlidePolicy,
|
||||
onCheckedChanged(_buttonGroup, _buttonGroup.getCheckedRadioButtonId());
|
||||
|
||||
// only enable the fingerprint option if the api version is new enough, permission is granted and a scanner is found
|
||||
FingerprintManager manager = FingerprintHelper.getManager(getContext());
|
||||
if (manager != null) {
|
||||
if (FingerprintHelper.isSupported() && FingerprintHelper.isAvailable(getContext())) {
|
||||
RadioButton button = view.findViewById(R.id.rb_fingerprint);
|
||||
TextView text = view.findViewById(R.id.text_rb_fingerprint);
|
||||
button.setEnabled(true);
|
||||
|
||||
@@ -8,7 +8,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.LayoutAnimationController;
|
||||
import android.widget.Toast;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.SortCategory;
|
||||
@@ -47,6 +47,7 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||
private PeriodProgressBar _progressBar;
|
||||
private boolean _showProgress;
|
||||
private ViewMode _viewMode;
|
||||
private LinearLayout _emptyStateView;
|
||||
|
||||
private UiRefresher _refresher;
|
||||
|
||||
@@ -107,6 +108,8 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||
}
|
||||
});
|
||||
|
||||
_emptyStateView = view.findViewById(R.id.vEmptyList);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -218,14 +221,17 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||
|
||||
public void addEntry(DatabaseEntry entry) {
|
||||
_adapter.addEntry(entry);
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
public void addEntries(List<DatabaseEntry> entries) {
|
||||
_adapter.addEntries(entries);
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
public void removeEntry(DatabaseEntry entry) {
|
||||
_adapter.removeEntry(entry);
|
||||
updateEmptyState();
|
||||
}
|
||||
|
||||
public void clearEntries() {
|
||||
@@ -267,6 +273,16 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||
_recyclerView.addItemDecoration(_dividerDecoration);
|
||||
}
|
||||
|
||||
private void updateEmptyState() {
|
||||
if (_adapter.getItemCount() > 0) {
|
||||
_recyclerView.setVisibility(View.VISIBLE);
|
||||
_emptyStateView.setVisibility(View.GONE);
|
||||
} else {
|
||||
_recyclerView.setVisibility(View.GONE);
|
||||
_emptyStateView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void onEntryClick(DatabaseEntry entry);
|
||||
void onEntryMove(DatabaseEntry entry1, DatabaseEntry entry2);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 75 KiB |
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:background="?attr/background"
|
||||
tools:context="com.beemdevelopment.aegis.ui.AboutActivity">
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:isScrollContainer="true">
|
||||
|
||||
<include layout="@layout/content_about" />
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -0,0 +1,484 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="8dp"
|
||||
app:cardUseCompatPadding="true">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardUseCompatPadding="true"
|
||||
android:background="?attr/cardBackground"
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:ignore="MissingPrefix">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="8dp"
|
||||
android:background="?attr/cardBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="72dp"
|
||||
android:orientation="horizontal"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:text="@string/app_name_full"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Headline" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-info-outline"
|
||||
app:ico_size="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/version"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0.0.0 (0)"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||
tools:ignore="HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_changelog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-time-restore"
|
||||
app:ico_size="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/changelog"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/whats_new"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_github"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-github"
|
||||
app:ico_size="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/github"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/github_description"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_licenses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-file-text"
|
||||
app:ico_size="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/licenses"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/licenses_description"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardUseCompatPadding="true"
|
||||
android:background="?attr/cardBackground"
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:ignore="MissingPrefix">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="8dp"
|
||||
android:background="?attr/cardBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:text="@string/org_name_full"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||
android:textColor="?android:textColorSecondary" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_alexander"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-account"
|
||||
app:ico_size="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/author_alex"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/country_netherlands"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_michael"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-account"
|
||||
app:ico_size="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/author_michael"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/country_netherlands"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_email"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-email"
|
||||
app:ico_size="16dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:text="@string/email_us"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_website"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-globe"
|
||||
app:ico_size="16dp" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:text="@string/visit_website"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardUseCompatPadding="true"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="?attr/cardBackground"
|
||||
tools:ignore="MissingPrefix">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="8dp"
|
||||
android:background="?attr/cardBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="16dp"
|
||||
android:text="@string/about_support"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||
android:textColor="?android:textColorSecondary" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_rate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:ico_color="@color/icon_about"
|
||||
app:ico_icon="gmi-star"
|
||||
app:ico_size="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginLeft="32dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/support_rate"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/support_rate_description"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp">
|
||||
|
||||
<WebView
|
||||
android:id="@+id/web_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -22,4 +22,47 @@
|
||||
android:id="@+id/rvKeyProfiles"
|
||||
android:layoutAnimation="@anim/layout_animation_fall_down"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center|fill_vertical"
|
||||
android:id="@+id/vEmptyList"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="150dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/ic_qrcode_scan"
|
||||
android:tint="?attr/primaryText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/empty_list_title"
|
||||
android:paddingTop="17dp"
|
||||
android:textColor="?attr/primaryText"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView5"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:lineSpacingExtra="5dp"
|
||||
android:paddingTop="7dp"
|
||||
android:text="@string/empty_list"
|
||||
android:textAlignment="center" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -63,4 +63,9 @@
|
||||
android:orderInCategory="100"
|
||||
android:title="@string/action_settings"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/action_about"
|
||||
android:orderInCategory="110"
|
||||
android:title="@string/action_about"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
License for everything not in third_party and not otherwise marked:
|
||||
|
||||
Copyright 2014 Google, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those of the
|
||||
authors and should not be interpreted as representing official policies, either expressed
|
||||
or implied, of Google, Inc.
|
||||
---------------------------------------------------------------------------------------------
|
||||
License for third_party/disklrucache:
|
||||
|
||||
Copyright 2012 Jake Wharton
|
||||
Copyright 2011 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.
|
||||
---------------------------------------------------------------------------------------------
|
||||
License for third_party/gif_decoder:
|
||||
|
||||
Copyright (c) 2013 Xcellent Creations, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
---------------------------------------------------------------------------------------------
|
||||
License for third_party/gif_encoder/AnimatedGifEncoder.java and
|
||||
third_party/gif_encoder/LZWEncoder.java:
|
||||
|
||||
No copyright asserted on the source code of this class. May be used for any
|
||||
purpose, however, refer to the Unisys LZW patent for restrictions on use of
|
||||
the associated LZWEncoder class. Please forward any corrections to
|
||||
kweiner@fmsware.com.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
License for third_party/gif_encoder/NeuQuant.java
|
||||
|
||||
Copyright (c) 1994 Anthony Dekker
|
||||
|
||||
NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. See
|
||||
"Kohonen neural networks for optimal colour quantization" in "Network:
|
||||
Computation in Neural Systems" Vol. 5 (1994) pp 351-367. for a discussion of
|
||||
the algorithm.
|
||||
|
||||
Any party obtaining a copy of these files from the author, directly or
|
||||
indirectly, is granted, free of charge, a full and unrestricted irrevocable,
|
||||
world-wide, paid up, royalty-free, nonexclusive right and license to deal in
|
||||
this software and documentation files (the "Software"), including without
|
||||
limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons who
|
||||
receive copies from any such party to do so, with the only requirement being
|
||||
that this copyright notice remain intact.
|
||||
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<notices>
|
||||
<notice>
|
||||
<name>TextDrawable</name>
|
||||
<url>https://github.com/amulyakhare/TextDrawable</url>
|
||||
<copyright>Copyright (C) 2014 Amulya Khare</copyright>
|
||||
<license>MIT License</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>Preferencex</name>
|
||||
<url>https://github.com/takisoft/preferencex-android</url>
|
||||
<copyright />
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>FloatingActionButton</name>
|
||||
<url>https://github.com/futuresimple/android-floating-action-button</url>
|
||||
<copyright>Copyright 2014 Jerzy Chalupski</copyright>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>AppIntro</name>
|
||||
<url>https://github.com/AppIntro/AppIntro</url>
|
||||
<copyright/>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>Krop</name>
|
||||
<url>https://github.com/avito-tech/krop</url>
|
||||
<copyright>Copyright (c) 2017 Avito Technology</copyright>
|
||||
<license>MIT License</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>Spongycastle</name>
|
||||
<url>https://github.com/rtyley/spongycastle/</url>
|
||||
<copyright>Copyright (c) 2000-2017 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)</copyright>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>Swirl</name>
|
||||
<url>https://github.com/mattprecious/swirl</url>
|
||||
<copyright>Copyright 2016 Matthew Precious</copyright>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>CircleImageView</name>
|
||||
<url>https://github.com/hdodenhof/CircleImageView</url>
|
||||
<copyright>Copyright 2014 - 2019 Henning Dodenhof</copyright>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>Barcodescanner</name>
|
||||
<url>https://github.com/dm77/barcodescanner</url>
|
||||
<copyright>Copyright (c) 2014 Dushyanth Maguluru</copyright>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>libsu</name>
|
||||
<url>https://github.com/topjohnwu/libsu</url>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>Glide</name>
|
||||
<url>https://github.com/bumptech/glide</url>
|
||||
<license>Glide License</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>Iconics</name>
|
||||
<url>https://github.com/mikepenz/Android-Iconics</url>
|
||||
<copyright/>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>Android Support Libraries</name>
|
||||
<url>http://developer.android.com/tools/support-library/index.html</url>
|
||||
<copyright>Copyright (C) 2016 The Android Open Source Project</copyright>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
</notices>
|
||||
@@ -0,0 +1,174 @@
|
||||
<resources>
|
||||
<string name="app_name">Aegis</string>
|
||||
<string name="app_name_full">Aegis Authenticator</string>
|
||||
<string name="app_name_dev">AegisDev</string>
|
||||
<string name="action_settings">Einstellungen</string>
|
||||
<string name="action_import">Importieren</string>
|
||||
<string name="action_delete">Löschen</string>
|
||||
<string name="action_default_icon">Standard-Symbol wiederherstellen</string>
|
||||
<string name="discard">Verwerfen</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="issuer">Herausgeber</string>
|
||||
|
||||
<string name="settings">Einstellungen</string>
|
||||
<string name="pref_appearance_group_title">Aussehen</string>
|
||||
<string name="pref_security_group_title">Sicherheit</string>
|
||||
<string name="pref_tools_group_title">Hilfsmittel</string>
|
||||
<string name="pref_select_theme_title">Thema</string>
|
||||
<string name="pref_view_mode_title">Ansichtsmodus</string>
|
||||
<string name="pref_lang_title">Sprache</string>
|
||||
<string name="pref_account_name_title">Anzeigen des Kontonamens</string>
|
||||
<string name="pref_account_name_summary">Aktiviere dies, um den Kontonamen neben dem Herausgeber anzuzeigen.</string>
|
||||
<string name="pref_timeout_title">Zeitüberschreitung</string>
|
||||
<string name="pref_timeout_summary">Sperrt die Datenbank automatisch nach %1$s Sekunden Inaktivität.</string>
|
||||
<string name="pref_slots_title">Schlüssel Steckplätze</string>
|
||||
<string name="pref_slots_summary">Verwalte die Liste der Schlüssel, die die Datenbank entschlüsseln können.</string>
|
||||
<string name="pref_import_file_title">Aus Datei importieren</string>
|
||||
<string name="pref_import_file_summary">Importieren einer Datenbank aus einer Datei</string>
|
||||
<string name="pref_import_app_title">Aus App importieren</string>
|
||||
<string name="pref_import_app_summary">Importieren einer Datenbank aus einer App (erfordert Root-Zugriff)</string>
|
||||
<string name="pref_export_title">Exportieren</string>
|
||||
<string name="pref_export_summary">Exportieren der Datenbank</string>
|
||||
<string name="pref_secure_screen_title">Bildschirmsicherheit</string>
|
||||
<string name="pref_secure_screen_summary">Blockiere Screenshots und andere Versuche, den Bildschirm innerhalb der App aufzunehmen.</string>
|
||||
<string name="pref_tap_to_reveal_title">Zum Aufdecken tippen</string>
|
||||
<string name="pref_tap_to_reveal_summary">Schlüssel werden standardmäßig ausgeblendet. Tippe auf die Schlüssel, um den Code anzuzeigen.</string>
|
||||
<string name="pref_tap_to_reveal_time_title">Zeitüberschreitung für Tippen zum Anzeigen</string>
|
||||
<string name="pref_auto_lock_title">Automatische Sperre</string>
|
||||
<string name="pref_auto_lock_summary">Automatische Sperre, wenn die App geschlossen oder dein Gerät gesperrt wird.</string>
|
||||
<string name="pref_encryption_title">Verschlüsselung</string>
|
||||
<string name="pref_encryption_summary">Verschlüssele die Datenbank und entsperre mit einem Passwort oder Fingerabdruck.</string>
|
||||
<string name="pref_fingerprint_title">Fingerabdruck</string>
|
||||
<string name="pref_fingerprint_summary">Ermöglicht es, dass auf diesem Gerät registrierte Fingerabdrücke den Tresor freischalten.</string>
|
||||
<string name="pref_set_password_title">Passwort ändern</string>
|
||||
<string name="pref_set_password_summary">Legen ein neues Passwort fest, das erforderlich ist, um deinen Tresor freizuschalten.</string>
|
||||
|
||||
<string name="fingerprint_hint">Berührungssensor</string>
|
||||
<string name="fingerprint_not_recognized">Fingerabdruck nicht erkannt. Versuche es noch einmal.</string>
|
||||
<string name="fingerprint_success">Fingerabdruck erkannt</string>
|
||||
|
||||
<string name="choose_authentication_method">Sicherheit</string>
|
||||
<string name="authentication_method_none">Keine</string>
|
||||
<string name="authentication_method_none_description">Du brauchst kein Passwort, um den Tresor freizuschalten, und es wird nicht verschlüsselt. Diese Option wird nicht empfohlen.</string>
|
||||
<string name="authentication_method_password">Passwort</string>
|
||||
<string name="authentication_method_password_description">Du benötigst ein Passwort, um den Tresor freizuschalten.</string>
|
||||
<string name="authentication_method_fingerprint">Fingerabdruck</string>
|
||||
<string name="authentication_method_fingerprint_description">Zusätzlich zu einem Passwort können auf diesem Gerät registrierte Fingerabdrücke verwendet werden, um den Tresor freizuschalten.</string>
|
||||
<string name="authentication_method_set_password">Passwort</string>
|
||||
<string name="authentication_enter_password">Gib dein Passwort ein</string>
|
||||
<string name="authentication">Entsperre den Tresor.</string>
|
||||
<string name="set_password">Bitte gib ein Passwort ein</string>
|
||||
<string name="set_group">Bitte gib einen Gruppennamen ein</string>
|
||||
<string name="set_number">Bitte gib eine Zahl ein</string>
|
||||
<string name="set_password_confirm">Bitte bestätige das Passwort</string>
|
||||
<string name="invalidated_fingerprint">Es wurde eine Änderung der Sicherheitseinstellungen deines Geräts festgestellt. Bitte gehe zu \"Aegis -> Einstellungen -> Fingerabdruck\" und füge deinen Fingerabdruck erneut hinzu.</string>
|
||||
|
||||
<string name="unlock">Entsperren</string>
|
||||
<string name="advanced">Fortgeschritten</string>
|
||||
<string name="seconds">Sekunden</string>
|
||||
<string name="counter">Zähler</string>
|
||||
<string name="digits">Ziffern</string>
|
||||
<string name="secret">Schlüssel</string>
|
||||
<string name="scan">QR-Code scannen</string>
|
||||
<string name="scan_image">Bild scannen</string>
|
||||
<string name="enter_manually">Manuell eingeben</string>
|
||||
<string name="add_fingerprint">Fingerabdruck hinzufügen</string>
|
||||
<string name="add_password">Passwort hinzufügen</string>
|
||||
<string name="slots_warning">Der Tresor ist nur so sicher wie dein schwächster Schlüssel. Wenn ein neuer Fingerabdruck zu deinem Gerät hinzugefügt wird, musst du die Fingerabdruck-Authentifizierung in Aegis reaktivieren.</string>
|
||||
<string name="copy">Kopieren</string>
|
||||
<string name="edit">Bearbeiten</string>
|
||||
<string name="delete">Löschen</string>
|
||||
<string name="password">Passwort</string>
|
||||
<string name="confirm_password">Passwort bestätigen</string>
|
||||
<string name="new_profile">Neues Profil</string>
|
||||
<string name="add_new_profile">Neues Profil hinzufügen</string>
|
||||
<string name="unlock_vault_error">Der Tresor konnte nicht entsperrt werden.</string>
|
||||
<string name="unlock_vault_error_description">Falsches Passwort. Achte darauf, dass du dein Passwort nicht falsch eingibst.</string>
|
||||
<string name="password_equality_error">Passwörter sollten identisch und nicht leer sein.</string>
|
||||
<string name="register_fingerprint">Registriere deinen Fingerabdruck</string>
|
||||
<string name="snackbar_authentication_method">Bitte wähle eine Authentifizierungsmethode aus</string>
|
||||
<string name="encrypting_vault">Verschlüsseln des Tresors</string>
|
||||
<string name="delete_entry">Eintrag löschen</string>
|
||||
<string name="delete_entry_description">Bist du sicher, dass du diesen Eintrag löschen möchtest?</string>
|
||||
<string name="discard_changes">Änderungen verwerfen?</string>
|
||||
<string name="discard_changes_description">Deine Änderungen wurden nicht gespeichert.</string>
|
||||
<string name="folder">Ordner</string>
|
||||
<string name="tap_to_select">Zum Auswählen tippen</string>
|
||||
<string name="saving_profile_error">Fehler beim Speichern des Profils</string>
|
||||
<string name="welcome">Willkommen</string>
|
||||
<string name="app_description">Aegis ist eine kostenlose, sichere und Open Source 2FA App.</string>
|
||||
<string name="setup_completed">Einrichten abgeschlossen</string>
|
||||
<string name="setup_completed_description">Aegis ist eingerichtet und einsatzbereit.</string>
|
||||
<string name="vault_not_found">Tresor nicht gefunden, Starten der Einrichtung…</string>
|
||||
<string name="code_copied">Code in die Zwischenablage kopiert</string>
|
||||
<string name="errors_copied">Fehlermeldungen in die Zwischenablage kopiert</string>
|
||||
<string name="decryption_error">Beim Versuch, den Tresor zu entsperren, ist ein Fehler aufgetreten.</string>
|
||||
<string name="saving_error">Beim Versuch, den Tresor zu speichern, ist ein Fehler aufgetreten.</string>
|
||||
<string name="disable_encryption">Verschlüsselung deaktivieren</string>
|
||||
<string name="disable_encryption_description">Bist du sicher, dass du die Verschlüsselung deaktivieren willst? Dadurch wird der Tresor im Klartext gespeichert.</string>
|
||||
<string name="enable_encryption_error">Bei der Aktivierung der Verschlüsselung ist ein Fehler aufgetreten.</string>
|
||||
<string name="disable_encryption_error">Bei der Deaktivierung der Verschlüsselung ist ein Fehler aufgetreten.</string>
|
||||
<string name="permission_denied">Zugriff verweigert</string>
|
||||
<string name="choose_application">Wähle die Anwendung aus, aus der du eine Datenbank importieren möchtest.</string>
|
||||
<string name="choose_theme">Wähle das gewünschte Thema aus</string>
|
||||
<string name="choose_view_mode">Wähle den gewünschten Ansichtsmodus aus</string>
|
||||
<string name="parsing_file_error">Beim Versuch, die Datei zu analysieren, ist ein Fehler aufgetreten.</string>
|
||||
<string name="file_not_found">Fehler: Datei nicht gefunden</string>
|
||||
<string name="reading_file_error">Beim Versuch, die Datei zu lesen, ist ein Fehler aufgetreten.</string>
|
||||
<string name="app_lookup_error">Fehler: App ist nicht installiert</string>
|
||||
<string name="root_error">Fehler: Es konnte kein Root-Zugriff gewährt werden.</string>
|
||||
<string name="imported_entries_count">Importierte %d Einträge</string>
|
||||
<string name="read_entries_count">%d Einträge gelesen. %d Fehler.</string>
|
||||
<string name="import_error_title">Beim Import sind ein oder mehrere Fehler aufgetreten.</string>
|
||||
<string name="exporting_database_error">Beim Versuch, die Datenbank zu exportieren, ist ein Fehler aufgetreten.</string>
|
||||
<string name="export_database_location">Die Datenbank wurde exportiert nach:</string>
|
||||
<string name="export_warning">Diese Aktion exportiert die Datenbank aus dem privaten Speicher von Aegis.</string>
|
||||
<string name="encryption_set_password_error">Beim Versuch, das Passwort festzulegen, ist ein Fehler aufgetreten: </string>
|
||||
<string name="encryption_enable_fingerprint_error">Beim Versuch den Fingerabdruck zu entsperren, ist ein Fehler aufgetreten: </string>
|
||||
<string name="no_cameras_available">Keine Kameras verfügbar</string>
|
||||
<string name="read_qr_error">Beim Versuch, den QR-Code zu lesen, ist ein Fehler aufgetreten.</string>
|
||||
<string name="authentication_method_raw">Raw</string>
|
||||
<string name="unlocking_vault">Entsperren des Tresors</string>
|
||||
<string name="unlocking_vault_repair">Entsperren des Tresors (Reparieren)</string>
|
||||
<string name="password_slot_error">Du musst mindestens einen Passwort-Slot haben.</string>
|
||||
<string name="remove_slot">Slot entfernen</string>
|
||||
<string name="remove_slot_description">Bist du sicher, dass du diesen Slot entfernen willst?</string>
|
||||
<string name="remove_group">Gruppe entfernen</string>
|
||||
<string name="remove_group_description">Bist du sicher, dass du diese Gruppe entfernen möchtest? Einträge in dieser Gruppe wechseln automatisch zu \'Keine Gruppe\'.</string>
|
||||
<string name="adding_new_slot_error">Beim Versuch, einen neuen Slot hinzuzufügen, ist ein Fehler aufgetreten:</string>
|
||||
<string name="progressbar_error">Die Skala der Animationsdauer kann nicht zurückgesetzt werden. Fortschrittsbalken werden unsichtbar sein.</string>
|
||||
<string name="details">Details</string>
|
||||
<string name="filter">Filter</string>
|
||||
<string name="lock">Sperren</string>
|
||||
<string name="all">Alle</string>
|
||||
<string name="name">Name</string>
|
||||
<string name="no_group">Keine Gruppe</string>
|
||||
<string name="sort_alphabetically">Herausgeber (A bis Z)</string>
|
||||
<string name="sort_alphabetically_reverse">Herausgeber (Z bis A)</string>
|
||||
<string name="sort_alphabetically_name">Konto (A bis Z)</string>
|
||||
<string name="sort_alphabetically_name_reverse">Konto (Z bis A)</string>
|
||||
<string name="sort_custom">Benutzerdefiniert</string>
|
||||
<string name="new_group">Neue Gruppe…</string>
|
||||
<string name="enter_group_name">Gib einen Gruppennamen ein</string>
|
||||
<string name="group_name_hint">Gruppenname</string>
|
||||
<string name="preference_manage_groups">Gruppen bearbeiten</string>
|
||||
<string name="preference_manage_groups_summary">Verwalte und lösche deine Gruppen hier</string>
|
||||
<string name="tap_to_reveal">Versteckt</string>
|
||||
<string name="selected">Ausgewählt</string>
|
||||
<string name="dark_theme_title">Dunkles Thema</string>
|
||||
<string name="light_theme_title">Helles Thema</string>
|
||||
<string name="amoled_theme_title">Amoled Thema</string>
|
||||
<string name="normal_viewmode_title">Normal</string>
|
||||
<string name="compact_mode_title">Kompakt</string>
|
||||
<string name="small_mode_title">Klein</string>
|
||||
<string name="unknown_issuer">Unbekannter Herausgeber</string>
|
||||
<string name="unknown_account_name">Unbekannter Kontoname</string>
|
||||
<string name="import_error_dialog">Aegis konnte %d Tokens nicht importieren. Diese Tokens werden übersprungen. Drücke \'details\', um mehr Informationen über die Fehler zu erhalten.</string>
|
||||
<string name="unable_to_read_qrcode">QR-Code kann nicht gelesen und verarbeitet werden.</string>
|
||||
<string name="select_picture">Bild auswählen</string>
|
||||
<string name="toggle_checkboxes">Markierungen umschalten</string>
|
||||
<string name="search">Suche</string>
|
||||
<string name="channel_name_lock_status">Sperrstatus</string>
|
||||
<string name="channel_description_lock_status">Aegis kann eine dauerhafte Benachrichtigung erstellen, um dich zu benachrichtigen, wenn der Tresor gesperrt ist.</string>
|
||||
<string name="vault_unlocked_state">Der Tresor ist freigeschaltet. Hier tippen, um zu sperren.</string>
|
||||
</resources>
|
||||
@@ -1,168 +1,172 @@
|
||||
<resources>
|
||||
<string name="app_name">Aegis</string>
|
||||
<string name="app_name_dev">AegisDev</string>
|
||||
<string name="action_settings">Настройки</string>
|
||||
<string name="action_import">Импорт</string>
|
||||
<string name="action_delete">Удалить</string>
|
||||
<string name="action_default_icon">Восстановить значок по умолчанию</string>
|
||||
<string name="discard">Отмена</string>
|
||||
<string name="save">Сохранить</string>
|
||||
<string name="issuer">Эмитент</string>
|
||||
<string name="app_name">Aegis</string>
|
||||
<string name="app_name_dev">AegisDev</string>
|
||||
<string name="action_settings">Настройки</string>
|
||||
<string name="action_import">Импорт</string>
|
||||
<string name="action_delete">Удалить</string>
|
||||
<string name="action_default_icon">Восстановить иконку по умолчанию</string>
|
||||
<string name="discard">Отмена</string>
|
||||
<string name="save">Сохранить</string>
|
||||
<string name="issuer">Эмитент</string>
|
||||
|
||||
<string name="settings">Предпочтения</string>
|
||||
<string name="pref_appearance_group_title">Appearance</string>
|
||||
<string name="pref_security_group_title">Security</string>
|
||||
<string name="pref_tools_group_title">Tools</string>
|
||||
<string name="pref_select_theme_title">Тема</string>
|
||||
<string name="pref_view_mode_title">Select view mode</string>
|
||||
<string name="pref_account_name_title">Показать имя аккаунта</string>
|
||||
<string name="pref_account_name_summary">Включите это, чтобы показать имя учетной записи рядом с эмитентом</string>
|
||||
<string name="pref_timeout_title">Тайм-аут</string>
|
||||
<string name="pref_timeout_summary">Автоматическая блокировка базы данных после %1$s секунд бездействия</string>
|
||||
<string name="pref_slots_title">Ключевые слоты</string>
|
||||
<string name="pref_slots_summary">Управление списком ключей которые могут расшифровать базу данных</string>
|
||||
<string name="pref_import_file_title">Импорт из файла</string>
|
||||
<string name="pref_import_file_summary">Импортировать базу данных из файла</string>
|
||||
<string name="pref_import_app_title">Импорт из приложения</string>
|
||||
<string name="pref_import_app_summary">Импорт базы данных из приложения (требуется root-доступ)</string>
|
||||
<string name="pref_export_title">Экспорт</string>
|
||||
<string name="pref_export_summary">Экспорт базы данных</string>
|
||||
<string name="pref_secure_screen_title">Безопасность экрана</string>
|
||||
<string name="pref_secure_screen_summary">Блокировка скриншотов и других попыток захвата экрана в приложении</string>
|
||||
<string name="pref_tap_to_reveal_title">Нажмите, чтобы показать</string>
|
||||
<string name="pref_tap_to_reveal_summary">Токены будут скрыты по умолчанию. Нажмите на токены, чтобы показать код.</string>
|
||||
<string name="pref_tap_to_reveal_time_title">Тайм-аут для показа экрана</string>
|
||||
<string name="pref_auto_lock_title">Автоматически блокировать</string>
|
||||
<string name="pref_auto_lock_summary">Автоматически блокировать, когда приложение закрывается или устройство блокируется</string>
|
||||
<string name="pref_encryption_title">Шифрование</string>
|
||||
<string name="pref_encryption_summary">Зашифруйте базу данных и разблокируйте ее с помощью пароля или отпечатка пальца</string>
|
||||
<string name="pref_fingerprint_title">Отпечаток пальца</string>
|
||||
<string name="pref_fingerprint_summary">Разрешить отпечатки пальцев зарегистрированных на этом устройстве, чтобы разблокировать хранилище</string>
|
||||
<string name="pref_set_password_title">Изменить пароль</string>
|
||||
<string name="pref_set_password_summary">Установите новый пароль который вам понадобится, чтобы разблокировать ваше хранилище</string>
|
||||
<string name="settings">Предпочтения</string>
|
||||
<string name="pref_appearance_group_title">Внешний вид</string>
|
||||
<string name="pref_security_group_title">Безопасность</string>
|
||||
<string name="pref_tools_group_title">Инструменты</string>
|
||||
<string name="pref_select_theme_title">Тема</string>
|
||||
<string name="pref_view_mode_title">Режим отображения</string>
|
||||
<string name="pref_account_name_title">Отображать имя аккаунта</string>
|
||||
<string name="pref_account_name_summary">Включите это, чтобы отображать имя учетной записи рядом с эмитентом</string>
|
||||
<string name="pref_timeout_title">Тайм-аут</string>
|
||||
<string name="pref_timeout_summary">Автоматическая блокировка базы данных после %1$s секунд бездействия</string>
|
||||
<string name="pref_slots_title">Ключевые слоты</string>
|
||||
<string name="pref_slots_summary">Управление списком ключей которые могут расшифровать базу данных</string>
|
||||
<string name="pref_import_file_title">Импорт из файла</string>
|
||||
<string name="pref_import_file_summary">Импортировать базу данных из файла</string>
|
||||
<string name="pref_import_app_title">Импорт из приложения</string>
|
||||
<string name="pref_import_app_summary">Импорт базы данных из другого приложения (требуются права суперпользователя)</string>
|
||||
<string name="pref_export_title">Экспорт в файл</string>
|
||||
<string name="pref_export_summary">Экспортировать базу данных в файл</string>
|
||||
<string name="pref_secure_screen_title">Безопасность экрана</string>
|
||||
<string name="pref_secure_screen_summary">Блокировка скриншотов и других попыток захвата экрана в приложении</string>
|
||||
<string name="pref_tap_to_reveal_title">Отображение по нажатию</string>
|
||||
<string name="pref_tap_to_reveal_summary">Коды будут скрыты по умолчанию. Нажмите на токен, чтобы показать код.</string>
|
||||
<string name="pref_tap_to_reveal_time_title">Тайм-аут для отображения по нажатию</string>
|
||||
<string name="pref_auto_lock_title">Автоматическая блокировка</string>
|
||||
<string name="pref_auto_lock_summary">Автоматическая блокировка при закрытии приложения и блокировке устройства.</string>
|
||||
<string name="pref_encryption_title">Шифрование</string>
|
||||
<string name="pref_encryption_summary">Зашифруйте базу данных и разблокируйте ее с помощью пароля или отпечатка пальца</string>
|
||||
<string name="pref_fingerprint_title">Отпечаток пальца</string>
|
||||
<string name="pref_fingerprint_summary">Разрешить разблокировку хранилища при помощи отпечатков пальцев, зарегистрированных на этом устройстве</string>
|
||||
<string name="pref_set_password_title">Изменить пароль</string>
|
||||
<string name="pref_set_password_summary">Установите новый пароль, который вам понадобится, чтобы разблокировать ваше хранилище</string>
|
||||
|
||||
<string name="fingerprint_hint">Сенсорный датчик</string>
|
||||
<string name="fingerprint_not_recognized">Отпечаток пальца не распознан. Попробуйте снова.</string>
|
||||
<string name="fingerprint_success">Отпечаток пальца распознан</string>
|
||||
<string name="fingerprint_hint">Прикоснитесь к сенсору</string>
|
||||
<string name="fingerprint_not_recognized">Отпечаток пальца не распознан. Попробуйте снова.</string>
|
||||
<string name="fingerprint_success">Отпечаток пальца распознан</string>
|
||||
|
||||
<string name="choose_authentication_method">Безопасность</string>
|
||||
<string name="authentication_method_none">Нет</string>
|
||||
<string name="authentication_method_none_description">Вам не нужен пароль для разблокировки хранилища, и он не будет зашифрован. Этот вариант не рекомендуется.</string>
|
||||
<string name="authentication_method_password">Пароль</string>
|
||||
<string name="authentication_method_password_description">Вам нужен пароль чтобы разблокировать хранилище.</string>
|
||||
<string name="authentication_method_fingerprint">Отпечаток</string>
|
||||
<string name="authentication_method_fingerprint_description">В дополнение к паролю для разблокировки хранилища можно использовать отпечатки пальцев, зарегистрированные на этом устройстве.</string>
|
||||
<string name="authentication_method_set_password">Пароль</string>
|
||||
<string name="authentication_enter_password">Введите свой пароль</string>
|
||||
<string name="authentication">Разблокировать хранилище</string>
|
||||
<string name="set_password">Пожалуйста, введите пароль</string>
|
||||
<string name="set_group">Пожалуйста, введите название группы</string>
|
||||
<string name="set_number">Пожалуйста, введите номер</string>
|
||||
<string name="set_password_confirm">Пожалуйста, подтвердите пароль</string>
|
||||
<string name="invalidated_fingerprint">Обнаружено изменение настроек безопасности вашего устройства. Перейдите в «Настройки - Отпечаток пальца» и повторно добавьте свой отпечаток пальца.</string>
|
||||
<string name="choose_authentication_method">Безопасность</string>
|
||||
<string name="authentication_method_none">Нет</string>
|
||||
<string name="authentication_method_none_description">Вам не нужен пароль для разблокировки хранилища, и оно не будет зашифровано. Этот вариант не рекомендуется.</string>
|
||||
<string name="authentication_method_password">Пароль</string>
|
||||
<string name="authentication_method_password_description">Вам нужен пароль, чтобы разблокировать хранилище.</string>
|
||||
<string name="authentication_method_fingerprint">Отпечаток пальца</string>
|
||||
<string name="authentication_method_fingerprint_description">В дополнение к паролю, для разблокировки хранилища можно использовать отпечатки пальцев, зарегистрированные на этом устройстве.</string>
|
||||
<string name="authentication_method_set_password">Пароль</string>
|
||||
<string name="authentication_enter_password">Введите свой пароль</string>
|
||||
<string name="authentication">Разблокировать хранилище</string>
|
||||
<string name="set_password">Пожалуйста, введите пароль</string>
|
||||
<string name="set_group">Пожалуйста, введите название группы</string>
|
||||
<string name="set_number">Пожалуйста, введите номер</string>
|
||||
<string name="set_password_confirm">Пожалуйста, подтвердите пароль</string>
|
||||
<string name="invalidated_fingerprint">Обнаружено изменение настроек безопасности вашего устройства. Перейдите в «Настройки - Отпечаток пальца» и повторно добавьте свой отпечаток пальца.</string>
|
||||
|
||||
<string name="unlock">Разблокировать</string>
|
||||
<string name="advanced">Расширенные</string>
|
||||
<string name="seconds">секунд</string>
|
||||
<string name="counter">Счетчик</string>
|
||||
<string name="digits">Цифры</string>
|
||||
<string name="secret">Секрет</string>
|
||||
<string name="scan">Сканировать QR-код</string>
|
||||
<string name="scan_image">Сканировать изображение</string>
|
||||
<string name="enter_manually">Введите вручную</string>
|
||||
<string name="add_fingerprint">Добавить отпечаток</string>
|
||||
<string name="add_password">Добавить паспорт</string>
|
||||
<string name="slots_warning">Хранилище надежно защищено. При добавлении нового отпечатка пальца на ваше устройство вы активируете аутентификацию по отпечатку пальца в Aegis.</string>
|
||||
<string name="copy">Копировать</string>
|
||||
<string name="edit">Изменить</string>
|
||||
<string name="delete">Удалить</string>
|
||||
<string name="password">Пароль</string>
|
||||
<string name="confirm_password">Подтвердите пароль</string>
|
||||
<string name="new_profile">Новый профиль</string>
|
||||
<string name="add_new_profile">Добавить новый профиль</string>
|
||||
<string name="unlock_vault_error">Не удалось разблокировать хранилище</string>
|
||||
<string name="unlock_vault_error_description">Неверный пароль. Убедитесь, что вы не опечатали свой пароль.</string>
|
||||
<string name="password_equality_error">Пароли должны быть одинаковыми и непустыми</string>
|
||||
<string name="register_fingerprint">Зарегистрируйте свой отпечаток пальца</string>
|
||||
<string name="snackbar_authentication_method">Пожалуйста, выберите метод аутентификации</string>
|
||||
<string name="encrypting_vault">Шифрование хранилища</string>
|
||||
<string name="delete_entry">Удалить запись</string>
|
||||
<string name="delete_entry_description">Вы уверены что хотите удалить эту запись?</string>
|
||||
<string name="discard_changes">Отменить изменения?</string>
|
||||
<string name="discard_changes_description">Ваши изменения не были сохранены</string>
|
||||
<string name="folder">Папка</string>
|
||||
<string name="tap_to_select">Нажмите, чтобы выбрать</string>
|
||||
<string name="saving_profile_error">Ошибка сохранения профиля</string>
|
||||
<string name="welcome">Добро пожаловать</string>
|
||||
<string name="app_description">Aegis - бесплатное, безопасное и открытое приложение 2FA.</string>
|
||||
<string name="setup_completed">Настройка завершена</string>
|
||||
<string name="setup_completed_description">Aegis настроен и готов к работе.</string>
|
||||
<string name="vault_not_found">Хранилище не найдено, запуск установки…</string>
|
||||
<string name="code_copied">Код скопирован в буфер обмена</string>
|
||||
<string name="errors_copied">Ошибка скопирована в буфер обмена</string>
|
||||
<string name="decryption_error">Произошла ошибка при попытке разблокировать хранилище</string>
|
||||
<string name="saving_error">Произошла ошибка при попытке сохранить хранилище</string>
|
||||
<string name="disable_encryption">Отключить шифрование</string>
|
||||
<string name="disable_encryption_description">Вы уверены что хотите отключить шифрование? Это приведет к хранению хранилища в виде простого текста.</string>
|
||||
<string name="enable_encryption_error">Произошла ошибка при включении шифрования</string>
|
||||
<string name="disable_encryption_error">Произошла ошибка при отключении шифрования</string>
|
||||
<string name="permission_denied">Доступ запрещен</string>
|
||||
<string name="choose_application">Выберите приложение из которого вы хотите импортировать базу данных.</string>
|
||||
<string name="choose_theme">Выберите тему</string>
|
||||
<string name="choose_view_mode">Выберите нужный режим просмотра</string>
|
||||
<string name="parsing_file_error">Произошла ошибка при попытке разобрать файл</string>
|
||||
<string name="file_not_found">Ошибка: файл не найден</string>
|
||||
<string name="reading_file_error">Произошла ошибка при попытке прочитать файл</string>
|
||||
<string name="app_lookup_error">Ошибка: приложение не установлено</string>
|
||||
<string name="root_error">Ошибка: невозможно получить root-доступ</string>
|
||||
<string name="imported_entries_count">Импортироаано %d записей</string>
|
||||
<string name="read_entries_count">Прочитано %d записей. %d ошибок.</string>
|
||||
<string name="import_error_title">Одна или более ошибок произошли при импорте</string>
|
||||
<string name="exporting_database_error">Произошла ошибка при попытке экспорта базы данных</string>
|
||||
<string name="export_database_location">База данных была экспортирована в:</string>
|
||||
<string name="export_warning">Это действие экспортирует базу данных из личного хранилища Aegis.</string>
|
||||
<string name="encryption_set_password_error">Произошла ошибка при попытке установить пароль:</string>
|
||||
<string name="encryption_enable_fingerprint_error">Произошла ошибка при попытке разблокировать отпечаток пальца:</string>
|
||||
<string name="no_cameras_available">Нет доступных камер</string>
|
||||
<string name="read_qr_error">Произошла ошибка при попытке прочитать QR-код</string>
|
||||
<string name="authentication_method_raw">Необработанный</string>
|
||||
<string name="unlocking_vault">Разблокировка хранилища</string>
|
||||
<string name="password_slot_error">У вас должен быть хотя бы один слот для пароля</string>
|
||||
<string name="remove_slot">Удалить слот</string>
|
||||
<string name="remove_slot_description">Вы уверены что хотите удалить этот слот?</string>
|
||||
<string name="remove_group">Удалить группу</string>
|
||||
<string name="remove_group_description">Вы уверены что хотите удалить эту группу? Записи в этой группе автоматически переключатся на «Нет группы».</string>
|
||||
<string name="adding_new_slot_error">Произошла ошибка при попытке добавить новый слот:</string>
|
||||
<string name="progressbar_error">Невозможно сбросить шкалу длительности аниматора. Индикаторы прогресса будут невидимы.</string>
|
||||
<string name="details">Подробнее</string>
|
||||
<string name="filter">Фильтр</string>
|
||||
<string name="lock">Заблокировать</string>
|
||||
<string name="all">Все</string>
|
||||
<string name="name">Имя</string>
|
||||
<string name="no_group">Нет группы</string>
|
||||
<string name="sort_alphabetically">Эмитенты (по алфавиту)</string>
|
||||
<string name="sort_alphabetically_reverse">Эмитенты (обратный порядок алфавита)</string>
|
||||
<string name="sort_alphabetically_name">Аккаунт (по алфавиту)</string>
|
||||
<string name="sort_alphabetically_name_reverse">Аккаунт (алфавит в обратном порядке)</string>
|
||||
<string name="sort_custom">По другому</string>
|
||||
<string name="new_group">Новая группа...</string>
|
||||
<string name="enter_group_name">Введите название группы</string>
|
||||
<string name="group_name_hint">Название группы</string>
|
||||
<string name="preference_manage_groups">Редактировать группы</string>
|
||||
<string name="preference_manage_groups_summary">Управляйте и удаляйте свои группы здесь</string>
|
||||
<string name="tap_to_reveal">Скрытый</string>
|
||||
<string name="selected">Выбрано</string>
|
||||
<string name="dark_theme_title">Темная тема</string>
|
||||
<string name="light_theme_title">Светлая тема</string>
|
||||
<string name="amoled_theme_title">Черная тема</string>
|
||||
<string name="normal_viewmode_title">Обычный</string>
|
||||
<string name="compact_mode_title">Компактный</string>
|
||||
<string name="small_mode_title">Маленький</string>
|
||||
<string name="unknown_issuer">Неизвестный эмитент</string>
|
||||
<string name="unknown_account_name">Неизвестное имя аккаунта</string>
|
||||
<string name="import_error_dialog">Aegis не может имитировать %d токены. Эти токены пропущены. Нажмите \'подробнее\' чтобы увидеть информацию об ошибках</string>
|
||||
<string name="unable_to_read_qrcode">Не удается прочитать и обработать QR-код</string>
|
||||
<string name="select_picture">Выбрать картинку</string>
|
||||
<string name="toggle_checkboxes">Переключить выбор</string>
|
||||
<string name="search">Поиск</string>
|
||||
<string name="unlock">Разблокировать</string>
|
||||
<string name="advanced">Расширенные</string>
|
||||
<string name="seconds">секунд</string>
|
||||
<string name="counter">Счетчик</string>
|
||||
<string name="digits">Цифры</string>
|
||||
<string name="secret">Секрет</string>
|
||||
<string name="scan">Сканировать QR-код</string>
|
||||
<string name="scan_image">Сканировать изображение</string>
|
||||
<string name="enter_manually">Ввести вручную</string>
|
||||
<string name="add_fingerprint">Добавить отпечаток</string>
|
||||
<string name="add_password">Добавить пароль</string>
|
||||
<string name="slots_warning">Хранилище надежно защищено. При добавлении нового отпечатка пальца на ваше устройство необходимо будет заново настроить разблокировку хранилища по отпечатку пальца в Aegis.</string>
|
||||
<string name="copy">Копировать</string>
|
||||
<string name="edit">Изменить</string>
|
||||
<string name="delete">Удалить</string>
|
||||
<string name="password">Пароль</string>
|
||||
<string name="confirm_password">Подтвердите пароль</string>
|
||||
<string name="new_profile">Новый профиль</string>
|
||||
<string name="add_new_profile">Добавить новый профиль</string>
|
||||
<string name="unlock_vault_error">Не удалось разблокировать хранилище</string>
|
||||
<string name="unlock_vault_error_description">Некорректный пароль. Убедитесь, что вы не допустили опечатку в вашем пароле.</string>
|
||||
<string name="password_equality_error">Пароли должны быть одинаковыми и непустыми</string>
|
||||
<string name="register_fingerprint">Зарегистрируйте свой отпечаток пальца</string>
|
||||
<string name="snackbar_authentication_method">Пожалуйста, выберите метод аутентификации</string>
|
||||
<string name="encrypting_vault">Шифрование хранилища</string>
|
||||
<string name="delete_entry">Удалить запись</string>
|
||||
<string name="delete_entry_description">Вы уверены что хотите удалить эту запись?</string>
|
||||
<string name="discard_changes">Отменить изменения?</string>
|
||||
<string name="discard_changes_description">Ваши изменения не были сохранены</string>
|
||||
<string name="folder">Папка</string>
|
||||
<string name="tap_to_select">Нажмите, чтобы выбрать</string>
|
||||
<string name="saving_profile_error">Ошибка сохранения профиля</string>
|
||||
<string name="welcome">Добро пожаловать</string>
|
||||
<string name="app_description">Aegis - бесплатное, безопасное и открытое приложение 2FA.</string>
|
||||
<string name="setup_completed">Настройка завершена</string>
|
||||
<string name="setup_completed_description">Aegis настроен и готов к работе.</string>
|
||||
<string name="vault_not_found">Хранилище не найдено, запуск первоначальной настройки…</string>
|
||||
<string name="code_copied">Код скопирован в буфер обмена</string>
|
||||
<string name="errors_copied">Ошибки скопированы в буфер обмена</string>
|
||||
<string name="decryption_error">Произошла ошибка при попытке разблокировать хранилище</string>
|
||||
<string name="saving_error">Произошла ошибка при попытке сохранить хранилище</string>
|
||||
<string name="disable_encryption">Отключить шифрование</string>
|
||||
<string name="disable_encryption_description">Вы уверены что хотите отключить шифрование? Это приведет к хранению хранилища в виде открытого текста.</string>
|
||||
<string name="enable_encryption_error">Произошла ошибка при включении шифрования</string>
|
||||
<string name="disable_encryption_error">Произошла ошибка при отключении шифрования</string>
|
||||
<string name="permission_denied">Доступ запрещен</string>
|
||||
<string name="choose_application">Выберите приложение из которого вы хотите импортировать базу данных</string>
|
||||
<string name="choose_theme">Выберите тему</string>
|
||||
<string name="choose_view_mode">Выберите режим отображения</string>
|
||||
<string name="parsing_file_error">Произошла ошибка при попытке разобрать файл</string>
|
||||
<string name="file_not_found">Ошибка: файл не найден</string>
|
||||
<string name="reading_file_error">Произошла ошибка при попытке прочитать файл</string>
|
||||
<string name="app_lookup_error">Ошибка: приложение не установлено</string>
|
||||
<string name="root_error">Ошибка: невозможно получить права суперпользователя</string>
|
||||
<string name="imported_entries_count">Импортировано %d записей</string>
|
||||
<string name="read_entries_count">Прочитано %d записей. %d ошибок.</string>
|
||||
<string name="import_error_title">При импорте произошла одна или несколько ошибок</string>
|
||||
<string name="exporting_database_error">Произошла ошибка при попытке экспорта базы данных</string>
|
||||
<string name="export_database_location">База данных была экспортирована в:</string>
|
||||
<string name="export_warning">Это действие экспортирует базу данных из приватного хранилища Aegis.</string>
|
||||
<string name="encryption_set_password_error">Произошла ошибка при попытке установить пароль:</string>
|
||||
<string name="encryption_enable_fingerprint_error">Произошла ошибка при попытке разблокировать отпечаток пальца:</string>
|
||||
<string name="no_cameras_available">Нет доступных камер</string>
|
||||
<string name="read_qr_error">Произошла ошибка при попытке прочитать QR-код</string>
|
||||
<string name="authentication_method_raw">Необработанный</string>
|
||||
<string name="unlocking_vault">Разблокировка хранилища</string>
|
||||
<string name="unlocking_vault_repair">Разблокировка хранилища (восстановление)</string>
|
||||
<string name="password_slot_error">У вас должен быть хотя бы один слот для пароля</string>
|
||||
<string name="remove_slot">Удалить слот</string>
|
||||
<string name="remove_slot_description">Вы уверены что хотите удалить этот слот?</string>
|
||||
<string name="remove_group">Удалить группу</string>
|
||||
<string name="remove_group_description">Вы уверены что хотите удалить эту группу? Записи в этой группе будут автоматически перемещены в «Нет группы».</string>
|
||||
<string name="adding_new_slot_error">Произошла ошибка при попытке добавить новый слот:</string>
|
||||
<string name="progressbar_error">Не удалось установить продолжительность анимации. Индикаторы прогресса не будут отображаться.</string>
|
||||
<string name="details">Подробнее</string>
|
||||
<string name="filter">Фильтр</string>
|
||||
<string name="lock">Заблокировать</string>
|
||||
<string name="all">Все</string>
|
||||
<string name="name">Имя</string>
|
||||
<string name="sort_alphabetically">Эмитент (в алфавитном порядке)</string>
|
||||
<string name="sort_alphabetically_reverse">Эмитент (в обратном порядке)</string>
|
||||
<string name="sort_alphabetically_name">Учетная запись (в алфавитном порядке)</string>
|
||||
<string name="sort_alphabetically_name_reverse">Учетная запись (в обратном порядке)</string>
|
||||
<string name="sort_custom">Произвольно</string>
|
||||
<string name="no_group">Нет группы</string>
|
||||
<string name="new_group">Новая группа…</string>
|
||||
<string name="enter_group_name">Введите название группы</string>
|
||||
<string name="group_name_hint">Название группы</string>
|
||||
<string name="preference_manage_groups">Редактировать группы</string>
|
||||
<string name="preference_manage_groups_summary">Редактирование и удаление ваших групп</string>
|
||||
<string name="tap_to_reveal">Скрытый</string>
|
||||
<string name="selected">Выбрано</string>
|
||||
<string name="dark_theme_title">Темная тема</string>
|
||||
<string name="light_theme_title">Светлая тема</string>
|
||||
<string name="amoled_theme_title">AMOLED-тема</string>
|
||||
<string name="normal_viewmode_title">Обычный</string>
|
||||
<string name="compact_mode_title">Компактный</string>
|
||||
<string name="small_mode_title">Уменьшенный</string>
|
||||
<string name="unknown_issuer">Неизвестный эмитент</string>
|
||||
<string name="unknown_account_name">Неизвестное название учетной записи</string>
|
||||
<string name="import_error_dialog">Aegis не удалось импортировать %d pfgbctq. Эти записи будут проигнорированы. Нажмите \'подробнее\' чтобы получить больше информации о возникших ошибках.</string>
|
||||
<string name="unable_to_read_qrcode">Не удалось прочитать и обработать QR-код</string>
|
||||
<string name="select_picture">Выберите изображение</string>
|
||||
<string name="toggle_checkboxes">Установите переключатели</string>
|
||||
<string name="search">Поиск</string>
|
||||
<string name="channel_name_lock_status">Статус блокировки</string>
|
||||
<string name="channel_description_lock_status">Aegis может создать постоянное уведомление для отображения статуса блокировки хранилища</string>
|
||||
<string name="vault_unlocked_state">Хранилище разблокировано. Нажмите для блокировки.</string>
|
||||
</resources>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<item>Dutch</item>
|
||||
<item>English</item>
|
||||
<item>French</item>
|
||||
<item>German</item>
|
||||
<item>Russian</item>
|
||||
</string-array>
|
||||
|
||||
@@ -43,6 +44,7 @@
|
||||
<item>nl</item>
|
||||
<item>en</item>
|
||||
<item>fr</item>
|
||||
<item>de</item>
|
||||
<item>ru</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<color name="colorAccentPressed">#FF5252</color>
|
||||
<color name="primary_text">#212121</color>
|
||||
<color name="secondary_text">#757575</color>
|
||||
<color name="icon_about">#757575</color>
|
||||
<color name="extra_info_text">#8e8e8e</color>
|
||||
<color name="primary_text_inverted">#ffffff</color>
|
||||
<color name="secondary_text_inverted">#efefef</color>b
|
||||
@@ -31,7 +32,7 @@
|
||||
<color name="code_primary_text">#0d47a1</color>
|
||||
<color name="code_primary_text_dark">#ffffff</color>
|
||||
|
||||
<color name="card_background_dark">#424242</color>
|
||||
<color name="card_background_dark">#363636</color>
|
||||
<color name="card_background_focused_dark">#6B6B6B</color>
|
||||
<color name="card_background_focused_true_dark">#1B1B1B</color>
|
||||
<color name="primary_text_dark">#ffffff</color>
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
<dimen name="list_item_height">48dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<string name="app_name">Aegis</string>
|
||||
<string name="app_name_full">Aegis Authenticator</string>
|
||||
<string name="app_name_dev">AegisDev</string>
|
||||
<string name="org_name_full">Beem Development</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="action_about">About</string>
|
||||
<string name="action_import">Import</string>
|
||||
<string name="action_delete">Delete</string>
|
||||
<string name="action_default_icon">Restore default icon</string>
|
||||
@@ -171,4 +173,38 @@
|
||||
<string name="channel_name_lock_status">Lock status</string>
|
||||
<string name="channel_description_lock_status">Aegis can create a persistent notification to notify you when the vault is locked</string>
|
||||
<string name="vault_unlocked_state">Vault is unlocked. Tap here to lock.</string>
|
||||
<string name="title_activity_about">About</string>
|
||||
<string name="version">Version</string>
|
||||
<string name="changelog">Changelog</string>
|
||||
<string name="whats_new">What\'s new</string>
|
||||
<string name="github">GitHub</string>
|
||||
<string name="github_description">Source code, issues and information</string>
|
||||
<string name="licenses">Licenses</string>
|
||||
<string name="licenses_description">Licenses of the libraries Aegis uses</string>
|
||||
<string name="author_alex">Alexander Bakker</string>
|
||||
<string name="country_netherlands">Netherlands</string>
|
||||
<string name="author_michael">Michael Schättgen</string>
|
||||
<string name="email_us">Write an email</string>
|
||||
<string name="visit_website">Visit our website</string>
|
||||
<string name="about_support">Support</string>
|
||||
<string name="support_rate">Rate</string>
|
||||
<string name="support_rate_description">Support us by leaving a review in the Google Play Store</string>
|
||||
<string name="webview_error">This device doesn\'t support web view, which is necessary to view the change log. It is missing a system component.</string>
|
||||
<string name="email">Email</string>
|
||||
|
||||
<string name="custom_notices_format_style" translatable="false" >
|
||||
body {
|
||||
background-color: #%1$s;
|
||||
color: #%2$s;
|
||||
font-family: sans-serif;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
pre {
|
||||
background-color: #%3$s;
|
||||
padding: 1em;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</string>
|
||||
<string name="empty_list">There are no codes to be shown. Start adding entries by tapping the plus sign in the bottom right corner</string>
|
||||
<string name="empty_list_title">No entries found</string>
|
||||
</resources>
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
|
||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<item name="primaryText">@color/primary_text</item>
|
||||
@@ -39,34 +40,43 @@
|
||||
|
||||
<item name="actionModeStyle">@style/ActionModeStyle</item>
|
||||
<item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
|
||||
<item name="alertDialogTheme">@style/DialogStyle</item>
|
||||
</style>
|
||||
|
||||
<style name="ActionModeStyle" parent="@style/Widget.AppCompat.Light.ActionMode.Inverse">
|
||||
<item name="background">@color/colorPrimary</item>
|
||||
<item name="titleTextStyle">@style/ActionModeTitleTextStyle</item>
|
||||
<item name="iconColorPrimary">@color/icon_primary</item>
|
||||
<item name="iconColorInverted">@color/icon_primary_inverted</item>
|
||||
</style>
|
||||
|
||||
<style name="ActionModeStyle.Dark" parent="@style/Widget.AppCompat.Light.ActionMode.Inverse">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="background">@color/colorPrimary</item>
|
||||
<item name="titleTextStyle">@style/ActionModeTitleTextStyle</item>
|
||||
<item name="iconColorPrimary">@color/icon_primary</item>
|
||||
<item name="iconColorInverted">@color/icon_primary_inverted</item>
|
||||
<item name="alertDialogStyle">@style/DialogStyle.Dark</item>
|
||||
</style>
|
||||
|
||||
<style name="ActionModeStyle.TrueBlack" parent="@style/Widget.AppCompat.Light.ActionMode.Inverse">
|
||||
<item name="colorPrimary">@color/background_true_dark</item>
|
||||
<item name="background">@color/background_true_dark</item>
|
||||
<item name="titleTextStyle">@style/ActionModeTitleTextStyle</item>
|
||||
<item name="iconColorPrimary">@color/icon_primary</item>
|
||||
<item name="iconColorInverted">@color/icon_primary_inverted</item>
|
||||
<item name="alertDialogStyle">@style/DialogStyle.TrueDark</item>
|
||||
</style>
|
||||
|
||||
<style name="ActionModeTitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionMode.Title">
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.TransparentActionBar">
|
||||
<item name="android:actionBarStyle">@style/ThemeActionBar</item>
|
||||
<item name="android:windowActionBarOverlay">true</item>
|
||||
@@ -74,6 +84,7 @@
|
||||
<item name="actionBarStyle">@style/ThemeActionBar</item>
|
||||
<item name="windowActionBarOverlay">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.Fullscreen" parent="AppTheme.TransparentActionBar">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
@@ -97,6 +108,8 @@
|
||||
<item name="swirl_errorColor">@color/colorSwirlErrorDark</item>
|
||||
|
||||
<item name="actionModeStyle">@style/ActionModeStyle.Dark</item>
|
||||
<item name="alertDialogTheme">@style/DialogStyle.Dark</item>
|
||||
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.TrueBlack" parent="AppTheme.Dark">
|
||||
@@ -107,6 +120,8 @@
|
||||
<item name="colorPrimaryDark">@color/background_true_dark</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
<item name="actionModeStyle">@style/ActionModeStyle.TrueBlack</item>
|
||||
<item name="alertDialogTheme">@style/DialogStyle.TrueDark</item>
|
||||
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.TrueBlack.Preferences" parent="AppTheme.TrueBlack">
|
||||
@@ -117,6 +132,7 @@
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.Dark.TransparentActionBar">
|
||||
<item name="android:actionBarStyle">@style/ThemeActionBar</item>
|
||||
<item name="android:windowActionBarOverlay">true</item>
|
||||
@@ -130,4 +146,34 @@
|
||||
<item name="android:textColor">#FFFFFF</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="DialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
|
||||
<item name="android:background">@color/card_background</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="textColorAlertDialogListItem">@color/primary_text</item>
|
||||
</style>
|
||||
|
||||
<style name="DialogStyle.Dark" parent="Theme.AppCompat.Dialog">
|
||||
<item name="android:background">@color/card_background_dark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="textColorAlertDialogListItem">@color/primary_text_dark</item>
|
||||
|
||||
<!--The following lines are needed because the non-light version of this parent changes the
|
||||
min width to 80% or something. Looks weird.-->
|
||||
<item name="android:windowMinWidthMajor">97%</item>
|
||||
<item name="android:windowMinWidthMinor">97%</item>
|
||||
</style>
|
||||
|
||||
<style name="DialogStyle.TrueDark" parent="DialogStyle.Dark">
|
||||
<item name="android:background">@color/card_background_focused_true_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<style name="AppTheme.NoActionBar.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
</resources>
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Mon Jun 10 14:39:47 CEST 2019
|
||||
#Sun Sep 01 21:12:20 CEST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
|
||||
Reference in New Issue
Block a user