Merge branch 'master' into reauthenticate_after_inactivity

This commit is contained in:
Jakob Nixdorf 2020-02-03 07:07:59 +01:00 committed by GitHub
commit 5795d07f9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
165 changed files with 4473 additions and 2790 deletions

24
.gitignore vendored
View file

@ -1,11 +1,17 @@
*.iml # Local config files
.gradle
crowdin.properties crowdin.properties
/local.properties local.properties
/.idea/workspace.xml
/.idea/libraries # IntelliJ
/.idea/markdown-navigator* *.iml
/.idea/caches .idea
# Gradle
.gradle
build
# Android Studio
captures
# OS files
.DS_Store .DS_Store
/build
/captures

View file

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="height" value="128" />
<entry key="outputName" value="thumb_instagram" />
<entry key="overrideSize" value="true" />
<entry key="sourceFile" value="$PROJECT_DIR$/../../../downloads/instagram.svg" />
<entry key="width" value="128" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

View file

@ -1,29 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>

View file

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/andOTP.iml" filepath="$PROJECT_DIR$/andOTP.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
</project>

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View file

@ -1,5 +1,29 @@
# Changelog # Changelog
#### v0.6.4 (WIP)
* New feature: Generate a new HOTP token when revealing (Issue #334, PR #366 by @moritzgloeckl)
* New feature: Split issuer and label (Issue #258, PR #372 by @lucavallerini)
* New feature: Automatic thumbnail selection based on the issuer (Issue #388, PR #389 by @schwedenmut)
* New feature: Allow searching the tags and issuers in addition to the label (Issue #327)
* New feature: Turn tokens red if they are about to expire (Issue #311, PR #410 by @Ullas-Aithal)
* New feature: Handle otpauth:// intents from other apps (Issue #324, PR #393 by @schwedenmut)
* New feature: Create an encrypted backup every time the entries are changed (PR #397 by @RichyHBM)
* New feature: Different layouts for the entry cards
* New feature: New thumbnail size "Tiny"
* Improvement: Hide the token list on screen off (Issue #264, PR #391 by @LizardWithHat)
* Improvement: Scale the font of the default thumbnail with its size
* Bug fix: Fix black navigation bar on OxygenOS devices (PR #417 by @Ullas-Aithal)
* Internal: Migrate to AndroidX
* Internal: Update Gradle and a lot of dependencies
* Thumbnails: Lots of new ones (thanks to all contributors)
#### v0.6.3.1
* Introduce build flavors:
- fdroid: Shows donation links in the About section
- play: Doesn't show donation links in the About section
#### v0.6.3 #### v0.6.3
* Security: Improved password derivation for the password protected backups * Security: Improved password derivation for the password protected backups
@ -11,8 +35,10 @@
* Bug fix: Always use arabic numerals for the tokens (Issue #359) * Bug fix: Always use arabic numerals for the tokens (Issue #359)
* Bug fix: Refactor storage access code to allow importing and exporting from cloud storage directly * Bug fix: Refactor storage access code to allow importing and exporting from cloud storage directly
* Bug fix: Hardcode the black background color to avoid strange behaviour on some custom ROMs * Bug fix: Hardcode the black background color to avoid strange behaviour on some custom ROMs
* Bug fix: Force English locales for saving AuthMethod
* Misc: Update donation links (PR #351) * Misc: Update donation links (PR #351)
* Thumbnails: Lots of new thumbnails * Thumbnails: Lots of new thumbnails
* Translations: Hungarian
#### v0.6.2 #### v0.6.2

View file

@ -1,7 +1,7 @@
# andOTP - Android OTP Authenticator # andOTP - Android OTP Authenticator
[![Build Status](https://travis-ci.org/andOTP/andOTP.svg?branch=master)](https://travis-ci.org/andOTP/andOTP) [![Build Status](https://travis-ci.org/andOTP/andOTP.svg?branch=master)](https://travis-ci.org/andOTP/andOTP)
[![Current release](https://img.shields.io/github/release/andOTP/andOTP/all.svg)](https://github.com/andOTP/andOTP/releases/download/v0.6.3-beta1/andOTP_v0.6.3-beta1.apk) [![Current release](https://img.shields.io/github/release/andOTP/andOTP/all.svg)](https://github.com/andOTP/andOTP/releases/download/v0.6.3.1/andOTP_v0.6.3.1.apk)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/andotp/localized.svg)](https://crowdin.com/project/andotp) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/andotp/localized.svg)](https://crowdin.com/project/andotp)
[![Chat - Telegram](https://img.shields.io/badge/chat-Telegram-blue.svg)](https://t.me/andOTP) [![Chat - Telegram](https://img.shields.io/badge/chat-Telegram-blue.svg)](https://t.me/andOTP)
[![Chat - Matrix](https://img.shields.io/badge/chat-Matrix-blue.svg)](https://matrix.to/#/#andOTP:privacytools.io) [![Chat - Matrix](https://img.shields.io/badge/chat-Matrix-blue.svg)](https://matrix.to/#/#andOTP:privacytools.io)
@ -61,9 +61,9 @@ key, which renders them useless.
### Opening the backups on your PC: ### Opening the backups on your PC:
* [OpenPGP](http://openpgp.org/): OpenPGP can be used to easily decrypt the **OpenPGP-encrypted backups** on your PC. * [OpenPGP](https://openpgp.org/): OpenPGP can be used to easily decrypt the **OpenPGP-encrypted backups** on your PC.
* [WebDecrypt](https://flocke.shadowice.org/andOTP/decrypt/): JavaScript-based decryption of the **new password-protected backup format** in the browser ([source code](https://github.com/andOTP/WebDecrypt)). * [WebDecrypt](https://flocke.shadowice.org/andOTP/decrypt/): JavaScript-based decryption of the **new password-protected backup format** in the browser ([source code](https://github.com/andOTP/WebDecrypt)).
* [andOTP-decrypt](https://github.com/asmw/andOTP-decrypt): Python script written by @asmw to decrypt the **old password-protected backup format** on your PC. * [andOTP-decrypt](https://github.com/asmw/andOTP-decrypt): Python script written by @asmw to decrypt the **old and new password-protected backup format** on your PC.
### Automatic backups: ### Automatic backups:
@ -89,16 +89,18 @@ So make sure you have a **current backup** before switching!
* **Translation**: If you want to help translate andOTP into your language head over to the [Crowdin project](https://crowdin.com/project/andotp). * **Translation**: If you want to help translate andOTP into your language head over to the [Crowdin project](https://crowdin.com/project/andotp).
* **Bug reports and feature requests**: You can report bugs and request features in the [Issue tracker](https://github.com/andOTP/andOTP/issues) on GitHub. * **Bug reports and feature requests**: You can report bugs and request features in the [Issue tracker](https://github.com/andOTP/andOTP/issues) on GitHub.
* **Requesting thumbnails**: If you are missing a thumbnail you can request it by editing the [wiki](https://github.com/andOTP/andOTP/wiki/Thumbnails#thumbnail-requests) * **Requesting thumbnails**: If you are missing a thumbnail you can request it by [opening an issue](https://github.com/andOTP/andOTP/issues/new).
* **Discussion and support**: * **Discussion and support**:
- [XDA thread](https://forum.xda-developers.com/android/apps-games/app-andotp-android-otp-authenticator-t3636993) (please keep off-topic to a minimum) - [XDA thread](https://forum.xda-developers.com/android/apps-games/app-andotp-android-otp-authenticator-t3636993) (please keep off-topic to a minimum)
- Telegram group [@andOTP](https://t.me/andOTP) (if you just want important updates you can mute the group so you only get notified about pinned messages) - Telegram group [@andOTP](https://t.me/andOTP) (if you just want important updates you can mute the group so you only get notified about pinned messages)
- Matrix channel [#andOTP:privacytools.io](https://matrix.to/#/#andOTP:privacytools.io) - Matrix channel [#andOTP:privacytools.io](https://matrix.to/#/#andOTP:privacytools.io)
#### Developers: #### Donations:
* [Jakob Nixdorf](https://github.com/flocke) (Telegram: [@flocke000](https://t.me/flocke000), Reddit: [/u/flocke000](https://www.reddit.com/user/flocke000)) If you want to show your appreciation for our work with a small donation you can do so using the following links:
* [Richy HBM](https://github.com/RichyHBM)
* [Donate to Jakob Nixdorf](https://flocke.shadowice.org/donate.html) (Main developer, maintainer)
* [Donate to Richy HBM](https://richyhbm.co.uk/donate) (Developer)
## Screenshots: ## Screenshots:
#### Light theme: #### Light theme:
@ -136,7 +138,7 @@ So make sure you have a **current backup** before switching!
* [Android-ItemTouchHelper-Demo](https://github.com/iPaulPro/Android-ItemTouchHelper-Demo/tree/master/app/src/main/java/co/paulburke/android/itemtouchhelperdemo/helper) * [Android-ItemTouchHelper-Demo](https://github.com/iPaulPro/Android-ItemTouchHelper-Demo/tree/master/app/src/main/java/co/paulburke/android/itemtouchhelperdemo/helper)
* [Code Parts from Google's Android Samples](https://android.googlesource.com/platform/development/+/master/samples/Vault/src/com/example/android/vault) * [Code Parts from Google's Android Samples](https://android.googlesource.com/platform/development/+/master/samples/Vault/src/com/example/android/vault)
* [LetterBitmap](http://stackoverflow.com/questions/23122088/colored-boxed-with-letters-a-la-gmail) * [LetterBitmap](https://stackoverflow.com/questions/23122088/colored-boxed-with-letters-a-la-gmail)
* [DimensionConverter](https://stackoverflow.com/questions/8343971/how-to-parse-a-dimension-string-and-convert-it-to-a-dimension-value) * [DimensionConverter](https://stackoverflow.com/questions/8343971/how-to-parse-a-dimension-string-and-convert-it-to-a-dimension-value)
#### Previously used open-source components: #### Previously used open-source components:

View file

@ -1,15 +1,15 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 28 compileSdkVersion 29
buildToolsVersion '28.0.3' buildToolsVersion '29.0.2'
defaultConfig { defaultConfig {
applicationId "org.shadowice.flocke.andotp" applicationId "org.shadowice.flocke.andotp"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 28 targetSdkVersion 29
versionCode 24 versionCode 26
versionName "0.6.3-beta1" versionName "0.6.3.1"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
} }
buildTypes { buildTypes {
@ -29,25 +29,38 @@ android {
dataBinding { dataBinding {
enabled = true enabled = true
} }
flavorDimensions 'market'
productFlavors {
fdroid {
dimension = 'market'
}
play {
dimension = 'market'
versionNameSuffix = "-play"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
} }
dependencies { dependencies {
ext.supportLibVersion = "28.0.0" implementation 'androidx.media:media:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0'
implementation "commons-codec:commons-codec:1.12" implementation "commons-codec:commons-codec:1.14"
implementation "com.android.support:support-media-compat:$supportLibVersion"
implementation "com.android.support:support-v4:$supportLibVersion"
implementation "com.android.support:appcompat-v7:$supportLibVersion"
implementation "com.android.support:cardview-v7:$supportLibVersion"
implementation "com.android.support:design:$supportLibVersion"
implementation "com.android.support:recyclerview-v7:$supportLibVersion"
implementation "com.android.support.constraint:constraint-layout:1.1.3"
implementation "com.github.aakira:expandable-layout:1.6.0" implementation "com.github.aakira:expandable-layout:1.6.0"
implementation "com.heinrichreimersoftware:material-intro:1.6.2" implementation "com.heinrichreimersoftware:material-intro:2.0.0"
implementation "com.journeyapps:zxing-android-embedded:3.6.0" implementation "com.journeyapps:zxing-android-embedded:3.6.0"
implementation "com.vanniktech:vntnumberpickerpreference:1.0.0" implementation "com.vanniktech:vntnumberpickerpreference:1.0.0"
implementation "me.zhanghai.android.materialprogressbar:library:1.4.2" implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
implementation "org.sufficientlysecure:openpgp-api:12.0" implementation "org.sufficientlysecure:openpgp-api:12.0"
implementation "com.leinardi.android:speed-dial:2.0.1" implementation "com.leinardi.android:speed-dial:3.1.1"
implementation "com.mikepenz:aboutlibraries:6.1.1" implementation "com.mikepenz:aboutlibraries:6.2.3"
} }

View file

@ -0,0 +1,54 @@
package org.shadowice.flocke.andotp.Fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import org.shadowice.flocke.andotp.R;
public class AboutFragment extends BaseAboutFragment {
private static final String ABOUT_AUTHOR1_EXTRA_LINK = "https://flocke.shadowice.org/donate.html";
private static final String ABOUT_AUTHOR2_EXTRA_LINK = "https://richyhbm.co.uk/donate";
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
LinearLayout author1Content = v.findViewById(R.id.aboutLayoutAuthor1Content);
LinearLayout author2Content = v.findViewById(R.id.aboutLayoutAuthor2Content);
View extra1 = inflater.inflate(R.layout.part_author_extra, null);
View extra2 = inflater.inflate(R.layout.part_author_extra, null);
extra1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
openURI(ABOUT_AUTHOR1_EXTRA_LINK);
} catch (Exception ignored) {
copyToClipboard(ABOUT_AUTHOR1_EXTRA_LINK);
}
}
});
extra2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
openURI(ABOUT_AUTHOR2_EXTRA_LINK);
} catch (Exception ignored) {
copyToClipboard(ABOUT_AUTHOR2_EXTRA_LINK);
}
}
});
author1Content.addView(extra1);
author2Content.addView(extra2);
return v;
}
}

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="@string/about_label_donate" />

View file

@ -27,8 +27,16 @@
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </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" android:host="totp" />
<data android:scheme="otpauth" android:host="hotp" />
</intent-filter>
<intent-filter> <intent-filter>
<action android:name="org.shadowice.flocke.andotp.intent.SCAN_QR" /> <action android:name="org.shadowice.flocke.andotp.intent.SCAN_QR" />
<action android:name="org.shadowice.flocke.andotp.intent.IMPORT_QR" />
<action android:name="org.shadowice.flocke.andotp.intent.ENTER_DETAILS" /> <action android:name="org.shadowice.flocke.andotp.intent.ENTER_DETAILS" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>

View file

@ -23,12 +23,12 @@
package org.shadowice.flocke.andotp.Activities; package org.shadowice.flocke.andotp.Activities;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.TabLayout; import com.google.android.material.tabs.TabLayout;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.support.v4.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter; import androidx.fragment.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager; import androidx.viewpager.widget.ViewPager;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.view.View; import android.view.View;
import android.view.ViewStub; import android.view.ViewStub;

View file

@ -24,9 +24,9 @@ package org.shadowice.flocke.andotp.Activities;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import android.support.design.widget.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.text.InputType; import android.text.InputType;
import android.text.method.PasswordTransformationMethod; import android.text.method.PasswordTransformationMethod;
import android.util.Base64; import android.util.Base64;
@ -89,6 +89,9 @@ public class AuthenticateActivity extends ThemedActivity
TextInputLayout passwordLayout = v.findViewById(R.id.passwordLayout); TextInputLayout passwordLayout = v.findViewById(R.id.passwordLayout);
passwordInput = v.findViewById(R.id.passwordEdit); passwordInput = v.findViewById(R.id.passwordEdit);
if (settings.getBlockAccessibility())
passwordLayout.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
passwordLabel.setText(labelMsg); passwordLabel.setText(labelMsg);
authMethod = settings.getAuthMethod(); authMethod = settings.getAuthMethod();

View file

@ -31,10 +31,10 @@ import android.content.IntentSender;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.v4.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import androidx.core.content.ContextCompat;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.ViewStub; import android.view.ViewStub;
@ -458,7 +458,7 @@ public class BackupActivity extends BaseActivity {
String password = settings.getBackupPasswordEnc(); String password = settings.getBackupPasswordEnc();
if (password.isEmpty()) { if (password.isEmpty()) {
PasswordEntryDialog pwDialog = new PasswordEntryDialog(this, PasswordEntryDialog.Mode.ENTER, new PasswordEntryDialog.PasswordEnteredCallback() { PasswordEntryDialog pwDialog = new PasswordEntryDialog(this, PasswordEntryDialog.Mode.ENTER, settings.getBlockAccessibility(), new PasswordEntryDialog.PasswordEnteredCallback() {
@Override @Override
public void onPasswordEntered(String newPassword) { public void onPasswordEntered(String newPassword) {
doRestoreCryptWithPassword(uri, newPassword, old_format); doRestoreCryptWithPassword(uri, newPassword, old_format);
@ -514,7 +514,7 @@ public class BackupActivity extends BaseActivity {
String password = settings.getBackupPasswordEnc(); String password = settings.getBackupPasswordEnc();
if (password.isEmpty()) { if (password.isEmpty()) {
PasswordEntryDialog pwDialog = new PasswordEntryDialog(this, PasswordEntryDialog.Mode.UPDATE, new PasswordEntryDialog.PasswordEnteredCallback() { PasswordEntryDialog pwDialog = new PasswordEntryDialog(this, PasswordEntryDialog.Mode.UPDATE, settings.getBlockAccessibility(), new PasswordEntryDialog.PasswordEnteredCallback() {
@Override @Override
public void onPasswordEntered(String newPassword) { public void onPasswordEntered(String newPassword) {
doBackupCryptWithPassword(uri, newPassword); doBackupCryptWithPassword(uri, newPassword);
@ -528,30 +528,8 @@ public class BackupActivity extends BaseActivity {
private void doBackupCryptWithPassword(Uri uri, String password) { private void doBackupCryptWithPassword(Uri uri, String password) {
if (Tools.isExternalStorageWritable()) { if (Tools.isExternalStorageWritable()) {
ArrayList<Entry> entries = DatabaseHelper.loadDatabase(this, encryptionKey);
String plain = DatabaseHelper.entriesToString(entries);
boolean success = true; boolean success = BackupHelper.backupToFile(this, uri, password, encryptionKey);
try {
int iter = EncryptionHelper.generateRandomIterations();
byte[] salt = EncryptionHelper.generateRandom(Constants.ENCRYPTION_IV_LENGTH);
SecretKey key = EncryptionHelper.generateSymmetricKeyPBKDF2(password, iter, salt);
byte[] encrypted = EncryptionHelper.encrypt(key, plain.getBytes(StandardCharsets.UTF_8));
byte[] iterBytes = ByteBuffer.allocate(Constants.INT_LENGTH).putInt(iter).array();
byte[] data = new byte[Constants.INT_LENGTH + Constants.ENCRYPTION_IV_LENGTH + encrypted.length];
System.arraycopy(iterBytes, 0, data, 0, Constants.INT_LENGTH);
System.arraycopy(salt, 0, data, Constants.INT_LENGTH, Constants.ENCRYPTION_IV_LENGTH);
System.arraycopy(encrypted, 0, data, Constants.INT_LENGTH + Constants.ENCRYPTION_IV_LENGTH, encrypted.length);
StorageAccessHelper.saveFile(this, uri, data);
} catch (Exception e) {
e.printStackTrace();
success = false;
}
if (success) { if (success) {
Toast.makeText(this, R.string.backup_toast_export_success, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.backup_toast_export_success, Toast.LENGTH_LONG).show();

View file

@ -27,10 +27,10 @@ import android.animation.ObjectAnimator;
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.design.widget.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import android.support.design.widget.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import android.support.v4.view.ViewPager; import androidx.viewpager.widget.ViewPager;
import android.text.Editable; import android.text.Editable;
import android.text.InputType; import android.text.InputType;
import android.text.TextWatcher; import android.text.TextWatcher;

View file

@ -23,24 +23,30 @@
package org.shadowice.flocke.andotp.Activities; package org.shadowice.flocke.andotp.Activities;
import android.Manifest;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.os.CountDownTimer; import android.os.CountDownTimer;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.widget.DrawerLayout; import androidx.annotation.NonNull;
import android.support.v7.app.ActionBarDrawerToggle; import androidx.core.app.ActivityCompat;
import android.support.v7.widget.LinearLayoutManager; import androidx.core.content.ContextCompat;
import android.support.v7.widget.RecyclerView; import androidx.drawerlayout.widget.DrawerLayout;
import android.support.v7.widget.SearchView; import androidx.appcompat.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar; import androidx.recyclerview.widget.LinearLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.ItemTouchHelper;
import android.text.TextUtils;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -63,10 +69,11 @@ import org.shadowice.flocke.andotp.Utilities.Constants;
import org.shadowice.flocke.andotp.Utilities.EncryptionHelper; import org.shadowice.flocke.andotp.Utilities.EncryptionHelper;
import org.shadowice.flocke.andotp.Utilities.KeyStoreHelper; import org.shadowice.flocke.andotp.Utilities.KeyStoreHelper;
import org.shadowice.flocke.andotp.Utilities.NotificationHelper; import org.shadowice.flocke.andotp.Utilities.NotificationHelper;
import org.shadowice.flocke.andotp.Utilities.ScanQRCodeFromFile;
import org.shadowice.flocke.andotp.Utilities.TokenCalculator; import org.shadowice.flocke.andotp.Utilities.TokenCalculator;
import org.shadowice.flocke.andotp.View.EntriesCardAdapter; import org.shadowice.flocke.andotp.View.EntriesCardAdapter;
import org.shadowice.flocke.andotp.View.ItemTouchHelper.SimpleItemTouchHelperCallback; import org.shadowice.flocke.andotp.View.ItemTouchHelper.SimpleItemTouchHelperCallback;
import org.shadowice.flocke.andotp.View.ManualEntryDialog; import org.shadowice.flocke.andotp.Dialogs.ManualEntryDialog;
import org.shadowice.flocke.andotp.View.TagsAdapter; import org.shadowice.flocke.andotp.View.TagsAdapter;
import java.util.ArrayList; import java.util.ArrayList;
@ -83,6 +90,7 @@ public class MainActivity extends BaseActivity
public static long animatorDuration = 1000; public static long animatorDuration = 1000;
private static final String INTENT_SCAN_QR = "org.shadowice.flocke.andotp.intent.SCAN_QR"; private static final String INTENT_SCAN_QR = "org.shadowice.flocke.andotp.intent.SCAN_QR";
private static final String INTENT_IMPORT_QR = "org.shadowice.flocke.andotp.intent.IMPORT_QR";
private static final String INTENT_ENTER_DETAILS = "org.shadowice.flocke.andotp.intent.ENTER_DETAILS"; private static final String INTENT_ENTER_DETAILS = "org.shadowice.flocke.andotp.intent.ENTER_DETAILS";
private EntriesCardAdapter adapter; private EntriesCardAdapter adapter;
@ -215,6 +223,9 @@ public class MainActivity extends BaseActivity
case R.id.fabEnterDetails: case R.id.fabEnterDetails:
ManualEntryDialog.show(MainActivity.this, settings, adapter); ManualEntryDialog.show(MainActivity.this, settings, adapter);
return false; return false;
case R.id.fabScanQRFromImage:
openFileWithPermissions(Constants.INTENT_MAIN_QR_OPEN_IMAGE);
return false;
default: default:
return false; return false;
} }
@ -280,20 +291,38 @@ public class MainActivity extends BaseActivity
setupDrawer(); setupDrawer();
Intent callingIntent = getIntent();
if (callingIntent != null && callingIntent.getAction() != null) {
if (callingIntent.getAction().equals(INTENT_SCAN_QR)) {
scanQRCode();
} else if (callingIntent.getAction().equals(INTENT_ENTER_DETAILS)) {
ManualEntryDialog.show(MainActivity.this, settings, adapter);
}
}
if (savedInstanceState != null){ if (savedInstanceState != null){
setFilterString(savedInstanceState.getString("filterString", "")); setFilterString(savedInstanceState.getString("filterString", ""));
} }
} }
private void checkIntent() {
Intent callingIntent = getIntent();
if (callingIntent != null && callingIntent.getAction() != null) {
// Cache and reset the action to prevent the same intent from being evaluated multiple times
String intentAction = callingIntent.getAction();
callingIntent.setAction(null);
if (intentAction.equals(INTENT_SCAN_QR)) {
scanQRCode();
} else if (intentAction.equals(INTENT_IMPORT_QR)) {
openFileWithPermissions(Constants.INTENT_MAIN_QR_OPEN_IMAGE);
} else if (intentAction.equals(INTENT_ENTER_DETAILS)) {
ManualEntryDialog.show(MainActivity.this, settings, adapter);
} else if (intentAction.equals(Intent.ACTION_VIEW)) {
try {
Entry entry = new Entry(callingIntent.getDataString());
entry.updateOTP();
entry.setLastUsed(System.currentTimeMillis());
adapter.addEntry(entry);
Toast.makeText(this, R.string.toast_intent_creation_succeeded, Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(this, R.string.toast_intent_creation_failed, Toast.LENGTH_LONG).show();
}
}
}
}
@Override @Override
protected void onPostCreate(Bundle savedInstanceState) { protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState); super.onPostCreate(savedInstanceState);
@ -325,6 +354,7 @@ public class MainActivity extends BaseActivity
} else { } else {
populateAdapter(); populateAdapter();
} }
checkIntent();
} }
if(setCountDownTimerNow()) countDownTimer.start(); if(setCountDownTimerNow()) countDownTimer.start();
@ -335,11 +365,22 @@ public class MainActivity extends BaseActivity
setFilterString(this.filterString); setFilterString(this.filterString);
} }
View cardList = findViewById(R.id.cardList);
if(cardList.getVisibility() == View.INVISIBLE)
cardList.setVisibility(View.VISIBLE);
startUpdater(); startUpdater();
} }
@Override @Override
public void onPause() { public void onPause() {
if(settings.getAuthMethod() == AuthMethod.DEVICE)
runOnUiThread(new Runnable() {
@Override
public void run() {
findViewById(R.id.cardList).setVisibility(View.INVISIBLE);
}
});
super.onPause(); super.onPause();
stopUpdater(); stopUpdater();
countDownTimer.cancel(); countDownTimer.cancel();
@ -357,11 +398,15 @@ public class MainActivity extends BaseActivity
key.equals(getString(R.string.settings_key_split_group_size)) || key.equals(getString(R.string.settings_key_split_group_size)) ||
key.equals(getString(R.string.settings_key_thumbnail_size))) { key.equals(getString(R.string.settings_key_thumbnail_size))) {
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} else if (key.equals(getString(R.string.settings_key_search_includes))) {
adapter.clearFilter();
} else if (key.equals(getString(R.string.settings_key_tap_to_reveal)) || } else if (key.equals(getString(R.string.settings_key_tap_to_reveal)) ||
key.equals(getString(R.string.settings_key_theme)) || key.equals(getString(R.string.settings_key_theme)) ||
key.equals(getString(R.string.settings_key_locale)) || key.equals(getString(R.string.settings_key_locale)) ||
key.equals(getString(R.string.settings_key_enable_screenshot)) || key.equals(getString(R.string.settings_key_enable_screenshot)) ||
key.equals(getString(R.string.settings_key_tag_functionality)) ) { key.equals(getString(R.string.settings_key_tag_functionality)) ||
key.equals(getString(R.string.settings_key_label_highlight_token)) ||
key.equals(getString(R.string.settings_key_card_layout))) {
recreate(); recreate();
} }
} }
@ -380,16 +425,7 @@ public class MainActivity extends BaseActivity
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if(result != null) { if(result != null) {
if(result.getContents() != null) { if(result.getContents() != null) {
try { addQRCode(result.getContents());
Entry e = new Entry(result.getContents());
e.updateOTP();
e.setLastUsed(System.currentTimeMillis());
adapter.addEntry(e);
adapter.saveEntries();
refreshTags();
} catch (Exception e) {
Toast.makeText(this, R.string.toast_invalid_qr_code, Toast.LENGTH_LONG).show();
}
} }
} else if (requestCode == Constants.INTENT_MAIN_BACKUP && resultCode == RESULT_OK) { } else if (requestCode == Constants.INTENT_MAIN_BACKUP && resultCode == RESULT_OK) {
if (intent.getBooleanExtra("reload", false)) { if (intent.getBooleanExtra("reload", false)) {
@ -421,6 +457,10 @@ public class MainActivity extends BaseActivity
updateEncryption(authKey); updateEncryption(authKey);
} }
} else if (requestCode == Constants.INTENT_MAIN_QR_OPEN_IMAGE && resultCode == RESULT_OK) {
if (intent != null) {
addQRCode(ScanQRCodeFromFile.scanQRImage(this, intent.getData()));
}
} }
} }
@ -742,4 +782,46 @@ public class MainActivity extends BaseActivity
}; };
return true; return true;
} }
private void openFileWithPermissions(int intentId){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
showOpenFileSelector(intentId);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Constants.PERMISSIONS_MAIN_QR_READ_IMAGE);
}
}
private void showOpenFileSelector(int intentId){
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, intentId);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == Constants.PERMISSIONS_MAIN_QR_READ_IMAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showOpenFileSelector(Constants.INTENT_MAIN_QR_OPEN_IMAGE);
} else {
Toast.makeText(this, R.string.backup_toast_storage_permissions, Toast.LENGTH_LONG).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void addQRCode(String result){
if(!TextUtils.isEmpty(result)) {
try {
Entry e = new Entry(result);
e.updateOTP();
e.setLastUsed(System.currentTimeMillis());
adapter.addEntry(e);
refreshTags();
} catch (Exception e) {
Toast.makeText(this, R.string.toast_invalid_qr_code, Toast.LENGTH_LONG).show();
}
}
}
} }

View file

@ -35,7 +35,7 @@ import android.preference.Preference;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v7.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import android.view.ViewStub; import android.view.ViewStub;
import android.widget.Toast; import android.widget.Toast;
@ -44,6 +44,7 @@ import org.openintents.openpgp.util.OpenPgpKeyPreference;
import org.shadowice.flocke.andotp.Database.Entry; import org.shadowice.flocke.andotp.Database.Entry;
import org.shadowice.flocke.andotp.Preferences.CredentialsPreference; import org.shadowice.flocke.andotp.Preferences.CredentialsPreference;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.BackupHelper;
import org.shadowice.flocke.andotp.Utilities.Constants; import org.shadowice.flocke.andotp.Utilities.Constants;
import org.shadowice.flocke.andotp.Utilities.DatabaseHelper; import org.shadowice.flocke.andotp.Utilities.DatabaseHelper;
import org.shadowice.flocke.andotp.Utilities.EncryptionHelper; import org.shadowice.flocke.andotp.Utilities.EncryptionHelper;
@ -52,6 +53,7 @@ import org.shadowice.flocke.andotp.Utilities.Settings;
import org.shadowice.flocke.andotp.Utilities.UIHelper; import org.shadowice.flocke.andotp.Utilities.UIHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
@ -143,6 +145,12 @@ public class SettingsActivity extends BaseActivity
fragment.useAndroidSync.setEnabled(true); fragment.useAndroidSync.setEnabled(true);
} }
} }
if (fragment.useAutoBackup != null) {
fragment.useAutoBackup.setEnabled(BackupHelper.autoBackupType(this) == Constants.BackupType.ENCRYPTED);
if (!fragment.useAutoBackup.isEnabled())
fragment.useAutoBackup.setValue(Constants.AutoBackup.OFF.toString().toLowerCase(Locale.ENGLISH));
}
} }
private void generateNewEncryptionKey() { private void generateNewEncryptionKey() {
@ -236,6 +244,7 @@ public class SettingsActivity extends BaseActivity
Settings settings; Settings settings;
ListPreference encryption; ListPreference encryption;
ListPreference useAutoBackup;
CheckBoxPreference useAndroidSync; CheckBoxPreference useAndroidSync;
OpenPgpAppPreference pgpProvider; OpenPgpAppPreference pgpProvider;
@ -344,6 +353,11 @@ public class SettingsActivity extends BaseActivity
} }
}); });
useAutoBackup = (ListPreference)findPreference(getString(R.string.settings_key_auto_backup_password_enc));
useAutoBackup.setEnabled(BackupHelper.autoBackupType(getActivity()) == Constants.BackupType.ENCRYPTED);
if(!useAutoBackup.isEnabled())
useAutoBackup.setValue(Constants.AutoBackup.OFF.toString().toLowerCase(Locale.ENGLISH));
useAndroidSync = (CheckBoxPreference) findPreference(getString(R.string.settings_key_enable_android_backup_service)); useAndroidSync = (CheckBoxPreference) findPreference(getString(R.string.settings_key_enable_android_backup_service));
useAndroidSync.setEnabled(settings.getEncryption() == EncryptionType.PASSWORD); useAndroidSync.setEnabled(settings.getEncryption() == EncryptionType.PASSWORD);
if(!useAndroidSync.isEnabled()) if(!useAndroidSync.isEnabled())

View file

@ -24,10 +24,13 @@ package org.shadowice.flocke.andotp.Activities;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.Settings; import org.shadowice.flocke.andotp.Utilities.Settings;
import org.shadowice.flocke.andotp.Utilities.Tools;
import java.util.Locale; import java.util.Locale;
@ -41,6 +44,11 @@ public abstract class ThemedActivity extends AppCompatActivity {
setTheme(settings.getTheme()); setTheme(settings.getTheme());
setLocale(); setLocale();
//Set navigation bar color
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(Tools.getThemeColor(this,R.attr.navigationBarColor));
}
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
} }

View file

@ -50,6 +50,7 @@ public class Entry {
private static final int DEFAULT_PERIOD = 30; private static final int DEFAULT_PERIOD = 30;
private static final String JSON_SECRET = "secret"; private static final String JSON_SECRET = "secret";
private static final String JSON_ISSUER = "issuer";
private static final String JSON_LABEL = "label"; private static final String JSON_LABEL = "label";
private static final String JSON_PERIOD = "period"; private static final String JSON_PERIOD = "period";
private static final String JSON_COUNTER = "counter"; private static final String JSON_COUNTER = "counter";
@ -66,6 +67,7 @@ public class Entry {
private TokenCalculator.HashAlgorithm algorithm = TokenCalculator.DEFAULT_ALGORITHM; private TokenCalculator.HashAlgorithm algorithm = TokenCalculator.DEFAULT_ALGORITHM;
private byte[] secret; private byte[] secret;
private long counter; private long counter;
private String issuer;
private String label; private String label;
private String currentOTP; private String currentOTP;
private boolean visible = false; private boolean visible = false;
@ -74,27 +76,35 @@ public class Entry {
private long last_used = 0; private long last_used = 0;
public List<String> tags = new ArrayList<>(); public List<String> tags = new ArrayList<>();
private EntryThumbnail.EntryThumbnails thumbnail = EntryThumbnail.EntryThumbnails.Default; private EntryThumbnail.EntryThumbnails thumbnail = EntryThumbnail.EntryThumbnails.Default;
private static final int COLOR_DEFAULT = 0;
public static final int COLOR_RED = 1;
private static final int EXPIRY_TIME = 8;
private int color = COLOR_DEFAULT;
public Entry(){} public Entry(){}
public Entry(OTPType type, String secret, int period, int digits, String label, TokenCalculator.HashAlgorithm algorithm, List<String> tags) { public Entry(OTPType type, String secret, int period, int digits, String issuer, String label, TokenCalculator.HashAlgorithm algorithm, List<String> tags) {
this.type = type; this.type = type;
this.secret = new Base32().decode(secret.toUpperCase()); this.secret = new Base32().decode(secret.toUpperCase());
this.period = period; this.period = period;
this.digits = digits; this.digits = digits;
this.issuer = issuer;
this.label = label; this.label = label;
this.algorithm = algorithm; this.algorithm = algorithm;
this.tags = tags; this.tags = tags;
setThumbnailFromIssuer(issuer);
} }
public Entry(OTPType type, String secret, long counter, int digits, String label, TokenCalculator.HashAlgorithm algorithm, List<String> tags) { public Entry(OTPType type, String secret, long counter, int digits, String issuer, String label, TokenCalculator.HashAlgorithm algorithm, List<String> tags) {
this.type = type; this.type = type;
this.secret = new Base32().decode(secret.toUpperCase()); this.secret = new Base32().decode(secret.toUpperCase());
this.counter = counter; this.counter = counter;
this.digits = digits; this.digits = digits;
this.issuer = issuer;
this.label = label; this.label = label;
this.algorithm = algorithm; this.algorithm = algorithm;
this.tags = tags; this.tags = tags;
setThumbnailFromIssuer(issuer);
} }
public Entry(String contents) throws Exception { public Entry(String contents) throws Exception {
@ -124,10 +134,6 @@ public class Entry {
String algorithm = uri.getQueryParameter("algorithm"); String algorithm = uri.getQueryParameter("algorithm");
List<String> tags = uri.getQueryParameters("tags"); List<String> tags = uri.getQueryParameters("tags");
if (issuer != null){
label = issuer +" - "+label;
}
if (type == OTPType.HOTP) { if (type == OTPType.HOTP) {
if (counter != null) { if (counter != null) {
this.counter = Long.parseLong(counter); this.counter = Long.parseLong(counter);
@ -142,6 +148,7 @@ public class Entry {
} }
} }
this.issuer = issuer;
this.label = label; this.label = label;
this.secret = new Base32().decode(secret.toUpperCase()); this.secret = new Base32().decode(secret.toUpperCase());
@ -157,11 +164,15 @@ public class Entry {
this.algorithm = TokenCalculator.DEFAULT_ALGORITHM; this.algorithm = TokenCalculator.DEFAULT_ALGORITHM;
} }
if(tags != null) { if (tags != null) {
this.tags = tags; this.tags = tags;
} else { } else {
this.tags = new ArrayList<>(); this.tags = new ArrayList<>();
} }
if (issuer != null) {
setThumbnailFromIssuer(issuer);
}
} }
public Entry (JSONObject jsonObj) public Entry (JSONObject jsonObj)
@ -169,6 +180,13 @@ public class Entry {
this.secret = new Base32().decode(jsonObj.getString(JSON_SECRET).toUpperCase()); this.secret = new Base32().decode(jsonObj.getString(JSON_SECRET).toUpperCase());
this.label = jsonObj.getString(JSON_LABEL); this.label = jsonObj.getString(JSON_LABEL);
try {
this.issuer = jsonObj.getString(JSON_ISSUER);
} catch (JSONException e) {
// Older backup version did not save issuer and label separately
this.issuer = "";
}
try { try {
this.type = OTPType.valueOf(jsonObj.getString(JSON_TYPE)); this.type = OTPType.valueOf(jsonObj.getString(JSON_TYPE));
} catch(Exception e) { } catch(Exception e) {
@ -227,6 +245,7 @@ public class Entry {
public JSONObject toJSON() throws JSONException { public JSONObject toJSON() throws JSONException {
JSONObject jsonObj = new JSONObject(); JSONObject jsonObj = new JSONObject();
jsonObj.put(JSON_SECRET, new String(new Base32().encode(getSecret()))); jsonObj.put(JSON_SECRET, new String(new Base32().encode(getSecret())));
jsonObj.put(JSON_ISSUER, getIssuer());
jsonObj.put(JSON_LABEL, getLabel()); jsonObj.put(JSON_LABEL, getLabel());
jsonObj.put(JSON_DIGITS, getDigits()); jsonObj.put(JSON_DIGITS, getDigits());
jsonObj.put(JSON_TYPE, getType().toString()); jsonObj.put(JSON_TYPE, getType().toString());
@ -252,6 +271,8 @@ public class Entry {
return type == OTPType.TOTP || type == OTPType.STEAM; return type == OTPType.TOTP || type == OTPType.STEAM;
} }
public boolean isCounterBased() { return type == OTPType.HOTP; }
public OTPType getType() { public OTPType getType() {
return type; return type;
} }
@ -268,6 +289,14 @@ public class Entry {
this.secret = secret; this.secret = secret;
} }
public String getIssuer() {
return issuer;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public String getLabel() { public String getLabel() {
return label; return label;
} }
@ -360,7 +389,8 @@ public class Entry {
currentOTP = TokenCalculator.TOTP_Steam(secret, period, digits, algorithm); currentOTP = TokenCalculator.TOTP_Steam(secret, period, digits, algorithm);
last_update = counter; last_update = counter;
//New OTP. Change color to default color
setColor(COLOR_DEFAULT);
return true; return true;
} else { } else {
return false; return false;
@ -373,6 +403,33 @@ public class Entry {
} }
} }
/**
* Checks if the OTP is expiring. The color for the entry will be changed to red if the expiry time is less than or equal to 8 seconds
* COLOR_DEFAULT indicates that the OTP has not expired. In this case check if the OTP is about to expire. Update color to COLOR_RED if it's about to expire
* COLOR_RED indicates that the OTP is already about to expire. Don't check again.
* The color will be reset to COLOR_DEFAULT in {@link #updateOTP()} method
*
* @return Return true only if the color has changed to red to save from unnecessary notifying dataset
* */
public boolean hasColorChanged() {
if(color == COLOR_DEFAULT){
long time = System.currentTimeMillis() / 1000;
if ((time % getPeriod()) > (getPeriod() - EXPIRY_TIME)) {
setColor(COLOR_RED);
return true;
}
}
return false;
}
private void setThumbnailFromIssuer(String issuer) {
try {
this.thumbnail = EntryThumbnail.EntryThumbnails.valueOfIgnoreCase(issuer);
} catch(Exception e) {
this.thumbnail = EntryThumbnail.EntryThumbnails.Default;
}
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
@ -391,4 +448,12 @@ public class Entry {
public int hashCode() { public int hashCode() {
return Objects.hash(type, period, counter, digits, algorithm, secret, label); return Objects.hash(type, period, counter, digits, algorithm, secret, label);
} }
public void setColor(int color) {
this.color = color;
}
public int getColor() {
return color;
}
} }

View file

@ -20,11 +20,11 @@
* SOFTWARE. * SOFTWARE.
*/ */
package org.shadowice.flocke.andotp.View; package org.shadowice.flocke.andotp.Dialogs;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.support.v7.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -45,6 +45,8 @@ import org.shadowice.flocke.andotp.Database.Entry;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.Settings; import org.shadowice.flocke.andotp.Utilities.Settings;
import org.shadowice.flocke.andotp.Utilities.TokenCalculator; import org.shadowice.flocke.andotp.Utilities.TokenCalculator;
import org.shadowice.flocke.andotp.View.EntriesCardAdapter;
import org.shadowice.flocke.andotp.View.TagsAdapter;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -58,7 +60,11 @@ public class ManualEntryDialog {
ViewGroup container = callingActivity.findViewById(R.id.main_content); ViewGroup container = callingActivity.findViewById(R.id.main_content);
View inputView = callingActivity.getLayoutInflater().inflate(R.layout.dialog_manual_entry, container, false); View inputView = callingActivity.getLayoutInflater().inflate(R.layout.dialog_manual_entry, container, false);
if (settings.getBlockAccessibility())
inputView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
final Spinner typeInput = inputView.findViewById(R.id.manual_type); final Spinner typeInput = inputView.findViewById(R.id.manual_type);
final EditText issuerInput = inputView.findViewById(R.id.manual_issuer);
final EditText labelInput = inputView.findViewById(R.id.manual_label); final EditText labelInput = inputView.findViewById(R.id.manual_label);
final EditText secretInput = inputView.findViewById(R.id.manual_secret); final EditText secretInput = inputView.findViewById(R.id.manual_secret);
final EditText counterInput = inputView.findViewById(R.id.manual_counter); final EditText counterInput = inputView.findViewById(R.id.manual_counter);
@ -192,28 +198,28 @@ public class ManualEntryDialog {
Entry.OTPType type = (Entry.OTPType) typeInput.getSelectedItem(); Entry.OTPType type = (Entry.OTPType) typeInput.getSelectedItem();
TokenCalculator.HashAlgorithm algorithm = (TokenCalculator.HashAlgorithm) algorithmInput.getSelectedItem(); TokenCalculator.HashAlgorithm algorithm = (TokenCalculator.HashAlgorithm) algorithmInput.getSelectedItem();
String issuer = issuerInput.getText().toString();
String label = labelInput.getText().toString(); String label = labelInput.getText().toString();
String secret = secretInput.getText().toString(); //Replace spaces with empty characters
String secret = secretInput.getText().toString().replaceAll("\\s+","");
int digits = Integer.parseInt(digitsInput.getText().toString()); int digits = Integer.parseInt(digitsInput.getText().toString());
if (type == Entry.OTPType.TOTP || type == Entry.OTPType.STEAM) { if (type == Entry.OTPType.TOTP || type == Entry.OTPType.STEAM) {
int period = Integer.parseInt(periodInput.getText().toString()); int period = Integer.parseInt(periodInput.getText().toString());
Entry e = new Entry(type, secret, period, digits, label, algorithm, tagsAdapter.getActiveTags()); Entry e = new Entry(type, secret, period, digits, issuer, label, algorithm, tagsAdapter.getActiveTags());
e.updateOTP(); e.updateOTP();
e.setLastUsed(System.currentTimeMillis()); e.setLastUsed(System.currentTimeMillis());
adapter.addEntry(e); adapter.addEntry(e);
adapter.saveEntries();
callingActivity.refreshTags(); callingActivity.refreshTags();
} else if (type == Entry.OTPType.HOTP) { } else if (type == Entry.OTPType.HOTP) {
long counter = Long.parseLong(counterInput.getText().toString()); long counter = Long.parseLong(counterInput.getText().toString());
Entry e = new Entry(type, secret, counter, digits, label, algorithm, tagsAdapter.getActiveTags()); Entry e = new Entry(type, secret, counter, digits, issuer, label, algorithm, tagsAdapter.getActiveTags());
e.updateOTP(); e.updateOTP();
e.setLastUsed(System.currentTimeMillis()); e.setLastUsed(System.currentTimeMillis());
adapter.addEntry(e); adapter.addEntry(e);
adapter.saveEntries();
} }
} }
}) })

View file

@ -1,8 +1,10 @@
package org.shadowice.flocke.andotp.Dialogs; package org.shadowice.flocke.andotp.Dialogs;
import android.content.Context; import android.content.Context;
import android.support.design.widget.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import android.support.v7.app.AppCompatDialog; import com.google.android.material.textfield.TextInputLayout;
import androidx.appcompat.app.AppCompatDialog;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -29,15 +31,21 @@ public class PasswordEntryDialog extends AppCompatDialog
private EditText passwordConfirm; private EditText passwordConfirm;
private Button okButton; private Button okButton;
public PasswordEntryDialog(Context context, Mode newMode, PasswordEnteredCallback newCallback) { public PasswordEntryDialog(Context context, Mode newMode, boolean blockAccessibility, PasswordEnteredCallback newCallback) {
super(context, Tools.getThemeResource(context, R.attr.dialogTheme)); super(context, Tools.getThemeResource(context, R.attr.dialogTheme));
setTitle(R.string.dialog_title_enter_password); setTitle(R.string.dialog_title_enter_password);
setContentView(R.layout.dialog_password_entry); setContentView(R.layout.dialog_password_entry);
TextInputLayout passwordLayout = findViewById(R.id.passwordInputLayout);
passwordInput = findViewById(R.id.passwordInput); passwordInput = findViewById(R.id.passwordInput);
passwordConfirm = findViewById(R.id.passwordConfirm); passwordConfirm = findViewById(R.id.passwordConfirm);
if (blockAccessibility) {
passwordLayout.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
passwordConfirm.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
okButton = findViewById(R.id.buttonOk); okButton = findViewById(R.id.buttonOk);
Button cancelButton = findViewById(R.id.buttonCancel); Button cancelButton = findViewById(R.id.buttonCancel);

View file

@ -21,7 +21,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package org.shadowice.flocke.andotp.View; package org.shadowice.flocke.andotp.Dialogs;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
@ -35,6 +35,7 @@ import android.widget.FrameLayout;
import android.widget.ListView; import android.widget.ListView;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.View.TagsAdapter;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;

View file

@ -11,8 +11,8 @@ import android.content.pm.PackageManager;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -25,32 +25,27 @@ import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.Settings; import org.shadowice.flocke.andotp.Utilities.Settings;
import org.shadowice.flocke.andotp.Utilities.Tools; import org.shadowice.flocke.andotp.Utilities.Tools;
public class AboutFragment extends Fragment { public class BaseAboutFragment extends Fragment {
private static final String GITHUB_URI = "https://github.com/andOTP/andOTP"; private static final String GITHUB_URI = "https://github.com/andOTP/andOTP";
private static final String CHANGELOG_URI = GITHUB_URI + "/blob/master/CHANGELOG.md"; private static final String CHANGELOG_URI = GITHUB_URI + "/blob/master/CHANGELOG.md";
private static final String MIT_URI = GITHUB_URI + "/blob/master/LICENSE.txt"; private static final String MIT_URI = GITHUB_URI + "/blob/master/LICENSE.txt";
private static final String AUTHOR1_GITHUB = "https://github.com/flocke"; private static final String AUTHOR1_GITHUB = "https://github.com/flocke";
private static final String AUTHOR1_EXTRA = "https://flocke.shadowice.org/donate.html";
private static final String AUTHOR2_GITHUB = "https://github.com/richyhbm"; private static final String AUTHOR2_GITHUB = "https://github.com/richyhbm";
private static final String AUTHOR2_EXTRA = "https://richyhbm.co.uk/donate";
private static final String AUTHOR_ORIGINAL_GITHUB = "https://github.com/0xbb"; private static final String AUTHOR_ORIGINAL_GITHUB = "https://github.com/0xbb";
private static final String AUTHOR_ORIGINAL_EXTRA = AUTHOR_ORIGINAL_GITHUB + "/otp-authenticator"; private static final String AUTHOR_ORIGINAL_EXTRA = AUTHOR_ORIGINAL_GITHUB + "/otp-authenticator";
private static final String CONTRIBUTORS_URI = GITHUB_URI + "/blob/master/README.md#contributors"; private static final String CONTRIBUTORS_URI = GITHUB_URI + "/graphs/contributors";
private static final String TRANSLATORS_URI = GITHUB_URI + "/blob/master/README.md#translators";
private static final String BUGREPORT_URI = GITHUB_URI + "/issues"; private static final String SUPPORT_URI = GITHUB_URI + "/blob/master/README.md#contribute";
private static final String TRANSLATE_URI = "https://crowdin.com/project/andotp";
private Settings settings; private Settings settings;
static final int[] imageResources = { static final int[] imageResources = {
R.id.aboutImgVersion, R.id.aboutImgLicense, R.id.aboutImgChangelog, R.id.aboutImgSource, R.id.aboutImgVersion, R.id.aboutImgLicense, R.id.aboutImgChangelog, R.id.aboutImgSource,
R.id.aboutImgAuthor2, R.id.aboutImgAuthorOriginal, R.id.aboutImgContributors, R.id.aboutImgAuthor2, R.id.aboutImgAuthorOriginal, R.id.aboutImgContributors,
R.id.aboutImgTranslators, R.id.aboutImgBugs, R.id.aboutImgTranslate R.id.aboutImgSupport
}; };
static long lastTap = 0; static long lastTap = 0;
@ -138,43 +133,20 @@ public class AboutFragment extends Fragment {
}); });
LinearLayout author1Layout = v.findViewById(R.id.aboutLayoutAuthor1); LinearLayout author1Layout = v.findViewById(R.id.aboutLayoutAuthor1);
TextView author1Donate = v.findViewById(R.id.about_author1_extra);
author1Layout.setOnClickListener(new View.OnClickListener() { author1Layout.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
openURI(AUTHOR1_GITHUB); openURI(AUTHOR1_GITHUB);
} }
}); });
author1Donate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
openURI(AUTHOR1_EXTRA);
} catch(Exception ignored) {
copyToClipboard(AUTHOR1_EXTRA);
}
}
});
LinearLayout author2Layout = v.findViewById(R.id.aboutLayoutAuthor2); LinearLayout author2Layout = v.findViewById(R.id.aboutLayoutAuthor2);
TextView author2Donate = v.findViewById(R.id.about_author2_extra);
author2Layout.setOnClickListener(new View.OnClickListener() { author2Layout.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
openURI(AUTHOR2_GITHUB); openURI(AUTHOR2_GITHUB);
} }
}); });
author2Donate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
openURI(AUTHOR2_EXTRA);
} catch(Exception ignored) {
copyToClipboard(AUTHOR2_EXTRA);
}
}
});
LinearLayout authorOrigialLayout = v.findViewById(R.id.aboutLayoutOriginalAuthor); LinearLayout authorOrigialLayout = v.findViewById(R.id.aboutLayoutOriginalAuthor);
TextView authorOriginalApp = v.findViewById(R.id.about_author_original_extra); TextView authorOriginalApp = v.findViewById(R.id.about_author_original_extra);
@ -196,32 +168,18 @@ public class AboutFragment extends Fragment {
}); });
LinearLayout contributors = v.findViewById(R.id.about_layout_contributors); LinearLayout contributors = v.findViewById(R.id.about_layout_contributors);
LinearLayout translators = v.findViewById(R.id.about_layout_translators);
contributors.setOnClickListener(new View.OnClickListener() { contributors.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
openURI(CONTRIBUTORS_URI); openURI(CONTRIBUTORS_URI);
} }
}); });
translators.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openURI(TRANSLATORS_URI);
}
});
LinearLayout bugReport = v.findViewById(R.id.about_layout_bugs); LinearLayout supportLayout = v.findViewById(R.id.about_layout_support);
LinearLayout translate = v.findViewById(R.id.about_layout_translate); supportLayout.setOnClickListener(new View.OnClickListener() {
bugReport.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
openURI(BUGREPORT_URI); openURI(SUPPORT_URI);
}
});
translate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openURI(TRANSLATE_URI);
} }
}); });
@ -259,5 +217,4 @@ public class AboutFragment extends Fragment {
clipboard.setPrimaryClip(clip); clipboard.setPrimaryClip(clip);
Toast.makeText(getActivity(), getString(R.string.about_toast_copied_to_clipboard), Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), getString(R.string.about_toast_copied_to_clipboard), Toast.LENGTH_SHORT).show();
} }
} }

View file

@ -26,8 +26,8 @@ import android.app.AlertDialog;
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.content.Context; import android.content.Context;
import android.preference.DialogPreference; import android.preference.DialogPreference;
import android.support.design.widget.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import android.support.design.widget.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import android.text.Editable; import android.text.Editable;
import android.text.InputType; import android.text.InputType;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -50,6 +50,7 @@ import org.shadowice.flocke.andotp.Utilities.UIHelper;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale;
import static android.content.Context.KEYGUARD_SERVICE; import static android.content.Context.KEYGUARD_SERVICE;
import static org.shadowice.flocke.andotp.Utilities.Constants.AuthMethod; import static org.shadowice.flocke.andotp.Utilities.Constants.AuthMethod;
@ -126,6 +127,11 @@ public class CredentialsPreference extends DialogPreference
passwordInput = view.findViewById(R.id.passwordEdit); passwordInput = view.findViewById(R.id.passwordEdit);
passwordConfirm = view.findViewById(R.id.passwordConfirm); passwordConfirm = view.findViewById(R.id.passwordConfirm);
if (settings.getBlockAccessibility()) {
passwordLayout.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
passwordConfirm.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
toShortWarning = view.findViewById(R.id.toShortWarning); toShortWarning = view.findViewById(R.id.toShortWarning);
passwordInput.addTextChangedListener(this); passwordInput.addTextChangedListener(this);
@ -145,11 +151,11 @@ public class CredentialsPreference extends DialogPreference
@Override @Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) { protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
if (restorePersistedValue) { if (restorePersistedValue) {
String stringValue = getPersistedString(DEFAULT_VALUE.name().toLowerCase()); String stringValue = getPersistedString(DEFAULT_VALUE.name().toLowerCase(Locale.ENGLISH));
value = AuthMethod.valueOf(stringValue.toUpperCase()); value = AuthMethod.valueOf(stringValue.toUpperCase(Locale.ENGLISH));
} else { } else {
value = DEFAULT_VALUE; value = DEFAULT_VALUE;
persistString(value.name().toLowerCase()); persistString(value.name().toLowerCase(Locale.ENGLISH));
} }
setSummary(entries.get(entryValues.indexOf(value))); setSummary(entries.get(entryValues.indexOf(value)));

View file

@ -26,8 +26,8 @@ import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.preference.DialogPreference; import android.preference.DialogPreference;
import android.support.design.widget.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import android.support.design.widget.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import android.text.Editable; import android.text.Editable;
import android.text.InputType; import android.text.InputType;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -42,6 +42,7 @@ import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.Constants; import org.shadowice.flocke.andotp.Utilities.Constants;
import org.shadowice.flocke.andotp.Utilities.EncryptionHelper; import org.shadowice.flocke.andotp.Utilities.EncryptionHelper;
import org.shadowice.flocke.andotp.Utilities.KeyStoreHelper; import org.shadowice.flocke.andotp.Utilities.KeyStoreHelper;
import org.shadowice.flocke.andotp.Utilities.Settings;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.KeyPair; import java.security.KeyPair;
@ -92,10 +93,17 @@ public class PasswordEncryptedPreference extends DialogPreference
@Override @Override
protected void onBindDialogView(View view) { protected void onBindDialogView(View view) {
Settings settings = new Settings(getContext());
TextInputLayout passwordLayout = view.findViewById(R.id.passwordLayout); TextInputLayout passwordLayout = view.findViewById(R.id.passwordLayout);
passwordInput = view.findViewById(R.id.passwordEdit); passwordInput = view.findViewById(R.id.passwordEdit);
passwordConfirm = view.findViewById(R.id.passwordConfirm); passwordConfirm = view.findViewById(R.id.passwordConfirm);
if (settings.getBlockAccessibility()) {
passwordLayout.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
passwordConfirm.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
}
Button btnCancel = view.findViewById(R.id.btnCancel); Button btnCancel = view.findViewById(R.id.btnCancel);
btnSave = view.findViewById(R.id.btnSave); btnSave = view.findViewById(R.id.btnSave);
btnSave.setEnabled(false); btnSave.setEnabled(false);

View file

@ -27,7 +27,7 @@ import android.Manifest;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.support.v4.content.ContextCompat; import androidx.core.content.ContextCompat;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.Constants; import org.shadowice.flocke.andotp.Utilities.Constants;

View file

@ -1,6 +1,18 @@
package org.shadowice.flocke.andotp.Utilities; package org.shadowice.flocke.andotp.Utilities;
import android.Manifest;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager;
import android.net.Uri;
import androidx.core.content.ContextCompat;
import org.shadowice.flocke.andotp.Database.Entry;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import javax.crypto.SecretKey;
public class BackupHelper { public class BackupHelper {
public static String backupFilename(Context context, Constants.BackupType type) { public static String backupFilename(Context context, Constants.BackupType type) {
@ -28,4 +40,53 @@ public class BackupHelper {
return Constants.BACKUP_FILENAME_PLAIN; return Constants.BACKUP_FILENAME_PLAIN;
} }
public static Constants.BackupType autoBackupType(Context context) {
Settings settings = new Settings(context);
if(ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
return Constants.BackupType.UNAVAILABLE;
}
if(settings.getBackupAsk()) {
return Constants.BackupType.UNAVAILABLE;
}
if(!Tools.mkdir(settings.getBackupDir())) {
return Constants.BackupType.UNAVAILABLE;
}
if (!settings.getBackupPasswordEnc().isEmpty()) {
return Constants.BackupType.ENCRYPTED;
}
return Constants.BackupType.UNAVAILABLE;
}
public static boolean backupToFile(Context context, Uri uri, String password, SecretKey encryptionKey)
{
ArrayList<Entry> entries = DatabaseHelper.loadDatabase(context, encryptionKey);
String plain = DatabaseHelper.entriesToString(entries);
try {
int iter = EncryptionHelper.generateRandomIterations();
byte[] salt = EncryptionHelper.generateRandom(Constants.ENCRYPTION_IV_LENGTH);
SecretKey key = EncryptionHelper.generateSymmetricKeyPBKDF2(password, iter, salt);
byte[] encrypted = EncryptionHelper.encrypt(key, plain.getBytes(StandardCharsets.UTF_8));
byte[] iterBytes = ByteBuffer.allocate(Constants.INT_LENGTH).putInt(iter).array();
byte[] data = new byte[Constants.INT_LENGTH + Constants.ENCRYPTION_IV_LENGTH + encrypted.length];
System.arraycopy(iterBytes, 0, data, 0, Constants.INT_LENGTH);
System.arraycopy(salt, 0, data, Constants.INT_LENGTH, Constants.ENCRYPTION_IV_LENGTH);
System.arraycopy(encrypted, 0, data, Constants.INT_LENGTH + Constants.ENCRYPTION_IV_LENGTH, encrypted.length);
StorageAccessHelper.saveFile(context, uri, data);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
} }

View file

@ -41,7 +41,7 @@ public class Constants {
} }
public enum BackupType { public enum BackupType {
PLAIN_TEXT, ENCRYPTED, OPEN_PGP PLAIN_TEXT, ENCRYPTED, OPEN_PGP, UNAVAILABLE
} }
public enum TagFunctionality { public enum TagFunctionality {
@ -52,11 +52,24 @@ public class Constants {
BACKUP_FAILED, BACKUP_SUCCESS BACKUP_FAILED, BACKUP_SUCCESS
} }
public enum SearchIncludes {
LABEL, ISSUER, TAGS
}
public enum CardLayouts {
DEFAULT, FULL
}
public enum AutoBackup {
OFF, NEW_ENTRIES, ALL_EDITS
}
// Intents (Format: A0x with A = parent Activity, x = number of the intent) // Intents (Format: A0x with A = parent Activity, x = number of the intent)
public final static int INTENT_MAIN_AUTHENTICATE = 100; public final static int INTENT_MAIN_AUTHENTICATE = 100;
public final static int INTENT_MAIN_SETTINGS = 101; public final static int INTENT_MAIN_SETTINGS = 101;
public final static int INTENT_MAIN_BACKUP = 102; public final static int INTENT_MAIN_BACKUP = 102;
public final static int INTENT_MAIN_INTRO = 103; public final static int INTENT_MAIN_INTRO = 103;
public final static int INTENT_MAIN_QR_OPEN_IMAGE = 104;
public final static int INTENT_BACKUP_OPEN_DOCUMENT_PLAIN = 200; public final static int INTENT_BACKUP_OPEN_DOCUMENT_PLAIN = 200;
public final static int INTENT_BACKUP_SAVE_DOCUMENT_PLAIN = 201; public final static int INTENT_BACKUP_SAVE_DOCUMENT_PLAIN = 201;
@ -71,6 +84,7 @@ public class Constants {
public static final int INTENT_SETTINGS_AUTHENTICATE = 300; public static final int INTENT_SETTINGS_AUTHENTICATE = 300;
// Permission requests (Format: A1x with A = parent Activity, x = number of the request) // Permission requests (Format: A1x with A = parent Activity, x = number of the request)
public final static int PERMISSIONS_MAIN_QR_READ_IMAGE = 111;
public final static int PERMISSIONS_BACKUP_READ_IMPORT_PLAIN = 210; public final static int PERMISSIONS_BACKUP_READ_IMPORT_PLAIN = 210;
public final static int PERMISSIONS_BACKUP_WRITE_EXPORT_PLAIN = 211; public final static int PERMISSIONS_BACKUP_WRITE_EXPORT_PLAIN = 211;
public final static int PERMISSIONS_BACKUP_READ_IMPORT_CRYPT = 212; public final static int PERMISSIONS_BACKUP_READ_IMPORT_CRYPT = 212;

View file

@ -28,7 +28,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.support.v7.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
@ -40,6 +40,7 @@ public class EntryThumbnail {
public enum EntryThumbnails { public enum EntryThumbnails {
Default(R.mipmap.ic_launcher_round), Default(R.mipmap.ic_launcher_round),
OneAndOne(R.drawable.thumb_1and1),
OnePassword(R.drawable.thumb_1password), OnePassword(R.drawable.thumb_1password),
Adobe(R.drawable.thumb_adobe), Adobe(R.drawable.thumb_adobe),
AdGuard(R.drawable.thumb_adguard), AdGuard(R.drawable.thumb_adguard),
@ -61,6 +62,7 @@ public class EntryThumbnail {
BitBucket(R.drawable.thumb_bitbucket), BitBucket(R.drawable.thumb_bitbucket),
Bitcoin(R.drawable.thumb_bitcoin), Bitcoin(R.drawable.thumb_bitcoin),
Bitfinex(R.drawable.thumb_bitfinex), Bitfinex(R.drawable.thumb_bitfinex),
Bitmex(R.drawable.thumb_bitmex),
Bitstamp(R.mipmap.thumb_bitstamp, AssetType.Bitmap), Bitstamp(R.mipmap.thumb_bitstamp, AssetType.Bitmap),
Bitpanda(R.drawable.thumb_bitpanda), Bitpanda(R.drawable.thumb_bitpanda),
Bittrex(R.drawable.thumb_bittrex), Bittrex(R.drawable.thumb_bittrex),
@ -86,6 +88,7 @@ public class EntryThumbnail {
Discord(R.drawable.thumb_discord), Discord(R.drawable.thumb_discord),
Discourse(R.drawable.thumb_discourse), Discourse(R.drawable.thumb_discourse),
Disroot(R.drawable.thumb_disroot), Disroot(R.drawable.thumb_disroot),
Docker(R.drawable.thumb_docker),
DocuSign(R.drawable.thumb_docusign), DocuSign(R.drawable.thumb_docusign),
Dropbox(R.drawable.thumb_dropbox), Dropbox(R.drawable.thumb_dropbox),
ElectronicArts(R.drawable.thumb_electronic_arts), ElectronicArts(R.drawable.thumb_electronic_arts),
@ -95,6 +98,7 @@ public class EntryThumbnail {
Facebook(R.drawable.thumb_facebook), Facebook(R.drawable.thumb_facebook),
FACEIT(R.drawable.thumb_faceit), FACEIT(R.drawable.thumb_faceit),
Fingerprint(R.drawable.thumb_fingerprint), Fingerprint(R.drawable.thumb_fingerprint),
Finnair(R.drawable.thumb_finnair),
Firefox(R.drawable.thumb_firefox), Firefox(R.drawable.thumb_firefox),
Flight(R.drawable.thumb_flight_takeoff), Flight(R.drawable.thumb_flight_takeoff),
Floatplane(R.drawable.thumb_floatplane), Floatplane(R.drawable.thumb_floatplane),
@ -116,6 +120,7 @@ public class EntryThumbnail {
HomeAssistant(R.drawable.thumb_home_assistant), HomeAssistant(R.drawable.thumb_home_assistant),
HumbleBundle(R.drawable.thumb_humblebundle), HumbleBundle(R.drawable.thumb_humblebundle),
HurricaneElectric(R.drawable.thumb_hurricane_electric), HurricaneElectric(R.drawable.thumb_hurricane_electric),
IBM(R.drawable.thumb_ibm),
Iconomi(R.drawable.thumb_iconomi), Iconomi(R.drawable.thumb_iconomi),
IFTTT(R.drawable.thumb_ifttt), IFTTT(R.drawable.thumb_ifttt),
Instagram(R.drawable.thumb_instagram), Instagram(R.drawable.thumb_instagram),
@ -127,6 +132,7 @@ public class EntryThumbnail {
Kraken(R.drawable.thumb_kraken), Kraken(R.drawable.thumb_kraken),
Kucoin(R.drawable.thumb_kucoin), Kucoin(R.drawable.thumb_kucoin),
LastPass(R.drawable.thumb_lastpass), LastPass(R.drawable.thumb_lastpass),
LibreNMS(R.drawable.thumb_librenms),
Lichess(R.drawable.thumb_lichess), Lichess(R.drawable.thumb_lichess),
LinkedIn(R.drawable.thumb_linkedin), LinkedIn(R.drawable.thumb_linkedin),
Linode(R.drawable.thumb_linode), Linode(R.drawable.thumb_linode),
@ -158,6 +164,7 @@ public class EntryThumbnail {
Okta(R.drawable.thumb_okta), Okta(R.drawable.thumb_okta),
OnlineNet(R.drawable.thumb_online), OnlineNet(R.drawable.thumb_online),
OpenVZ(R.drawable.thumb_openvz), OpenVZ(R.drawable.thumb_openvz),
OPNsense(R.drawable.thumb_opnsense),
Origin(R.drawable.thumb_origin), Origin(R.drawable.thumb_origin),
OVH(R.drawable.thumb_ovh), OVH(R.drawable.thumb_ovh),
Packet(R.drawable.thumb_packet), Packet(R.drawable.thumb_packet),
@ -170,6 +177,7 @@ public class EntryThumbnail {
phpMyAdmin(R.drawable.thumb_phpmyadmin), phpMyAdmin(R.drawable.thumb_phpmyadmin),
Plurk(R.drawable.thumb_plurk), Plurk(R.drawable.thumb_plurk),
Posteo(R.drawable.thumb_posteo), Posteo(R.drawable.thumb_posteo),
PrivateInternetAccess(R.drawable.thumb_private_internet_access),
ProtonMail(R.drawable.thumb_protonmail), ProtonMail(R.drawable.thumb_protonmail),
Proxmox(R.drawable.thumb_proxmox), Proxmox(R.drawable.thumb_proxmox),
PyPI(R.drawable.thumb_pypi), PyPI(R.drawable.thumb_pypi),
@ -239,14 +247,21 @@ public class EntryThumbnail {
public AssetType getAssetType() { public AssetType getAssetType() {
return assetType; return assetType;
} }
public static EntryThumbnails valueOfIgnoreCase(String thumbnail) {
for (EntryThumbnails entryThumbnails : values())
if (entryThumbnails.name().equalsIgnoreCase(thumbnail)) return entryThumbnails;
throw new IllegalArgumentException();
}
} }
public static Bitmap getThumbnailGraphic(Context context, String label, int size, EntryThumbnails thumbnail) { public static Bitmap getThumbnailGraphic(Context context, String issuer, String label, int size, EntryThumbnails thumbnail) {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
if (thumbnail == EntryThumbnails.Default && size > 0) { if (thumbnail == EntryThumbnails.Default && size > 0) {
LetterBitmap letterBitmap = new LetterBitmap(context); LetterBitmap letterBitmap = new LetterBitmap(context);
return letterBitmap.getLetterTile(label, label, size, size); String letterSrc = issuer.isEmpty() ? label : issuer;
return letterBitmap.getLetterTile(letterSrc, letterSrc, size, size);
} else if (thumbnail != EntryThumbnails.Default) { } else if (thumbnail != EntryThumbnails.Default) {
try { try {

View file

@ -27,13 +27,13 @@ import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.text.TextPaint; import android.text.TextPaint;
import android.util.TypedValue;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
@ -76,11 +76,7 @@ class LetterBitmap {
/** /**
* The font size used to display the letter * The font size used to display the letter
*/ */
private final int mTileLetterFontSize; private final float mTileLetterFontSizeScale;
/**
* The default image to display
*/
private final Bitmap mDefaultBitmap;
/** /**
* Constructor for <code>LetterTileProvider</code> * Constructor for <code>LetterTileProvider</code>
@ -96,9 +92,10 @@ class LetterBitmap {
mPaint.setAntiAlias(true); mPaint.setAntiAlias(true);
mColors = res.obtainTypedArray(R.array.letter_tile_colors); mColors = res.obtainTypedArray(R.array.letter_tile_colors);
mTileLetterFontSize = res.getDimensionPixelSize(R.dimen.tile_letter_font_size);
mDefaultBitmap = BitmapFactory.decodeResource(res, android.R.drawable.sym_def_app_icon); TypedValue typedValue = new TypedValue();
res.getValue(R.dimen.tile_letter_font_size_scale, typedValue, true);
mTileLetterFontSizeScale = typedValue.getFloat();
} }
/** /**
@ -123,7 +120,7 @@ class LetterBitmap {
c.drawColor(pickColor(key)); c.drawColor(pickColor(key));
mFirstChar[0] = Character.toUpperCase(firstChar); mFirstChar[0] = Character.toUpperCase(firstChar);
mPaint.setTextSize(mTileLetterFontSize); mPaint.setTextSize(mTileLetterFontSizeScale * height);
mPaint.getTextBounds(mFirstChar, 0, 1, mBounds); mPaint.getTextBounds(mFirstChar, 0, 1, mBounds);
c.drawText(mFirstChar, 0, 1, width / 2, height / 2 c.drawText(mFirstChar, 0, 1, width / 2, height / 2
+ (mBounds.bottom - mBounds.top) / 2, mPaint); + (mBounds.bottom - mBounds.top) / 2, mPaint);

View file

@ -27,7 +27,7 @@ import android.app.NotificationChannel;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.support.v4.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;

View file

@ -0,0 +1,65 @@
package org.shadowice.flocke.andotp.Utilities;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.widget.Toast;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import org.shadowice.flocke.andotp.R;
import java.io.IOException;
public class ScanQRCodeFromFile {
public static String scanQRImage(Context context, Uri uri) {
//Check if external storage is accessible
if (!Tools.isExternalStorageReadable()) {
Toast.makeText(context, R.string.backup_toast_storage_not_accessible, Toast.LENGTH_LONG).show();
return null;
}
//Get image in bytes
byte[] imageInBytes;
try {
imageInBytes = StorageAccessHelper.loadFile(context,uri);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context,R.string.toast_file_load_error,Toast.LENGTH_LONG).show();
return null;
}
Bitmap bMap = BitmapFactory.decodeByteArray(imageInBytes,0,imageInBytes.length);
String contents = null;
int[] intArray = new int[bMap.getWidth()*bMap.getHeight()];
bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight());
LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
//Try finding QR code
try {
Result result = reader.decode(bitmap);
contents = result.getText();
} catch (NotFoundException e) {
e.printStackTrace();
Toast.makeText(context,R.string.toast_qr_error,Toast.LENGTH_LONG).show();
} catch (ChecksumException e) {
e.printStackTrace();
Toast.makeText(context,R.string.toast_qr_checksum_exception,Toast.LENGTH_LONG).show();
} catch (FormatException e) {
e.printStackTrace();
Toast.makeText(context,R.string.toast_qr_format_error,Toast.LENGTH_LONG).show();
}
//Return QR code (if found)
return contents;
}
}

View file

@ -34,6 +34,7 @@ import java.nio.charset.StandardCharsets;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -216,12 +217,12 @@ public class Settings {
} }
public AuthMethod getAuthMethod() { public AuthMethod getAuthMethod() {
String authString = getString(R.string.settings_key_auth, CredentialsPreference.DEFAULT_VALUE.name().toLowerCase()); String authString = getString(R.string.settings_key_auth, CredentialsPreference.DEFAULT_VALUE.name().toLowerCase(Locale.ENGLISH));
return AuthMethod.valueOf(authString.toUpperCase()); return AuthMethod.valueOf(authString.toUpperCase(Locale.ENGLISH));
} }
public void setAuthMethod(AuthMethod authMethod) { public void setAuthMethod(AuthMethod authMethod) {
setString(R.string.settings_key_auth, authMethod.name().toLowerCase()); setString(R.string.settings_key_auth, authMethod.name().toLowerCase(Locale.ENGLISH));
} }
public void removeAuthPasswordHash() { public void removeAuthPasswordHash() {
@ -310,6 +311,10 @@ public class Settings {
return getBoolean(R.string.settings_key_relock_screen_off, true); return getBoolean(R.string.settings_key_relock_screen_off, true);
} }
public boolean getBlockAccessibility() {
return getBoolean(R.string.settings_key_block_accessibility, false);
}
public void setLocale(String locale) { public void setLocale(String locale) {
setString(R.string.settings_key_locale, locale); setString(R.string.settings_key_locale, locale);
} }
@ -379,6 +384,23 @@ public class Settings {
setString(R.string.settings_key_sort_mode, value.toString()); setString(R.string.settings_key_sort_mode, value.toString());
} }
public List<Constants.SearchIncludes> getSearchValues() {
Set<String> stringValues = settings.getStringSet(getResString(R.string.settings_key_search_includes), new HashSet<>(Arrays.asList(context.getResources().getStringArray(R.array.settings_defaults_search_includes))));
List<Constants.SearchIncludes> values = new ArrayList<>();
for (String value : stringValues) {
values.add(Constants.SearchIncludes.valueOf(value.toUpperCase(Locale.ENGLISH)));
}
return values;
}
public Constants.CardLayouts getCardLayout() {
String stringValue = getString(R.string.settings_key_card_layout, R.string.settings_default_card_layout);
return Constants.CardLayouts.valueOf(stringValue.toUpperCase(Locale.ENGLISH));
}
public boolean getBackupAsk() { public boolean getBackupAsk() {
return getBoolean(R.string.settings_key_backup_ask, true); return getBoolean(R.string.settings_key_backup_ask, true);
} }
@ -532,4 +554,25 @@ public class Settings {
public boolean getAuthInactivity() { public boolean getAuthInactivity() {
return getBoolean(R.string.settings_key_auth_inactivity, false); return getBoolean(R.string.settings_key_auth_inactivity, false);
} }
public boolean isMinimizeAppOnCopyEnabled() {
return getBoolean(R.string.settings_key_minimize_on_copy, false);
}
private Constants.AutoBackup getAutoBackupEncryptedSetting() {
String stringValue = getString(R.string.settings_key_auto_backup_password_enc, R.string.settings_default_auto_backup_password_enc);
return Constants.AutoBackup.valueOf(stringValue.toUpperCase(Locale.ENGLISH));
}
public boolean getAutoBackupEncryptedPasswordsEnabled() {
return getAutoBackupEncryptedSetting() != Constants.AutoBackup.OFF;
}
public boolean getAutoBackupEncryptedFullEnabled() {
return getAutoBackupEncryptedSetting() == Constants.AutoBackup.ALL_EDITS;
}
public boolean isHighlightTokenOptionEnabled() {
return getBoolean(R.string.settings_key_label_highlight_token,true);
}
} }

View file

@ -27,10 +27,11 @@ import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.v7.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.text.Editable; import android.text.Editable;
import android.text.InputType; import android.text.InputType;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -48,10 +49,14 @@ import android.widget.GridView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Toast; import android.widget.Toast;
import org.shadowice.flocke.andotp.Activities.MainActivity;
import org.shadowice.flocke.andotp.Database.Entry; import org.shadowice.flocke.andotp.Database.Entry;
import org.shadowice.flocke.andotp.Dialogs.TagsDialog;
import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.R;
import org.shadowice.flocke.andotp.Utilities.BackupHelper;
import org.shadowice.flocke.andotp.Utilities.Constants; import org.shadowice.flocke.andotp.Utilities.Constants;
import org.shadowice.flocke.andotp.Utilities.DatabaseHelper; import org.shadowice.flocke.andotp.Utilities.DatabaseHelper;
import org.shadowice.flocke.andotp.Utilities.EncryptionHelper;
import org.shadowice.flocke.andotp.Utilities.EntryThumbnail; import org.shadowice.flocke.andotp.Utilities.EntryThumbnail;
import org.shadowice.flocke.andotp.Utilities.Settings; import org.shadowice.flocke.andotp.Utilities.Settings;
import org.shadowice.flocke.andotp.Utilities.Tools; import org.shadowice.flocke.andotp.Utilities.Tools;
@ -116,6 +121,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
if (! entries.contains(e)) { if (! entries.contains(e)) {
entries.add(e); entries.add(e);
entriesChanged(); entriesChanged();
saveEntries(settings.getAutoBackupEncryptedPasswordsEnabled());
} else { } else {
Toast.makeText(context, R.string.toast_entry_exists, Toast.LENGTH_LONG).show(); Toast.makeText(context, R.string.toast_entry_exists, Toast.LENGTH_LONG).show();
} }
@ -131,8 +137,25 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void saveEntries() { public void saveEntries(boolean auto_backup) {
DatabaseHelper.saveDatabase(context, entries, encryptionKey); DatabaseHelper.saveDatabase(context, entries, encryptionKey);
if(auto_backup) {
Constants.BackupType backupType = BackupHelper.autoBackupType(context);
if (backupType == Constants.BackupType.ENCRYPTED) {
Uri backupFilename = Tools.buildUri(settings.getBackupDir(), BackupHelper.backupFilename(context, Constants.BackupType.ENCRYPTED));
byte[] keyMaterial = encryptionKey.getEncoded();
SecretKey encryptionKey = EncryptionHelper.generateSymmetricKey(keyMaterial);
boolean success = BackupHelper.backupToFile(context, backupFilename, settings.getBackupPasswordEnc(), encryptionKey);
if (success) {
Toast.makeText(context, R.string.backup_toast_export_success, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, R.string.backup_toast_export_failed, Toast.LENGTH_LONG).show();
}
}
}
} }
public void loadEntries() { public void loadEntries() {
@ -177,7 +200,14 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
for (Entry e : entries) { for (Entry e : entries) {
if (e.isTimeBased()) { if (e.isTimeBased()) {
boolean item_changed = e.updateOTP(); boolean item_changed = e.updateOTP();
change = change || item_changed || e.hasNonDefaultPeriod(); boolean color_changed = false;
//Check color change only if highlighting token feature is enabled
if(settings.isHighlightTokenOptionEnabled()) {
color_changed = e.hasColorChanged();
}
change = change || item_changed || e.hasNonDefaultPeriod() || color_changed;
} }
} }
@ -192,6 +222,9 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
if (!entry.isTimeBased()) if (!entry.isTimeBased())
entry.updateOTP(); entry.updateOTP();
if(settings.isHighlightTokenOptionEnabled())
entryViewHolder.updateColor(entry.getColor());
entryViewHolder.updateValues(entry); entryViewHolder.updateValues(entry);
entryViewHolder.setLabelSize(settings.getLabelSize()); entryViewHolder.setLabelSize(settings.getLabelSize());
@ -203,7 +236,17 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
@Override @NonNull @Override @NonNull
public EntryViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { public EntryViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.component_card, viewGroup, false); int cardLayout = R.layout.component_card_default;
Constants.CardLayouts layout = settings.getCardLayout();
if (layout == Constants.CardLayouts.DEFAULT) {
cardLayout = R.layout.component_card_default;
} else if (layout == Constants.CardLayouts.FULL) {
cardLayout = R.layout.component_card_full;
}
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(cardLayout, viewGroup, false);
EntryViewHolder viewHolder = new EntryViewHolder(context, itemView, settings.getTapToReveal()); EntryViewHolder viewHolder = new EntryViewHolder(context, itemView, settings.getTapToReveal());
viewHolder.setCallback(new EntryViewHolder.Callback() { viewHolder.setCallback(new EntryViewHolder.Callback() {
@ -228,6 +271,9 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
public void onCopyButtonClicked(String text, int position) { public void onCopyButtonClicked(String text, int position) {
copyToClipboard(text); copyToClipboard(text);
updateLastUsed(position, getRealIndex(position)); updateLastUsed(position, getRealIndex(position));
if(context != null && settings.isMinimizeAppOnCopyEnabled()) {
((MainActivity)context).moveTaskToBack(true);
}
} }
@Override @Override
@ -247,6 +293,9 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
}); });
taskHandler.postDelayed(entries.get(realIndex).getHideTask(), settings.getTapToRevealTimeout() * 1000); taskHandler.postDelayed(entries.get(realIndex).getHideTask(), settings.getTapToRevealTimeout() * 1000);
if (entry.isCounterBased()) {
updateEntry(entry, entries.get(realIndex), position);
}
entry.setVisible(true); entry.setVisible(true);
notifyItemChanged(position); notifyItemChanged(position);
} }
@ -255,18 +304,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
@Override @Override
public void onCounterClicked(int position) { public void onCounterClicked(int position) {
Entry entry = displayedEntries.get(position); updateEntry(displayedEntries.get(position), entries.get(getRealIndex(position)), position);
Entry realEntry = entries.get(getRealIndex(position));
long counter = entry.getCounter() + 1;
entry.setCounter(counter);
entry.updateOTP();
notifyItemChanged(position);
realEntry.setCounter(counter);
realEntry.updateOTP();
DatabaseHelper.saveDatabase(context, entries, encryptionKey);
} }
@Override @Override
@ -278,6 +316,19 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
return viewHolder; return viewHolder;
} }
private void updateEntry(Entry entry, Entry realEntry, final int position) {
long counter = entry.getCounter() + 1;
entry.setCounter(counter);
entry.updateOTP();
notifyItemChanged(position);
realEntry.setCounter(counter);
realEntry.updateOTP();
saveEntries(settings.getAutoBackupEncryptedFullEnabled());
}
private void hideEntry(Entry entry) { private void hideEntry(Entry entry) {
int pos = displayedEntries.indexOf(entry); int pos = displayedEntries.indexOf(entry);
int realIndex = entries.indexOf(entry); int realIndex = entries.indexOf(entry);
@ -328,7 +379,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
Entry e = entries.get(realIndex); Entry e = entries.get(realIndex);
e.setCounter(newCounter); e.setCounter(newCounter);
DatabaseHelper.saveDatabase(context, entries, encryptionKey); saveEntries(settings.getAutoBackupEncryptedFullEnabled());
} }
}) })
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@ -346,7 +397,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
displayedEntries.get(position).setLastUsed(timeStamp); displayedEntries.get(position).setLastUsed(timeStamp);
entries.get(realIndex).setLastUsed(timeStamp); entries.get(realIndex).setLastUsed(timeStamp);
DatabaseHelper.saveDatabase(context, entries, encryptionKey); saveEntries(settings.getAutoBackupEncryptedFullEnabled());
if (sortMode == SortMode.LAST_USED) { if (sortMode == SortMode.LAST_USED) {
displayedEntries = sortEntries(displayedEntries); displayedEntries = sortEntries(displayedEntries);
@ -365,12 +416,57 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
displayedEntries = new ArrayList<>(entries); displayedEntries = new ArrayList<>(entries);
notifyItemMoved(fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition);
DatabaseHelper.saveDatabase(context, entries, encryptionKey); saveEntries(settings.getAutoBackupEncryptedFullEnabled());
} }
return true; return true;
} }
public void editEntryIssuer(final int pos) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
int marginSmall = context.getResources().getDimensionPixelSize(R.dimen.activity_margin_small);
int marginMedium = context.getResources().getDimensionPixelSize(R.dimen.activity_margin_medium);
final EditText input = new EditText(context);
input.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
input.setText(displayedEntries.get(pos).getIssuer());
input.setSingleLine();
FrameLayout container = new FrameLayout(context);
container.setPaddingRelative(marginMedium, marginSmall, marginMedium, 0);
container.addView(input);
builder.setTitle(R.string.dialog_title_rename)
.setView(container)
.setPositiveButton(R.string.button_save, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
int realIndex = getRealIndex(pos);
String newIssuer = input.getEditableText().toString();
displayedEntries.get(pos).setIssuer(newIssuer);
if (sortMode == SortMode.LABEL) {
displayedEntries = sortEntries(displayedEntries);
notifyDataSetChanged();
} else {
notifyItemChanged(pos);
}
Entry e = entries.get(realIndex);
e.setIssuer(newIssuer);
DatabaseHelper.saveDatabase(context, entries, encryptionKey);
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {}
})
.create()
.show();
}
public void editEntryLabel(final int pos) { public void editEntryLabel(final int pos) {
AlertDialog.Builder builder = new AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
@ -405,7 +501,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
Entry e = entries.get(realIndex); Entry e = entries.get(realIndex);
e.setLabel(newLabel); e.setLabel(newLabel);
DatabaseHelper.saveDatabase(context, entries, encryptionKey); saveEntries(settings.getAutoBackupEncryptedFullEnabled());
} }
}) })
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@ -423,7 +519,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
int marginMedium = context.getResources().getDimensionPixelSize(R.dimen.activity_margin_medium); int marginMedium = context.getResources().getDimensionPixelSize(R.dimen.activity_margin_medium);
int realIndex = getRealIndex(pos); int realIndex = getRealIndex(pos);
final ThumbnailSelectionAdapter thumbnailAdapter = new ThumbnailSelectionAdapter(context, entries.get(realIndex).getLabel()); final ThumbnailSelectionAdapter thumbnailAdapter = new ThumbnailSelectionAdapter(context, entries.get(realIndex).getIssuer(), entries.get(realIndex).getLabel());
final EditText input = new EditText(context); final EditText input = new EditText(context);
input.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); input.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
@ -491,7 +587,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
Entry e = entries.get(realIndex); Entry e = entries.get(realIndex);
e.setThumbnail(thumbnail); e.setThumbnail(thumbnail);
DatabaseHelper.saveDatabase(context, entries, encryptionKey); saveEntries(settings.getAutoBackupEncryptedFullEnabled());
notifyItemChanged(pos); notifyItemChanged(pos);
alert.cancel(); alert.cancel();
} }
@ -519,7 +615,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
@Override @Override
public Object call() throws Exception { public Object call() throws Exception {
entries.get(realPos).setTags(tagsAdapter.getActiveTags()); entries.get(realPos).setTags(tagsAdapter.getActiveTags());
DatabaseHelper.saveDatabase(context, entries, encryptionKey); saveEntries(settings.getAutoBackupEncryptedFullEnabled());
List<String> inUseTags = getTags(); List<String> inUseTags = getTags();
@ -564,7 +660,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
notifyItemRemoved(pos); notifyItemRemoved(pos);
entries.remove(realIndex); entries.remove(realIndex);
DatabaseHelper.saveDatabase(context, entries, encryptionKey); saveEntries(settings.getAutoBackupEncryptedFullEnabled());
} }
}) })
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
@ -585,7 +681,10 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
int id = item.getItemId(); int id = item.getItemId();
if (id == R.id.menu_popup_editLabel) { if (id == R.id.menu_popup_editIssuer) {
editEntryIssuer(pos);
return true;
} else if (id == R.id.menu_popup_editLabel) {
editEntryLabel(pos); editEntryLabel(pos);
return true; return true;
} else if(id == R.id.menu_popup_changeImage) { } else if(id == R.id.menu_popup_changeImage) {
@ -645,6 +744,11 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
return filter; return filter;
} }
public void clearFilter() {
if (filter != null)
filter = null;
}
public List<String> getTags() { public List<String> getTags() {
HashSet<String> tags = new HashSet<String>(); HashSet<String> tags = new HashSet<String>();
@ -656,15 +760,28 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
} }
public class EntryFilter extends Filter { public class EntryFilter extends Filter {
private List<Constants.SearchIncludes> filterValues = settings.getSearchValues();
@Override @Override
protected FilterResults performFiltering(CharSequence constraint) { protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults filterResults = new FilterResults(); final FilterResults filterResults = new FilterResults();
ArrayList<Entry> filtered = new ArrayList<>(); ArrayList<Entry> filtered = new ArrayList<>();
if (constraint != null && constraint.length() != 0){ if (constraint != null && constraint.length() != 0){
for (int i = 0; i < entries.size(); i++) { for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).getLabel().toLowerCase().contains(constraint.toString().toLowerCase())) { if (filterValues.contains(Constants.SearchIncludes.LABEL) && entries.get(i).getLabel().toLowerCase().contains(constraint.toString().toLowerCase())) {
filtered.add(entries.get(i)); filtered.add(entries.get(i));
} else if (filterValues.contains(Constants.SearchIncludes.ISSUER) && entries.get(i).getIssuer().toLowerCase().contains(constraint.toString().toLowerCase())) {
filtered.add(entries.get(i));
} else if (filterValues.contains(Constants.SearchIncludes.TAGS)) {
List<String> tags = entries.get(i).getTags();
for (int j = 0; j < tags.size(); j++) {
if (tags.get(j).toLowerCase().contains(constraint.toString().toLowerCase())) {
filtered.add(entries.get(i));
break;
}
}
} }
} }
} else { } else {

View file

@ -25,8 +25,8 @@ package org.shadowice.flocke.andotp.View;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.support.v7.widget.CardView; import androidx.cardview.widget.CardView;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.animation.LinearInterpolator; import android.view.animation.LinearInterpolator;
@ -64,7 +64,9 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
private ImageView visibleImg; private ImageView visibleImg;
private ImageView thumbnailImg; private ImageView thumbnailImg;
private TextView value; private TextView value;
private TextView issuer;
private TextView label; private TextView label;
private TextView separator;
private TextView counter; private TextView counter;
private TextView tags; private TextView tags;
private MaterialProgressBar progressBar; private MaterialProgressBar progressBar;
@ -81,7 +83,9 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
thumbnailFrame = v.findViewById(R.id.thumbnailFrame); thumbnailFrame = v.findViewById(R.id.thumbnailFrame);
thumbnailImg = v.findViewById(R.id.thumbnailImg); thumbnailImg = v.findViewById(R.id.thumbnailImg);
coverLayout = v.findViewById(R.id.coverLayout); coverLayout = v.findViewById(R.id.coverLayout);
issuer = v.findViewById(R.id.textViewIssuer);
label = v.findViewById(R.id.textViewLabel); label = v.findViewById(R.id.textViewLabel);
separator = v.findViewById(R.id.textViewSeparator);
tags = v.findViewById(R.id.textViewTags); tags = v.findViewById(R.id.textViewTags);
counterLayout = v.findViewById(R.id.counterLayout); counterLayout = v.findViewById(R.id.counterLayout);
counter = v.findViewById(R.id.counter); counter = v.findViewById(R.id.counter);
@ -149,7 +153,28 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
final String tokenFormatted = Tools.formatToken(entry.getCurrentOTP(), settings.getTokenSplitGroupSize()); final String tokenFormatted = Tools.formatToken(entry.getCurrentOTP(), settings.getTokenSplitGroupSize());
label.setText(entry.getLabel()); String issuerText = entry.getIssuer();
if (!TextUtils.isEmpty(issuerText)) {
issuer.setText(entry.getIssuer());
issuer.setVisibility(View.VISIBLE);
} else {
issuer.setVisibility(View.GONE);
}
String labelText = entry.getLabel();
if (!TextUtils.isEmpty(labelText)) {
label.setText(entry.getLabel());
label.setVisibility(View.VISIBLE);
} else {
label.setVisibility(View.GONE);
}
if (! issuerText.isEmpty() && ! labelText.isEmpty()) {
separator.setVisibility(View.VISIBLE);
} else {
separator.setVisibility(View.GONE);
}
value.setText(tokenFormatted); value.setText(tokenFormatted);
// save the unformatted token to the tag of this TextView for copy/paste // save the unformatted token to the tag of this TextView for copy/paste
value.setTag(entry.getCurrentOTP()); value.setTag(entry.getCurrentOTP());
@ -170,7 +195,7 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
int thumbnailSize = settings.getThumbnailSize(); int thumbnailSize = settings.getThumbnailSize();
if(settings.getThumbnailVisible()) { if(settings.getThumbnailVisible()) {
thumbnailImg.setImageBitmap(EntryThumbnail.getThumbnailGraphic(context, entry.getLabel(), thumbnailSize, entry.getThumbnail())); thumbnailImg.setImageBitmap(EntryThumbnail.getThumbnailGraphic(context, entry.getIssuer(), entry.getLabel(), thumbnailSize, entry.getThumbnail()));
} }
if (entry.isTimeBased() && entry.hasNonDefaultPeriod()) { if (entry.isTimeBased() && entry.hasNonDefaultPeriod()) {
@ -279,4 +304,19 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
void onCounterClicked(int position); void onCounterClicked(int position);
void onCounterLongPressed(int position); void onCounterLongPressed(int position);
} }
/**
* Updates the color of OTP to red (if expiring) or default color (if new OTP)
*
* @param color will define if the color needs to be changed to red or default
* */
public void updateColor(int color) {
int textColor;
if(color == Entry.COLOR_RED) {
textColor = Tools.getThemeColor(context, R.attr.colorExpiring);
} else {
textColor = Tools.getThemeColor(context, android.R.attr.textColorSecondary);
}
value.setTextColor(textColor);
}
} }

View file

@ -16,8 +16,8 @@
package org.shadowice.flocke.andotp.View.ItemTouchHelper; package org.shadowice.flocke.andotp.View.ItemTouchHelper;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
/** /**
* Interface to listen for a move or dismissal event from a {@link ItemTouchHelper.Callback}. * Interface to listen for a move or dismissal event from a {@link ItemTouchHelper.Callback}.

View file

@ -16,11 +16,11 @@
package org.shadowice.flocke.andotp.View.ItemTouchHelper; package org.shadowice.flocke.andotp.View.ItemTouchHelper;
import android.support.v7.widget.helper.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
/** /**
* Interface to notify an item ViewHolder of relevant callbacks from {@link * Interface to notify an item ViewHolder of relevant callbacks from {@link
* android.support.v7.widget.helper.ItemTouchHelper.Callback}. * androidx.recyclerview.widget.ItemTouchHelper.Callback}.
* *
* @author Paul Burke (ipaulpro) * @author Paul Burke (ipaulpro)
*/ */

View file

@ -17,9 +17,9 @@
package org.shadowice.flocke.andotp.View.ItemTouchHelper; package org.shadowice.flocke.andotp.View.ItemTouchHelper;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.support.v7.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
/** /**
* An implementation of {@link ItemTouchHelper.Callback} that enables basic drag & drop and * An implementation of {@link ItemTouchHelper.Callback} that enables basic drag & drop and

View file

@ -24,7 +24,7 @@
package org.shadowice.flocke.andotp.View; package org.shadowice.flocke.andotp.View;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;

View file

@ -24,7 +24,7 @@
package org.shadowice.flocke.andotp.View; package org.shadowice.flocke.andotp.View;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
@ -41,12 +41,14 @@ import java.util.List;
public class ThumbnailSelectionAdapter extends BaseAdapter { public class ThumbnailSelectionAdapter extends BaseAdapter {
private Context context; private Context context;
private List items; private List items;
private String issuer = "Example";
private String label = "Example"; private String label = "Example";
private Settings settings; private Settings settings;
ThumbnailSelectionAdapter(Context context, String label) { ThumbnailSelectionAdapter(Context context, String issuer, String label) {
items = new ArrayList(EntryThumbnail.EntryThumbnails.values().length); items = new ArrayList(EntryThumbnail.EntryThumbnails.values().length);
Collections.addAll(items, EntryThumbnail.EntryThumbnails.values()); Collections.addAll(items, EntryThumbnail.EntryThumbnails.values());
this.issuer = issuer;
this.label = label; this.label = label;
this.context = context; this.context = context;
settings = new Settings(context); settings = new Settings(context);
@ -98,7 +100,7 @@ public class ThumbnailSelectionAdapter extends BaseAdapter {
EntryThumbnail.EntryThumbnails thumb = (EntryThumbnail.EntryThumbnails)getItem(i); EntryThumbnail.EntryThumbnails thumb = (EntryThumbnail.EntryThumbnails)getItem(i);
imageView.setImageBitmap(EntryThumbnail.getThumbnailGraphic(context, label, thumbnailSize, thumb)); imageView.setImageBitmap(EntryThumbnail.getThumbnailGraphic(context, issuer, label, thumbnailSize, thumb));
return imageView; return imageView;
} }
} }

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF727272"
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF727272"
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#388E3C"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z" />
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0" >
<path
android:fillColor="#FFFFFFFF"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"/>
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF727272"
android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
</vector>

View file

@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="113.4dp"
android:height="113.4dp"
android:viewportWidth="113.4"
android:viewportHeight="113.4">
<path
android:pathData="M0,0V113.4H113.4V0ZM111.6,111.6H1.9V1.9h109.7z"
android:fillColor="#ffffff"/>
<path
android:pathData="M1.9,111.6H111.6V1.9H1.9ZM78.4,30.7H97V82.3H86.7V39H78.4ZM47.9,52.9c-4.7,-6 -5.6,-8 -5.6,-11.8 0,-6.4 5.4,-11 13.1,-11 7.1,0 12.2,4.8 12.2,11.3 0,4.8 -2,8.3 -8,13.3l8.9,12.1c0.7,-0.7 1.4,-4.8 1.3,-8.1 0,-0.4 -0.1,-1.6 -0.2,-2.8h8.3c0,1.1 0.1,2.7 0.1,3.1 0,6.5 -1,10.6 -4.2,14.6l6.6,8.7H70.3L68,79.2c-3.8,3 -7.1,4.1 -12.4,4.1C45.2,83.2 38,77.9 37.3,68.5 36.9,62.9 40.7,57 47.9,52.9ZM12.4,30.7H31V82.3H20.7V39h-8.3z"
android:fillColor="#164194"/>
<path
android:pathData="m55.6,75.2c3.2,0 5.4,-1.2 7.2,-2.7L53,59.5c-4.6,3 -6.4,6 -6.3,8.8 0.1,4.2 3.7,6.9 8.9,6.9zM59.6,41.3c0,-2.3 -1.6,-3.8 -4.2,-3.8 -2.5,0 -4.3,1.6 -4.3,3.9 0,2.1 0.6,3.3 3.6,7.1 3.6,-2.6 4.9,-4.9 4.9,-7.2z"
android:fillColor="#164194"/>
<path
android:pathData="M86.7,82.3L97,82.3L97,30.7L78.4,30.7L78.4,39h8.3zM55.6,83.3c5.3,0 8.6,-1.1 12.4,-4.1l2.3,3.1L80.5,82.3L73.9,73.6C77,69.6 78.1,65.5 78.1,59 78.1,58.6 78,57 78,55.9h-8.3c0.1,1.3 0.2,2.4 0.2,2.8 0.1,3.3 -0.5,7.4 -1.3,8.1L59.7,54.7c6,-5 8,-8.6 8,-13.3 0,-6.5 -5.1,-11.3 -12.2,-11.3 -7.7,0 -13.1,4.7 -13.1,11 0,3.7 1,5.8 5.6,11.8 -7.2,4.2 -11,10 -10.6,15.6 0.6,9.4 7.8,14.7 18.2,14.8zM55.4,37.5c2.6,0 4.2,1.5 4.2,3.8 0,2.3 -1.3,4.7 -4.8,7.2 -3,-3.8 -3.6,-5 -3.6,-7.1 -0.1,-2.3 1.7,-3.9 4.2,-3.9zM53,59.5 L62.8,72.5c-1.9,1.5 -4,2.7 -7.2,2.7 -5.2,0 -8.8,-2.7 -8.9,-7 -0.1,-2.7 1.8,-5.7 6.3,-8.7zM20.6,82.3L31,82.3L31,30.7L12.4,30.7L12.4,39h8.2z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="80dp"
android:viewportWidth="312.41"
android:viewportHeight="195.69">
<path
android:pathData="m107.52,0h118.16a7.78,7.78 0,0 1,-1.55 4.32c-4,6.86 -7.6,14 -11.53,20.86 -5.6,9.82 -10.76,19.88 -16.41,29.69 -3.58,7.06 -7.62,13.9 -11.44,20.84h-68.88c-1.2,0 -2.39,0.06 -3.59,0.13 -1,2.64 -2.66,5 -4,7.43 -1.75,2.84 -3.17,5.87 -4.9,8.71 -1.83,3.82 -4.36,7.24 -6.2,11 -3.8,6.45 -7.35,13 -11.07,19.52q-5.82,10 -11.38,20.28c-1.57,2.43 -3,4.94 -4.33,7.51 -7.77,13.57 -15.29,27.21 -23.07,40.71a16.39,16.39 0,0 1,-2.58 4c-13.3,-0.09 -26.6,0 -39.9,0a20.34,20.34 0,0 0,-4.85 0.68c0,-3.68 2.46,-6.62 4.12,-9.68 2,-4.15 4.67,-8 6.68,-12.16 15.94,-28.52 31.71,-57.14 47.6,-85.68 3.6,-6.2 6.69,-12.53 10.31,-18.61 4.52,-8 8.73,-16.18 13.44,-24.09 1.5,-3.31 3.52,-6.34 5.17,-9.57 5.86,-10.43 11.61,-20.92 17.45,-31.35a18.11,18.11 0,0 1,2.75 -4.54z"
android:fillColor="#eb4a60"/>
<path
android:pathData="m244.44,42c7.87,-13.75 15.47,-27.65 23.45,-41.34h42.68a8.82,8.82 0,0 1,1.84 0.29c-1.42,2.15 -2.61,4.43 -3.86,6.67q-15.44,27.71 -30.79,55.45c-4.3,7.53 -8.3,15.23 -12.66,22.72l-0.43,0.15 -0.08,0.94q-30.1,54 -60,108.08 -58.77,0.04 -117.59,0.04c2.23,-4.66 4.87,-9.11 7.35,-13.64 11.2,-20.57 22.65,-40.91 33.65,-61.43q36.1,-0.06 72.22,0c14.87,-25.93 29.42,-52 44.18,-77.93z"
android:fillColor="#595fb5"/>
</vector>

View file

@ -0,0 +1,181 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="76dp"
android:viewportWidth="270"
android:viewportHeight="160">
<path
android:pathData="m154.958,53.322h22.866v23.375h11.562c5.339,0 10.831,-0.951 15.887,-2.664 2.484,-0.842 5.273,-2.015 7.724,-3.489 -3.228,-4.214 -4.876,-9.536 -5.361,-14.781 -0.659,-7.134 0.78,-16.42 5.609,-22.004l2.404,-2.78 2.864,2.302c7.211,5.794 13.276,13.889 14.345,23.118 8.683,-2.554 18.878,-1.95 26.531,2.467l3.14,1.812 -1.653,3.226c-6.473,12.633 -20.005,16.547 -33.235,15.854 -19.797,49.308 -62.898,72.653 -115.157,72.653 -26.999,0 -51.77,-10.093 -65.876,-34.047 -0.827,-1.488 -1.535,-3.044 -2.286,-4.572 -4.768,-10.544 -6.352,-22.095 -5.277,-33.637l0.322,-3.457H58.92V53.322h22.866V30.456H127.518V7.59h27.44v45.732"
android:fillColor="#394d54"/>
<group>
<clip-path android:pathData="M83.471,9.59L83.471,55.59L61.471,55.59L61.471,78.59L43.051,78.59c-0.078,0.666 -0.141,1.333 -0.206,2 -1.151,12.531 1.036,24.088 6.063,33.969L50.596,117.59c1.011,1.817 2.191,3.523 3.438,5.188 1.245,1.662 1.686,2.583 2.469,3.688C69.791,141.401 89.6,148.59 112.471,148.59 163.119,148.59 206.104,126.152 225.127,75.746 238.624,77.131 251.57,73.67 257.471,62.152 248.072,56.729 235.992,58.467 229.033,61.965L247.471,9.59 175.471,55.59L152.471,55.59L152.471,9.59Z M 0,0"/>
<path
android:pathData="m131.33,-11.465h19.818L151.147,8.352h-19.818z"
android:fillColor="#00acd3"/>
<path
android:pathData="m131.33,11.4h19.818v19.818h-19.818z"
android:fillColor="#20c2ef"/>
<path
android:fillColor="#FF000000"
android:pathData="M133.763,6.701L133.763,-9.815M136.735,6.701L136.735,-9.815m3.002,16.516L139.737,-9.815m3.003,16.516L142.74,-9.815M145.743,6.701L145.743,-9.815m2.971,16.516L148.714,-9.815"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:fillColor="#FF000000"
android:pathData="M133.763,29.567L133.763,13.051M136.735,29.567L136.735,13.051m3.002,16.516L139.737,13.051m3.003,16.516L142.74,13.051M145.743,29.567L145.743,13.051m2.971,16.516L148.714,13.051"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:pathData="m154.196,31.217l19.818,-0L174.014,11.4l-19.818,-0z"
android:fillColor="#00acd3"/>
<path
android:pathData="m154.196,8.352l19.818,-0l0,-19.818l-19.818,-0z"
android:fillColor="#20c2ef"/>
<path
android:fillColor="#FF000000"
android:pathData="M156.629,13.051L156.629,29.567M159.601,13.051L159.601,29.567m3.002,-16.516L162.603,29.567m3.003,-16.516L165.606,29.567M168.609,13.051L168.609,29.567m2.971,-16.516L171.58,29.567"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:fillColor="#FF000000"
android:pathData="M156.629,-9.815L156.629,6.701M159.601,-9.815L159.601,6.701m3.002,-16.516L162.603,6.701m3.003,-16.516L165.606,6.701M168.609,-9.815L168.609,6.701m2.971,-16.516L171.58,6.701"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:pathData="m39.866,34.267h19.818L59.684,54.084h-19.818z"
android:fillColor="#00acd3"/>
<path
android:pathData="m39.866,57.132h19.818v19.818h-19.818z"
android:fillColor="#20c2ef"/>
<path
android:fillColor="#FF000000"
android:pathData="M42.299,52.433L42.299,35.917M45.271,52.433L45.271,35.917m3.002,16.516L48.273,35.917m3.003,16.516L51.276,35.917M54.279,52.433L54.279,35.917m2.971,16.516L57.25,35.917"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:fillColor="#FF000000"
android:pathData="M42.299,75.299L42.299,58.783M45.271,75.299L45.271,58.783m3.002,16.516L48.273,58.783m3.003,16.516L51.276,58.783M54.279,75.299L54.279,58.783m2.971,16.516L57.25,58.783"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:pathData="m62.732,76.949l19.818,-0L82.55,57.132l-19.818,-0z"
android:fillColor="#00acd3"/>
<path
android:pathData="m62.732,54.084l19.818,-0l0,-19.818l-19.818,-0z"
android:fillColor="#20c2ef"/>
<path
android:fillColor="#FF000000"
android:pathData="M65.165,58.783L65.165,75.299M68.137,58.783L68.137,75.299m3.002,-16.516L71.139,75.299m3.003,-16.516L74.142,75.299M77.145,58.783L77.145,75.299m2.971,-16.516L80.116,75.299"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:fillColor="#FF000000"
android:pathData="M65.165,35.917L65.165,52.433M68.137,35.917L68.137,52.433m3.002,-16.516L71.139,52.433m3.003,-16.516L74.142,52.433M77.145,35.917L77.145,52.433m2.971,-16.516L80.116,52.433"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:pathData="m85.598,34.267h19.818L105.416,54.084h-19.818z"
android:fillColor="#00acd3"/>
<path
android:pathData="m85.598,57.132h19.818v19.818h-19.818z"
android:fillColor="#20c2ef"/>
<path
android:fillColor="#FF000000"
android:pathData="M88.031,52.433L88.031,35.917M91.003,52.433L91.003,35.917m3.002,16.516L94.005,35.917m3.003,16.516L97.008,35.917M100.011,52.433L100.011,35.917m2.971,16.516L102.982,35.917"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:fillColor="#FF000000"
android:pathData="M88.031,75.299L88.031,58.783M91.003,75.299L91.003,58.783m3.002,16.516L94.005,58.783m3.003,16.516L97.008,58.783M100.011,75.299L100.011,58.783m2.971,16.516L102.982,58.783"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:pathData="m108.464,76.949l19.818,-0L128.282,57.132l-19.818,-0z"
android:fillColor="#00acd3"/>
<path
android:pathData="m108.464,54.084l19.818,-0l0,-19.818l-19.818,-0z"
android:fillColor="#20c2ef"/>
<path
android:fillColor="#FF000000"
android:pathData="M110.897,58.783L110.897,75.299M113.869,58.783L113.869,75.299m3.002,-16.516L116.871,75.299m3.003,-16.516L119.874,75.299M122.877,58.783L122.877,75.299m2.971,-16.516L125.848,75.299"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:fillColor="#FF000000"
android:pathData="M110.897,35.917L110.897,52.433M113.869,35.917L113.869,52.433m3.002,-16.516L116.871,52.433m3.003,-16.516L119.874,52.433M122.877,35.917L122.877,52.433m2.971,-16.516L125.848,52.433"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:pathData="m131.33,34.267h19.818L151.148,54.084h-19.818z"
android:fillColor="#00acd3"/>
<path
android:pathData="m131.33,57.132h19.818v19.818h-19.818z"
android:fillColor="#20c2ef"/>
<path
android:fillColor="#FF000000"
android:pathData="M133.763,52.433L133.763,35.917M136.735,52.433L136.735,35.917m3.002,16.516L139.737,35.917m3.003,16.516L142.74,35.917M145.743,52.433L145.743,35.917m2.971,16.516L148.714,35.917"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:fillColor="#FF000000"
android:pathData="M133.763,75.299L133.763,58.783M136.735,75.299L136.735,58.783m3.002,16.516L139.737,58.783m3.003,16.516L142.74,58.783M145.743,75.299L145.743,58.783m2.971,16.516L148.714,58.783"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:pathData="m154.196,76.949l19.818,-0L174.014,57.132l-19.818,-0z"
android:fillColor="#00acd3"/>
<path
android:pathData="m154.196,54.084l19.818,-0l0,-19.818l-19.818,-0z"
android:fillColor="#20c2ef"/>
<path
android:fillColor="#FF000000"
android:pathData="M156.629,58.783L156.629,75.299M159.601,58.783L159.601,75.299m3.002,-16.516L162.603,75.299m3.003,-16.516L165.606,75.299M168.609,58.783L168.609,75.299m2.971,-16.516L171.58,75.299"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
<path
android:fillColor="#FF000000"
android:pathData="M156.629,35.917L156.629,52.433M159.601,35.917L159.601,52.433m3.002,-16.516L162.603,52.433m3.003,-16.516L165.606,52.433M168.609,35.917L168.609,52.433m2.971,-16.516L171.58,52.433"
android:strokeWidth="1.55999994"
android:strokeColor="#394d54"/>
</group>
<group>
<clip-path android:pathData="M83.471,9.59L83.471,55.59L61.471,55.59L61.471,78.59L43.051,78.59c-0.078,0.666 -0.141,1.333 -0.206,2 -1.151,12.531 1.036,24.088 6.063,33.969L50.596,117.59c1.011,1.817 2.191,3.523 3.438,5.188 1.245,1.662 1.686,2.583 2.469,3.688C69.791,141.401 89.6,148.59 112.471,148.59 163.119,148.59 206.104,126.152 225.127,75.746 238.624,77.131 251.57,73.67 257.471,62.152 248.072,56.729 235.992,58.467 229.033,61.965L247.471,9.59 175.471,55.59L152.471,55.59L152.471,9.59Z M 0,0"/>
<path
android:pathData="m229.041,61.969c1.533,-11.915 -7.384,-21.275 -12.914,-25.718 -6.373,7.368 -7.363,26.678 2.635,34.807 -5.58,4.956 -17.337,9.448 -29.376,9.448L41.471,80.507C40.3,93.074 41.471,153.59 41.471,153.59h217l-0.987,-91.424c-9.399,-5.424 -21.484,-3.694 -28.443,-0.197"
android:fillColor="#17b5eb"/>
</group>
<group>
<clip-path android:pathData="M83.471,9.59L83.471,55.59L61.471,55.59L61.471,78.59L43.051,78.59c-0.078,0.666 -0.141,1.333 -0.206,2 -1.151,12.531 1.036,24.088 6.063,33.969L50.596,117.59c1.011,1.817 2.191,3.523 3.438,5.188 1.245,1.662 1.686,2.583 2.469,3.688C69.791,141.401 89.6,148.59 112.471,148.59 163.119,148.59 206.104,126.152 225.127,75.746 238.624,77.131 251.57,73.67 257.471,62.152 248.072,56.729 235.992,58.467 229.033,61.965L247.471,9.59 175.471,55.59L152.471,55.59L152.471,9.59Z M 0,0"/>
<path
android:fillColor="#FF000000"
android:pathData="m41.471,96.59v57L258.471,153.59L258.471,96.59"
android:fillAlpha="0.17000002"/>
</group>
<group>
<clip-path android:pathData="M83.471,9.59L83.471,55.59L61.471,55.59L61.471,78.59L43.051,78.59c-0.078,0.666 -0.141,1.333 -0.206,2 -1.151,12.531 1.036,24.088 6.063,33.969L50.596,117.59c1.011,1.817 2.191,3.523 3.438,5.188 1.245,1.662 1.686,2.583 2.469,3.688C69.791,141.401 89.6,148.59 112.471,148.59 163.119,148.59 206.104,126.152 225.127,75.746 238.624,77.131 251.57,73.67 257.471,62.152 248.072,56.729 235.992,58.467 229.033,61.965L247.471,9.59 175.471,55.59L152.471,55.59L152.471,9.59Z M 0,0"/>
<path
android:pathData="M118.708,148.48C105.168,142.055 97.736,133.321 93.601,123.785L52.471,125.59l21,28 45.237,-5.11"
android:fillColor="#d4edf1"/>
</group>
<group>
<clip-path android:pathData="M83.471,9.59L83.471,55.59L61.471,55.59L61.471,78.59L43.051,78.59c-0.078,0.666 -0.141,1.333 -0.206,2 -1.151,12.531 1.036,24.088 6.063,33.969L50.596,117.59c1.011,1.817 2.191,3.523 3.438,5.188 1.245,1.662 1.686,2.583 2.469,3.688C69.791,141.401 89.6,148.59 112.471,148.59 163.119,148.59 206.104,126.152 225.127,75.746 238.624,77.131 251.57,73.67 257.471,62.152 248.072,56.729 235.992,58.467 229.033,61.965L247.471,9.59 175.471,55.59L152.471,55.59L152.471,9.59Z M 0,0"/>
<path
android:fillColor="#FF000000"
android:pathData="m229.971,61.527v0.031c-20.861,26.889 -50.783,50.379 -82.906,62.719 -28.655,11.008 -53.638,11.06 -70.875,2.219 -1.856,-1.048 -3.676,-2.212 -5.5,-3.313C58.053,114.352 50.935,99.742 51.533,80.496L41.471,80.496L41.471,153.59L258.471,153.59L258.471,57.59h-25z"
android:fillAlpha="0.08500001"/>
</group>
<path
android:pathData="m53.096,124.621c14.165,0.775 29.282,0.914 42.469,-3.219"
android:strokeWidth="3.4000001"
android:fillColor="#00000000"
android:strokeColor="#394d54"
android:strokeLineCap="round"/>
<path
android:pathData="m109.641,114.549c0,3.019 -2.448,5.467 -5.467,5.467 -3.02,0 -5.468,-2.448 -5.468,-5.467 0,-3.019 2.448,-5.468 5.468,-5.468 3.019,0 5.467,2.449 5.467,5.468z"
android:fillColor="#d4edf1"/>
<path
android:pathData="m105.592,110.898c-0.477,0.276 -0.8,0.793 -0.8,1.384 0,0.883 0.716,1.597 1.598,1.597 0.605,0 1.13,-0.336 1.402,-0.832 0.192,0.462 0.298,0.97 0.298,1.502 0,2.162 -1.753,3.915 -3.916,3.915 -2.162,0 -3.916,-1.753 -3.916,-3.915 0,-2.163 1.754,-3.917 3.916,-3.917 0.5,0 0.977,0.094 1.418,0.265z"
android:fillColor="#394d54"/>
<path
android:pathData="M7.471,97.752H261.798c-5.538,-1.405 -17.521,-3.302 -15.545,-10.56 -10.069,11.652 -34.353,8.174 -40.481,2.429 -6.825,9.898 -46.555,6.136 -49.326,-1.575 -8.556,10.041 -35.067,10.041 -43.623,0 -2.772,7.711 -42.501,11.473 -49.327,1.575 -6.128,5.746 -30.41,9.223 -40.48,-2.429 1.976,7.257 -10.007,9.155 -15.546,10.56"
android:fillColor="#394d54"/>
</vector>

View file

@ -0,0 +1,27 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="14dp"
android:viewportWidth="199.999"
android:viewportHeight="21.883688">
<path
android:pathData="M17.985,0.801C18.989,0.27 20.117,-0.006 21.252,0.02 26.324,0.018 31.396,0.037 36.468,0.014 35.806,1.483 35.103,3.417 33.222,3.586 28.509,3.717 23.784,3.574 19.066,3.652 17.9,3.632 16.738,4.246 16.244,5.33c-1.016,1.991 -1.928,4.035 -2.926,6.038 4.043,-0.003 8.088,0.003 12.132,-0.006 -0.354,0.688 -0.619,1.452 -1.175,2.01 -0.678,0.534 -1.601,0.435 -2.406,0.459 -3.131,-0.041 -6.266,0.034 -9.396,-0.044 -1.129,2.116 -2.082,4.318 -3.173,6.453 -0.497,1.007 -1.584,1.658 -2.709,1.619 -2.196,0 -4.397,0.08 -6.591,-0.072v-0.118c0.038,0.009 0.116,0.031 0.156,0.04 1.9,-4.104 3.881,-8.165 5.844,-12.24C6.965,7.428 8.615,5.742 10.603,4.672 13.049,3.354 15.524,2.092 17.985,0.801z"
android:fillColor="#0b1560"/>
<path
android:pathData="m38.996,1.801c0.509,-1.078 1.675,-1.75 2.853,-1.769 2.156,-0.034 4.312,0.013 6.469,-0.022 -3.174,6.676 -6.424,13.319 -9.621,19.985 -0.447,1.091 -1.543,1.875 -2.734,1.858 -2.215,0.031 -4.431,0.007 -6.645,0.01 3.222,-6.687 6.451,-13.373 9.678,-20.062z"
android:fillColor="#0b1560"/>
<path
android:pathData="m56.965,0.137c0.706,-0.351 1.525,0.047 1.909,0.678 3.159,4.344 6.337,8.675 9.527,12.994 0.351,0.478 0.615,1.006 0.875,1.537 2.021,-3.998 3.9,-8.069 5.856,-12.098 0.503,-0.997 0.872,-2.197 1.929,-2.756 1.461,-0.781 3.185,-0.375 4.769,-0.462 -3.524,7.279 -7.041,14.56 -10.561,21.842 -1.785,-0.025 -3.572,0.037 -5.354,-0.027 -1.109,-0.035 -1.965,-0.856 -2.594,-1.688 -2.465,-3.281 -4.934,-6.56 -7.4,-9.834 -0.531,-0.673 -1.047,-1.356 -1.413,-2.134 -2.006,3.994 -3.853,8.067 -5.834,12.074 -0.456,0.881 -1.372,1.528 -2.372,1.582 -1.166,0.067 -2.332,0.01 -3.496,0.024 2.48,-5.319 5.021,-10.616 7.555,-15.91 0.82,-1.744 2.045,-3.344 3.731,-4.319 0.934,-0.544 1.882,-1.069 2.873,-1.503z"
android:fillColor="#0b1560"/>
<path
android:pathData="m91.36,0.137c0.692,-0.344 1.498,0.028 1.889,0.644 3.166,4.347 6.348,8.688 9.544,13.016 0.358,0.481 0.622,1.022 0.888,1.556 2.248,-4.478 4.351,-9.033 6.553,-13.537 0.461,-0.983 1.47,-1.633 2.537,-1.746 1.145,-0.098 2.295,-0.022 3.441,-0.053 -3.479,7.303 -7.031,14.571 -10.551,21.858 -1.793,-0.03 -3.59,0.037 -5.385,-0.03 -1.188,-0.062 -2.057,-0.994 -2.713,-1.892 -2.797,-3.769 -5.674,-7.478 -8.438,-11.272 -0.09,-0.072 -0.271,-0.222 -0.361,-0.293 -1.801,3.848 -3.676,7.659 -5.492,11.5 -0.412,0.943 -1.236,1.781 -2.293,1.922 -1.246,0.131 -2.502,0.024 -3.75,0.071 2.021,-4.479 4.19,-8.899 6.297,-13.343 0.9,-1.771 1.588,-3.697 2.923,-5.207 1.309,-1.498 3.155,-2.345 4.911,-3.194z"
android:fillColor="#0b1560"/>
<path
android:pathData="m128.938,0.833c0.992,-0.538 2.109,-0.828 3.242,-0.811 2.398,0 4.799,-0.002 7.202,0 1.743,-0.006 3.459,0.639 4.8,1.75 1.534,1.182 3.112,2.307 4.631,3.507 0.683,0.469 0.734,1.384 0.345,2.069 -2.304,4.847 -4.679,9.662 -6.981,14.512 -1.99,0 -3.984,0.027 -5.975,-0.006 -1.072,0.074 -1.956,-1.172 -1.432,-2.142 0.854,-1.997 1.91,-3.905 2.791,-5.891 -4.709,-0.011 -9.416,-0.003 -14.125,-0.003 -1.031,2.087 -2.017,4.199 -3.047,6.287 -0.464,0.972 -1.438,1.722 -2.537,1.74 -2.264,0.06 -4.528,-0.014 -6.791,0.034 1.965,-4.135 3.955,-8.257 5.939,-12.382 0.963,-2.034 2.585,-3.729 4.562,-4.797 2.453,-1.301 4.916,-2.582 7.376,-3.867M127.549,5.336c-1.013,1.988 -1.925,4.028 -2.928,6.025 4.716,0.013 9.428,0.003 14.144,0.003 0.947,-1.988 1.909,-3.969 2.879,-5.947 0.152,-0.419 0.519,-0.872 0.293,-1.328 -0.369,-0.537 -1.062,-0.435 -1.619,-0.459 -3.334,0.025 -6.668,-0.021 -10,0.022 -1.167,-0.031 -2.278,0.622 -2.769,1.684z"
android:fillColor="#0b1560"/>
<path
android:pathData="m157.174,2.51c0.44,-1.222 1.423,-2.306 2.778,-2.439 2.281,-0.125 4.572,0.003 6.855,-0.062 -3.078,6.647 -6.354,13.207 -9.502,19.822 -0.43,1.064 -1.406,1.953 -2.589,2.014 -2.291,0.062 -4.584,0.01 -6.878,0.024 3.114,-6.455 6.233,-12.902 9.336,-19.359z"
android:fillColor="#0b1560"/>
<path
android:pathData="m177.005,2.324c1.875,-0.872 3.638,-2.269 5.794,-2.291 2.51,-0.017 5.022,-0.028 7.531,0.006 2.278,0.078 4.222,1.388 5.916,2.794 1.234,1.059 2.766,1.807 3.753,3.125v0.809c-0.578,1.492 -1.253,2.951 -2,4.363 -0.841,1.506 -2.675,1.984 -4.269,2.145 -2.636,0.209 -5.281,-0.055 -7.916,0.148 0.074,0.102 0.226,0.305 0.3,0.403 1.513,0.56 3.71,0.028 4.625,1.681 1.281,2.129 2.562,4.258 3.862,6.377 -2.574,-0.049 -5.152,0.019 -7.729,-0.031 -0.984,0.039 -1.906,-0.498 -2.4,-1.336 -1.184,-1.85 -2.242,-3.774 -3.394,-5.641 -0.44,-0.725 -1.122,-1.372 -2,-1.462 -1.481,-0.147 -2.972,-0.022 -4.456,-0.069 -1.088,2.166 -2.115,4.359 -3.188,6.531 -0.455,1.062 -1.446,1.956 -2.649,1.967 -2.267,0.074 -4.531,-0.008 -6.797,0.036 2.116,-4.399 4.159,-8.84 6.368,-13.19 1.778,-3.347 5.534,-4.628 8.649,-6.365m1.288,2.858c-0.969,1.881 -1.841,3.812 -2.788,5.703 3.791,-0.006 7.582,0.012 11.372,-0.01 1.272,0.003 2.794,-0.259 3.469,-1.479 0.69,-1.299 1.257,-2.662 1.926,-3.971 0.162,-0.426 0.537,-0.897 0.284,-1.363 -0.391,-0.49 -1.054,-0.428 -1.608,-0.435 -3.332,0.025 -6.663,-0.022 -9.994,0.022 -1.077,0.006 -2.161,0.556 -2.661,1.533z"
android:fillColor="#0b1560"/>
</vector>

View file

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="51dp"
android:viewportWidth="1000"
android:viewportHeight="400">
<group>
<clip-path android:pathData="M0,-1v83h55.94v236L1.52,318v82h194.65v-82h-55.94L140.23,82h54.41L194.65,-1zM554.02,0v82h55.94v236h-54.41v82h138.71L694.25,171.84l82.66,228.08 1.68,0.04 81.17,-228.12L859.76,400h140.23v-82h-55.94L944.05,82h54.42L998.47,0h-156.33l-64.73,182.89L711.87,0z M 0,0M222.23,0v82h55.94v130h215.31v-24.93s18.01,-14.04 23.75,-27.37l11.52,-25.85s5.35,-14.47 5.35,-27.41l-2.31,-25.85s-3.62,-21.06 -9.92,-27.33l-22.27,-25.9S471.28,0 433.75,0zM362.46,82h81.99v76L362.46,158z M 0,0M222.23,400l0,-82l55.94,-0l0,-130l215.31,-0l0,24.93s18.01,14.04 23.75,27.37l11.52,25.85s5.35,14.47 5.35,27.41l-2.31,25.85s-3.62,21.06 -9.92,27.33l-22.27,25.9S471.28,400 433.75,400zM362.46,318l81.99,-0l0,-76L362.46,242z M 0,0"/>
<path
android:pathData="M0,13.68h1030v53.23H0m0,53.23h975v53.24H0v53.22h975v53.22H0m0,53.24h1030v53.24H0"
android:strokeWidth="27.37"
android:fillColor="#00000000"
android:strokeColor="#1f70c1"/>
</group>
</vector>

View file

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<path
android:pathData="m71.517,44.187 l12.296,12.296 -4.839,4.879 -12.296,-12.296zM94.007,21.737 L106.303,34.033 101.424,38.912 89.128,26.615zM93.214,65.924 L105.589,78.22 100.71,83.099 88.018,70.803zM115.704,43.473 L128,55.769 123.161,60.648 110.865,47.955zM67.035,34.35 L79.331,22.054 84.249,26.933 71.953,39.229zM88.732,56.166 L101.028,43.87 105.946,48.63 93.65,60.926zM110.468,77.823 L122.764,65.527 127.643,70.366 115.347,82.662zM44.545,56.88 L56.841,44.584 61.759,49.423 49.463,61.719zM66.241,78.537 L78.617,66.241 83.456,71.12 71.16,83.416zM87.978,100.353 L100.274,87.978 105.193,92.856 92.896,105.549z"
android:strokeWidth="0.26458332"
android:fillColor="#575756"/>
<path
android:pathData="m26.576,89.088 l12.376,12.296 -4.839,4.918 -12.376,-12.376zM49.066,66.638 L61.362,78.934 56.523,83.813 44.227,71.517zM48.391,110.825 L60.688,123.121 55.809,128 43.513,115.704zM70.802,88.374 L83.098,100.671 78.259,105.549 65.963,93.253zM4.879,67.352 L17.175,79.648 12.296,84.487 0,72.191zM27.369,44.901 L39.665,57.197 34.787,62.076 22.49,49.78zM49.78,22.451 L62.076,34.747 57.316,39.665 45.02,27.369zM72.191,-0 L84.566,12.296 79.687,17.175 66.995,4.879zM45.337,12.693 L57.634,0.397 62.512,5.236 50.216,17.532zM22.847,35.183 L35.143,22.887 40.062,27.766 27.766,40.062zM0.397,57.673 L12.693,45.377 17.572,50.137 5.276,62.513zM22.054,79.331 L34.35,67.034 39.269,71.913 26.972,84.21zM43.79,101.067 L56.087,88.771 60.966,93.61 48.669,105.906zM65.448,122.804 L77.823,110.508 82.702,115.267 70.406,127.643z"
android:strokeWidth="0.26458332"
android:fillColor="#db202e"/>
</vector>

View file

@ -0,0 +1,31 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<path
android:pathData="m19.747,45.145c-0.04,0.287 -0.109,2.458 -0.155,4.826l-0.083,4.304 4.612,2.237 4.612,2.238 -14.366,0.007L0.001,58.763l0,5.164 0,5.164l14.113,0.031 14.113,0.031 -4.341,2.214 -4.341,2.214 0.014,2.89c0.008,1.59 0.049,3.78 0.092,4.867l0.077,1.977 2.854,-1.463c1.57,-0.805 4.51,-2.285 6.533,-3.289 2.023,-1.004 7.018,-3.535 11.1,-5.623l7.421,-3.797L47.635,63.936 47.635,58.729l-7.928,-4.049c-4.361,-2.227 -9.669,-4.909 -11.797,-5.96 -2.128,-1.052 -3.926,-1.953 -3.996,-2.002 -0.07,-0.05 -1.019,-0.541 -2.11,-1.092l-1.984,-1.002 -0.072,0.521m85.29,1.03c-1.64,0.843 -3.609,1.842 -4.377,2.221 -0.768,0.379 -5.661,2.853 -10.875,5.498l-9.479,4.808 -0.003,5.182 -0.003,5.183 9.038,4.608c4.971,2.534 9.638,4.898 10.371,5.253 0.732,0.355 2.95,1.474 4.927,2.486 1.978,1.012 3.621,1.816 3.652,1.785 0.031,-0.03 0.092,-2.206 0.134,-4.836l0.077,-4.781 -4.32,-2.214 -4.32,-2.214 14.068,-0.031 14.068,-0.031l0,-5.164 0,-5.164l-14.43,-0.007 -14.43,-0.007 4.662,-2.269 4.662,-2.269 -0.017,-2.244c-0.031,-3.973 -0.166,-7.265 -0.3,-7.296 -0.07,-0.017 -1.468,0.659 -3.108,1.502"
android:fillColor="#d3732c"
android:strokeColor="#00000000"
android:fillType="evenOdd"/>
<path
android:pathData="M12.179,0.244C7.005,1.52 2.266,5.764 0.723,10.503 0.044,12.59 0.001,13.097 0.002,19.024l0.001,5.49 13.904,7.194c7.647,3.957 14.397,7.421 15,7.697 0.603,0.277 4.978,2.511 9.722,4.965 4.744,2.454 8.726,4.512 8.848,4.574 0.21,0.106 0.222,-0.16 0.222,-4.796L47.699,39.24L38.39,34.429C33.27,31.783 29.038,29.617 28.986,29.617 28.858,29.617 20.337,25.208 19.849,24.889 19.636,24.75 17.366,23.558 14.803,22.239l-4.66,-2.398 0.035,-2.829c0.045,-3.618 0.52,-4.796 2.279,-5.645l0.66,-0.319l52.366,0 52.366,0l-0.001,4.396 -0.001,4.397 -4.652,2.398c-2.558,1.319 -4.827,2.511 -5.042,2.65 -0.487,0.315 -9.014,4.729 -9.135,4.729 -0.049,0 -4.28,2.167 -9.404,4.816l-9.315,4.816l0,4.902 0,4.902l0.368,-0.185c0.203,-0.102 4.47,-2.303 9.483,-4.893 5.013,-2.589 9.268,-4.763 9.456,-4.83 0.189,-0.067 6.653,-3.387 14.366,-7.377L127.996,24.514 127.997,12.257 127.998,0 70.501,0.02C17.484,0.039 12.939,0.057 12.179,0.244m27.655,82.54c-4.291,2.222 -9.172,4.722 -10.846,5.557 -1.675,0.834 -8.867,4.53 -15.984,8.213L0.065,103.249 0.032,115.625 0,128l58.333,0c57.968,0 58.34,-0.002 59.337,-0.247 4.434,-1.09 8.166,-4.916 9.942,-10.19l0.388,-1.152 -0.033,-6.586 -0.033,-6.586 -13.637,-7.062c-7.5,-3.884 -14.151,-7.299 -14.778,-7.588 -0.628,-0.29 -5.21,-2.632 -10.181,-5.204l-9.04,-4.677 0.033,4.932 0.033,4.932 9.823,5.079c5.403,2.793 9.868,5.079 9.922,5.079 0.124,0 7.728,3.935 7.905,4.091 0.072,0.063 2.3,1.237 4.951,2.609l4.82,2.494l0,3.123 0,3.123l-0.431,0.848c-0.728,1.433 -1.794,2.248 -3.301,2.525 -0.452,0.083 -17.909,0.125 -52.293,0.125L10.147,117.67l0.033,-4.873 0.033,-4.872 4.82,-2.494c2.651,-1.371 4.878,-2.543 4.947,-2.605 0.166,-0.145 7.803,-4.096 7.918,-4.096 0.116,0 19.568,-10.057 19.701,-10.185 0.056,-0.054 0.087,-2.282 0.068,-4.95l-0.033,-4.852 -7.801,4.04"
android:fillColor="#939393"
android:strokeColor="#00000000"
android:fillType="evenOdd"/>
<path
android:pathData="m20.073,22.631 l0.034,2.36 4.44,2.306 4.44,2.306 35.012,0.002 35.012,0.002 4.44,-2.303 4.44,-2.302 0.034,-2.366 0.035,-2.366L64,20.271 20.039,20.271l0.035,2.36m69.911,21.478 l-9.407,4.877 9.392,0.032 9.392,0.032 5.216,-2.659c9.67,-4.93 13.271,-6.832 13.271,-7.008 0,-0.147 -1.386,-0.171 -9.229,-0.162l-9.229,0.011 -9.407,4.878m-79.933,0.11 l0.029,4.891 0.066,-4.743 0.066,-4.743 3.171,1.648c1.744,0.906 5.871,3.027 9.17,4.713l5.999,3.065 9.442,-0.031 9.442,-0.032 -9.225,-4.796 -9.225,-4.796 -9.483,-0.033 -9.482,-0.033 0.029,4.891m16.145,35.831c-1.465,0.748 -3.72,1.888 -5.011,2.534 -4.706,2.354 -11.163,5.728 -11.163,5.833 0,0.061 4.047,0.108 9.289,0.108l9.289,0l9.422,-4.869c5.182,-2.678 9.422,-4.891 9.422,-4.919 0,-0.028 -4.182,-0.049 -9.292,-0.048l-9.292,0.002 -2.664,1.36m54.427,-1.26c0.067,0.057 4.321,2.271 9.454,4.919l9.333,4.815l9.294,0c7.338,0 9.282,-0.032 9.241,-0.152 -0.051,-0.149 -4.175,-2.331 -8.595,-4.548 -1.221,-0.612 -3.997,-2.019 -6.168,-3.126l-3.949,-2.012l-9.365,0c-5.151,0 -9.31,0.047 -9.244,0.103m-56.678,21.998 l-3.901,2.028l0,2.631 0,2.631L64,108.078 107.955,108.078l0,-2.631 0,-2.631l-3.96,-2.042 -3.96,-2.042 -36.095,0.014 -36.094,0.014 -3.901,2.028"
android:fillColor="#3d3d3d"
android:strokeColor="#00000000"
android:fillType="evenOdd"/>
<path
android:pathData="m113.092,42.05c-2.581,1.345 -4.722,2.46 -4.757,2.478 -0.035,0.017 -0.047,1.042 -0.026,2.276l0.037,2.244l4.752,0 4.751,0l0,-4.734c0,-2.604 -0.014,-4.729 -0.032,-4.722 -0.017,0.007 -2.144,1.113 -4.725,2.458m-102.942,2.373l0,4.748l4.757,0 4.757,0l0.024,-1.968c0.013,-1.082 0.028,-2.109 0.032,-2.282 0.007,-0.268 -7.835,-4.589 -9.411,-5.186 -0.125,-0.047 -0.158,0.94 -0.158,4.688m98.269,35.462c-0.132,1.927 -0.104,3.474 0.062,3.474 0.08,0 2.226,1.079 4.769,2.398 2.543,1.319 4.647,2.398 4.675,2.398 0.028,0 0.051,-2.131 0.051,-4.735l0,-4.734l-4.738,0 -4.738,0l-0.082,1.199M10.023,83.529l0,4.72l4.815,-2.475 4.815,-2.475 0.005,-1.488c0.003,-0.819 -0.031,-1.829 -0.076,-2.244l-0.081,-0.756l-4.739,0 -4.739,0l0,4.72"
android:fillColor="#6b6b6b"
android:strokeColor="#00000000"
android:fillType="evenOdd"/>
<path
android:pathData="m12.41,78.778c1.348,0.02 3.517,0.02 4.821,0 1.304,-0.02 0.201,-0.036 -2.45,-0.036 -2.651,0 -3.718,0.016 -2.37,0.036"
android:fillColor="#545454"
android:strokeColor="#00000000"
android:fillType="evenOdd"/>
</vector>

View file

@ -0,0 +1,155 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<path
android:pathData="m111.17,46.365l0,0.004L105.973,46.368L105.973,41.724C105.973,18.68 87.179,0 63.993,0 40.81,0 22.016,18.68 22.016,41.724l0,4.644L16.826,46.368C11.375,46.368 6.96,50.755 6.96,56.174l0,38.306c0.011,2.551 0.164,4.406 1.162,5.757 1.036,1.356 2.776,1.84 5.373,1.832l8.35,0l1.274,20.17c0,0.048 -0.004,0.127 -0.004,0.227 0.004,0.536 0.063,1.761 0.741,2.938 0.667,1.188 2.068,2.249 4.333,2.231l21.219,0l11.018,-11.682l8.234,0L79.314,128l0.298,0c0,0 3.856,0 8.13,0 4.266,0 8.95,0 10.6,0l0.004,0c1.639,-0.007 3.141,0.034 4.441,-0.793 1.297,-0.845 2.075,-2.45 2.452,-5.247 0.548,-4.067 0.674,-15.194 0.924,-19.887l8.342,0c2.567,-0.007 4.244,-0.253 5.332,-1.423 1.051,-1.192 1.189,-2.89 1.203,-5.437L121.04,56.174c-0.007,-5.419 -4.423,-9.805 -9.87,-9.809z"
android:strokeWidth="1"
android:fillColor="#349334"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m119.826,95.291c0.015,2.511 -0.242,3.915 -0.861,4.563 -0.578,0.674 -1.842,1.002 -4.358,0.995l-9.599,0l-0.034,0.618c-0.231,4.426 -0.388,16.265 -0.943,20.411 -0.362,2.675 -1.059,3.807 -1.868,4.329 -0.813,0.548 -2.062,0.589 -3.724,0.581l-0.004,0c-3.034,0 -16.28,0 -18.442,0L69.336,114.734L59.938,114.734L48.911,126.424L28.247,126.424c-1.883,-0.019 -2.684,-0.741 -3.195,-1.576 -0.492,-0.846 -0.57,-1.881 -0.567,-2.291 0,-0.127 0.004,-0.179 0.004,-0.179l0.004,-0.052 -1.364,-21.48L13.548,100.846c-2.494,-0.004 -3.691,-0.462 -4.324,-1.311 -0.671,-0.857 -0.91,-2.47 -0.902,-4.973L8.322,56.247C8.329,51.549 12.154,47.753 16.881,47.745L23.393,47.745L23.393,41.792C23.431,19.463 41.604,1.399 64.076,1.362 86.544,1.399 104.721,19.463 104.762,41.792l0,5.953l6.516,0c4.723,0.007 8.544,3.804 8.552,8.501l0,39.045z"
android:strokeWidth="1"
android:fillColor="#4bb749"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M24.511,99.707l78.979,0l0,2.617l-78.979,0z"
android:strokeWidth="1"
android:fillColor="#118011"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M23.3,100.615l0,-49.475l1.335,0l0,49.475z"
android:strokeWidth="1"
android:fillColor="#118011"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M103.641,100.615l0,-49.475l1.335,0l0,49.475z"
android:strokeWidth="1"
android:fillColor="#118011"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M35.102,61.73a5.144,28.293 90,1 0,56.586 0a5.144,28.293 90,1 0,-56.586 0z"
android:strokeWidth="1"
android:strokeColor="#00000000"
android:fillType="nonZero">
<aapt:attr name="android:fillColor">
<gradient
android:startY="66.862495"
android:startX="63.394802"
android:endY="57.485966"
android:endX="63.394802"
android:type="linear">
<item android:offset="0" android:color="#FF4BB749"/>
<item android:offset="1" android:color="#FF79B481"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m89.721,48.567l0,-7.545c0,-14.216 -11.547,-25.741 -25.795,-25.741 -14.248,0 -25.799,11.525 -25.799,25.741l0,7.545z"
android:strokeWidth="1"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M53.106,40.7l22.998,0l0,2.735l-22.998,0z"
android:strokeWidth="1"
android:strokeColor="#00000000"
android:fillType="nonZero">
<aapt:attr name="android:fillColor">
<gradient
android:gradientRadius="10.784006"
android:centerX="64.86781"
android:centerY="42.21012"
android:type="radial">
<item android:offset="0" android:color="#FF000000"/>
<item android:offset="0.1901" android:color="#FF030303"/>
<item android:offset="0.3236" android:color="#FF0C0C0C"/>
<item android:offset="0.4397" android:color="#FF1C1C1C"/>
<item android:offset="0.5461" android:color="#FF323232"/>
<item android:offset="0.64559996" android:color="#FF4E4E4E"/>
<item android:offset="0.7402" android:color="#FF717171"/>
<item android:offset="0.83089995" android:color="#FF9A9A9A"/>
<item android:offset="0.9161" android:color="#FFC9C9C9"/>
<item android:offset="0.9985" android:color="#FFFEFEFE"/>
<item android:offset="1" android:color="#FFFFFFFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M55.452,29.277m-4.766,0a4.766,4.766 45,1 1,9.532 0a4.766,4.766 135,1 1,-9.532 0"
android:strokeWidth="1"
android:fillColor="#000000"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M72.397,29.277m-4.766,0a4.766,4.766 0,1 1,9.532 0a4.766,4.766 135,1 1,-9.532 0"
android:strokeWidth="1"
android:fillColor="#000000"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="M54.771,77.314l17.248,0l0,12.861l-17.248,0z"
android:strokeWidth="1"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m57.433,75.953c0.778,-2.716 3.189,-4.687 6.039,-4.69 2.85,0.004 5.261,1.974 6.043,4.69l2.05,0c-0.826,-3.792 -4.115,-6.657 -8.096,-6.657 -3.981,0.004 -7.267,2.865 -8.093,6.657z"
android:strokeWidth="1"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m115.805,103.307c0.464,-0.004 0.89,-0.015 1.302,-0.034l0,-1.448c-0.752,0.116 -1.616,0.157 -2.622,0.161l-8.374,0c-0.127,2.341 -0.221,6.268 -0.352,10.128l1.365,0c0.112,-3.416 0.198,-6.735 0.31,-8.806z"
android:strokeWidth="1"
android:fillColor="#118011"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m117.106,104.053l0,-0.715c-0.408,0.019 -0.834,0.033 -1.302,0.033l-8.374,0c-0.112,2.057 -0.198,5.351 -0.31,8.742l1.941,-0c4.447,0.004 8.045,-3.606 8.045,-8.06z"
android:strokeWidth="1"
android:strokeColor="#00000000"
android:fillType="nonZero">
<aapt:attr name="android:fillColor">
<gradient
android:startY="97.49953"
android:startX="102.2623"
android:endY="108.40542"
android:endX="112.76872"
android:type="linear">
<item android:offset="0" android:color="#FF23FF16"/>
<item android:offset="1" android:color="#FF189A33"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M21.91,102.073L13.549,102.073c-1.295,0.004 -2.369,-0.115 -3.261,-0.4l0,1.669c0.526,0.063 1.101,0.089 1.731,0.089l8.364,-0.004 0.552,8.686l1.608,0z"
android:strokeWidth="1"
android:fillColor="#118011"
android:strokeColor="#00000000"
android:fillType="nonZero"/>
<path
android:pathData="m12.01,103.427c-0.627,0 -1.199,-0.026 -1.722,-0.089l0,0.722c0,4.447 3.57,8.053 7.975,8.053l2.616,0l-0.549,-8.69z"
android:strokeWidth="1"
android:strokeColor="#00000000"
android:fillType="nonZero">
<aapt:attr name="android:fillColor">
<gradient
android:startY="93.15896"
android:startX="28.748474"
android:endY="110.74311"
android:endX="12.861952"
android:type="linear">
<item android:offset="0" android:color="#FF23FF16"/>
<item android:offset="1" android:color="#FF189A33"/>
</gradient>
</aapt:attr>
</path>
</vector>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -7,7 +7,7 @@
android:background="?attr/windowBackground" android:background="?attr/windowBackground"
android:fitsSystemWindows="true" > android:fitsSystemWindows="true" >
<android.support.design.widget.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"> android:theme="@style/AppTheme.AppBarOverlay">
@ -18,7 +18,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/container_toolbar" android:id="@+id/container_toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
@ -28,7 +28,7 @@
</RelativeLayout> </RelativeLayout>
</android.support.design.widget.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<ViewStub <ViewStub
android:id="@+id/container_stub" android:id="@+id/container_stub"
@ -38,4 +38,4 @@
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
@ -9,7 +9,7 @@
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
tools:context="org.shadowice.flocke.andotp.Activities.MainActivity"> tools:context="org.shadowice.flocke.andotp.Activities.MainActivity">
<android.support.design.widget.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"> android:theme="@style/AppTheme.AppBarOverlay">
@ -21,7 +21,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
@ -43,7 +43,7 @@
</RelativeLayout> </RelativeLayout>
</android.support.design.widget.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/main_content" android:id="@+id/main_content"
@ -51,12 +51,12 @@
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" > app:layout_behavior="@string/appbar_scrolling_view_behavior" >
<android.support.v4.widget.DrawerLayout <androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout" android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/cardList" android:id="@+id/cardList"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -69,7 +69,7 @@
<include layout="@layout/component_tags" /> <include layout="@layout/component_tags" />
</android.support.v4.widget.DrawerLayout> </androidx.drawerlayout.widget.DrawerLayout>
</RelativeLayout> </RelativeLayout>
@ -86,4 +86,4 @@
app:sdMainFabClosedSrc="@drawable/ic_add_white" app:sdMainFabClosedSrc="@drawable/ic_add_white"
app:sdOverlayLayout="@id/speedDialOverlay" /> app:sdOverlayLayout="@id/speedDialOverlay" />
</android.support.design.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -7,13 +7,13 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" > android:orientation="vertical" >
<android.support.design.widget.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout" android:id="@+id/tabLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:tabMode="fixed" /> app:tabMode="fixed" />
<android.support.v4.view.ViewPager <androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager" android:id="@+id/viewPager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />

View file

@ -24,21 +24,21 @@
android:paddingStart="@dimen/activity_margin" android:paddingStart="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"> android:paddingEnd="@dimen/activity_margin">
<android.support.design.widget.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/passwordLayout" android:id="@+id/passwordLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/settings_hint_password" android:hint="@string/settings_hint_password"
app:passwordToggleEnabled="true" > app:passwordToggleEnabled="true" >
<android.support.design.widget.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordEdit" android:id="@+id/passwordEdit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:inputType="textPassword" android:inputType="textPassword"
android:autofillHints="password" /> android:autofillHints="password" />
</android.support.design.widget.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<EditText <EditText
android:id="@+id/passwordConfirm" android:id="@+id/passwordConfirm"
@ -60,7 +60,7 @@
</LinearLayout> </LinearLayout>
<android.support.v7.widget.ButtonBarLayout <androidx.appcompat.widget.ButtonBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin" android:layout_marginTop="@dimen/activity_margin"
@ -80,6 +80,6 @@
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:text="@string/button_save" /> android:text="@string/button_save" />
</android.support.v7.widget.ButtonBarLayout> </androidx.appcompat.widget.ButtonBarLayout>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,240 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_xsmall"
android:layout_marginBottom="@dimen/activity_margin_xsmall"
app:contentPadding="0dp"
style="?attr/cardStyle">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false">
<FrameLayout
android:id="@+id/thumbnailFrame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingEnd="@dimen/activity_margin"
android:paddingStart="@dimen/card_padding_without_corners"
android:background="?attr/thumbnailBackground">
<ImageView
android:id="@+id/thumbnailImg"
android:layout_width="@dimen/card_thumbnail_size"
android:layout_height="@dimen/card_thumbnail_size"
android:layout_gravity="center"
android:src="@mipmap/ic_launcher" />
</FrameLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:paddingStart="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin_small"
android:gravity="center_vertical"
android:baselineAligned="false" >
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:id="@+id/valueLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone">
<ImageView
android:id="@+id/valueImg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/activity_margin_small"
app:srcCompat="@drawable/ic_visibility_visible"/>
<TextView
android:textDirection="ltr"
android:id="@+id/valueText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="28sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="@+id/coverLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/coverImg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/activity_margin_small"
android:alpha="0.4"
app:srcCompat="@drawable/ic_visibility_invisible"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.4"
android:textColor="?android:attr/textColorSecondary"
android:textSize="28sp"
android:textStyle="bold"
android:text="@string/label_hidden" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textViewIssuer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="18sp"
android:text="Issuer"
android:textStyle="bold" />
<TextView
android:id="@+id/textViewSeparator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textSize="18sp"
android:text="@string/card_separator" />
<TextView
android:id="@+id/textViewLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:text="Label"
android:textSize="18sp" />
</LinearLayout>
<TextView
android:id="@+id/textViewTags"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:text="Tags"
android:textSize="13.5sp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/customPeriodLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:visibility="gone"
android:orientation="horizontal" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:srcCompat="@drawable/ic_alarm_gray" />
<TextView
android:id="@+id/customPeriod"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="@+id/counterLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="@dimen/activity_horizontal_margin"
android:gravity="center"
android:visibility="visible"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/label_counter_symbol" />
<TextView
android:id="@+id/counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold" />
</LinearLayout>
<ImageButton
android:id="@+id/copyButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
app:srcCompat="@drawable/ic_content_copy_gray" />
<ImageButton
android:id="@+id/menuButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
app:srcCompat="@drawable/ic_more_vert_gray" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/cardProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:max="3000"
android:progress="1500"
app:mpb_progressStyle="horizontal"
app:mpb_useIntrinsicPadding="false"
app:mpb_showProgressBackground="false"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding" />
</LinearLayout>
</androidx.cardview.widget.CardView>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view" android:id="@+id/card_view"
@ -105,6 +105,22 @@
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<TextView
android:id="@+id/textViewIssuer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/textViewSeparator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="0"
android:visibility="gone" />
<TextView <TextView
android:id="@+id/textViewLabel" android:id="@+id/textViewLabel"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -207,4 +223,4 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>

View file

@ -26,7 +26,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin" android:layout_marginTop="@dimen/activity_margin"
android:text="@string/intro_slide3_desc_keystore"/> android:text="@string/intro_slide3_desc_password"/>
<Spinner <Spinner
android:id="@+id/introAuthSelection" android:id="@+id/introAuthSelection"
@ -59,21 +59,21 @@
android:paddingStart="@dimen/activity_margin" android:paddingStart="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"> android:paddingEnd="@dimen/activity_margin">
<android.support.design.widget.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/introPasswordLayout" android:id="@+id/introPasswordLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/settings_hint_password" android:hint="@string/settings_hint_password"
app:passwordToggleEnabled="true" > app:passwordToggleEnabled="true" >
<android.support.design.widget.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/introPasswordEdit" android:id="@+id/introPasswordEdit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:inputType="textPassword" android:inputType="textPassword"
android:autofillHints="password" /> android:autofillHints="password" />
</android.support.design.widget.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<EditText <EditText
android:id="@+id/introPasswordConfirm" android:id="@+id/introPasswordConfirm"

View file

@ -10,21 +10,21 @@
android:paddingStart="@dimen/activity_margin_medium" android:paddingStart="@dimen/activity_margin_medium"
android:paddingEnd="@dimen/activity_margin_medium" > android:paddingEnd="@dimen/activity_margin_medium" >
<android.support.design.widget.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/passwordLayout" android:id="@+id/passwordLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/settings_hint_password" android:hint="@string/settings_hint_password"
app:passwordToggleEnabled="true" > app:passwordToggleEnabled="true" >
<android.support.design.widget.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordEdit" android:id="@+id/passwordEdit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:inputType="textPassword" android:inputType="textPassword"
android:autofillHints="password" /> android:autofillHints="password" />
</android.support.design.widget.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<EditText <EditText
android:id="@+id/passwordConfirm" android:id="@+id/passwordConfirm"
@ -34,7 +34,7 @@
android:inputType="textPassword" android:inputType="textPassword"
android:autofillHints="password" /> android:autofillHints="password" />
<android.support.v7.widget.ButtonBarLayout <androidx.appcompat.widget.ButtonBarLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin" android:layout_marginTop="@dimen/activity_margin"
@ -54,6 +54,6 @@
style="?android:attr/buttonBarButtonStyle" style="?android:attr/buttonBarButtonStyle"
android:text="@string/button_save" /> android:text="@string/button_save" />
</android.support.v7.widget.ButtonBarLayout> </androidx.appcompat.widget.ButtonBarLayout>
</LinearLayout> </LinearLayout>

View file

@ -17,14 +17,14 @@
android:textStyle="bold" android:textStyle="bold"
android:text="@string/auth_msg_authenticate"/> android:text="@string/auth_msg_authenticate"/>
<android.support.design.widget.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/passwordLayout" android:id="@+id/passwordLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/auth_hint_password" android:hint="@string/auth_hint_password"
app:passwordToggleEnabled="true" > app:passwordToggleEnabled="true" >
<android.support.design.widget.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordEdit" android:id="@+id/passwordEdit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -32,7 +32,7 @@
android:inputType="textPassword" android:inputType="textPassword"
android:autofillHints="password" /> android:autofillHints="password" />
<requestFocus/> <requestFocus/>
</android.support.design.widget.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<Button <Button
android:id="@+id/buttonUnlock" android:id="@+id/buttonUnlock"

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView <androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/scroll_view" android:id="@+id/scroll_view"
@ -253,4 +253,4 @@
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>
</android.support.v4.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>

View file

@ -32,6 +32,27 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" >
<TextView
android:layout_weight="3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/label_issuer"/>
<EditText
android:id="@+id/manual_issuer"
android:layout_weight="7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/label_issuer"/>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -71,6 +92,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:lines="3" android:lines="3"
android:inputType="textVisiblePassword"
android:hint="@string/hint_secret" /> android:hint="@string/hint_secret" />
</LinearLayout> </LinearLayout>

View file

@ -11,20 +11,20 @@
android:background="@null" android:background="@null"
android:padding="@dimen/activity_margin"> android:padding="@dimen/activity_margin">
<android.support.design.widget.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/passwordInputLayout" android:id="@+id/passwordInputLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/dialog_label_enter_password" android:hint="@string/dialog_label_enter_password"
app:passwordToggleEnabled="true" > app:passwordToggleEnabled="true" >
<android.support.design.widget.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordInput" android:id="@+id/passwordInput"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:inputType="textPassword" /> android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<EditText <EditText
android:id="@+id/passwordConfirm" android:id="@+id/passwordConfirm"

View file

@ -14,7 +14,7 @@
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" > android:orientation="vertical" >
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small" android:layout_marginTop="@dimen/activity_margin_small"
@ -57,9 +57,9 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small" android:layout_marginTop="@dimen/activity_margin_small"
@ -209,9 +209,9 @@
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small" android:layout_marginTop="@dimen/activity_margin_small"
@ -249,6 +249,7 @@
android:src="@mipmap/ic_author_flocke" /> android:src="@mipmap/ic_author_flocke" />
<LinearLayout <LinearLayout
android:id="@+id/aboutLayoutAuthor1Content"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -266,16 +267,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/about_label_main_developer"/> android:text="@string/about_label_main_developer"/>
<TextView
android:id="@+id/about_author1_extra"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="@string/about_label_donate" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
@ -306,6 +297,7 @@
app:srcCompat="@drawable/ic_account_circle_gray" /> app:srcCompat="@drawable/ic_account_circle_gray" />
<LinearLayout <LinearLayout
android:id="@+id/aboutLayoutAuthor2Content"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -323,16 +315,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/about_label_developer"/> android:text="@string/about_label_developer"/>
<TextView
android:id="@+id/about_author2_extra"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="@string/about_label_donate" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
@ -428,73 +410,33 @@
</LinearLayout> </LinearLayout>
<!-- translators -->
<LinearLayout
android:id="@+id/about_layout_translators"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/aboutImgTranslators"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin_large"
app:srcCompat="@drawable/ic_translate_gray" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_label_translators"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small" android:layout_marginTop="@dimen/activity_margin_small"
android:layout_marginBottom="@dimen/activity_margin_small" android:layout_marginBottom="@dimen/activity_margin_small"
style="?attr/cardStyle" > style="?attr/cardStyle" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/about_title_support"/>
<!-- bug reports -->
<LinearLayout <LinearLayout
android:id="@+id/about_layout_bugs" android:id="@+id/about_layout_support"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin_small" android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small" android:paddingBottom="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical" > android:gravity="center_vertical" >
<ImageView <ImageView
android:id="@+id/aboutImgBugs" android:id="@+id/aboutImgSupport"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin" android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin_large" android:layout_marginEnd="@dimen/activity_margin_large"
app:srcCompat="@drawable/ic_bug_report_gray" /> app:srcCompat="@drawable/ic_heart_gray" />
<LinearLayout <LinearLayout
android:orientation="vertical" android:orientation="vertical"
@ -505,7 +447,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/about_label_report_bugs" android:text="@string/about_title_support"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold" /> android:textStyle="bold" />
@ -513,57 +455,15 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/about_desc_report_bugs"/> android:text="@string/about_desc_support"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<!-- translate --> </androidx.cardview.widget.CardView>
<LinearLayout
android:id="@+id/about_layout_translate"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin_small"
android:paddingBottom="@dimen/activity_margin_small"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/aboutImgTranslate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginEnd="@dimen/activity_margin_large"
app:srcCompat="@drawable/ic_translate_gray" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/about_label_translate"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/about_desc_translate"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<!-- thumbnails --> <!-- thumbnails -->
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_margin_small" android:layout_marginTop="@dimen/activity_margin_small"
@ -618,7 +518,7 @@
android:text="@string/about_thumbnails_disclaimer_no4" /> android:text="@string/about_thumbnails_disclaimer_no4" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View file

@ -4,7 +4,10 @@
android:id="@+id/fabEnterDetails" android:id="@+id/fabEnterDetails"
android:title="@string/button_enter_details" android:title="@string/button_enter_details"
android:icon="@drawable/ic_edit_white" /> android:icon="@drawable/ic_edit_white" />
<item
android:id="@+id/fabScanQRFromImage"
android:title="@string/button_qr_from_image"
android:icon="@drawable/ic_image_white" />
<item <item
android:id="@+id/fabScanQR" android:id="@+id/fabScanQR"
android:title="@string/button_scan_qr" android:title="@string/button_scan_qr"

View file

@ -31,7 +31,7 @@
android:title="@string/menu_main_search" android:title="@string/menu_main_search"
android:icon="@drawable/ic_search_white" android:icon="@drawable/ic_search_white"
app:showAsAction="always|collapseActionView" app:showAsAction="always|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" /> app:actionViewClass="androidx.appcompat.widget.SearchView" />
<item <item
android:id="@+id/action_backup" android:id="@+id/action_backup"

View file

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_popup_editIssuer"
android:title="@string/menu_popup_edit_issuer" />
<item <item
android:id="@+id/menu_popup_editLabel" android:id="@+id/menu_popup_editLabel"
android:title="@string/menu_popup_edit_label" /> android:title="@string/menu_popup_edit_label" />

View file

@ -18,8 +18,7 @@
<string name="about_label_original_author">مؤلف التطبيق الأصلي</string> <string name="about_label_original_author">مؤلف التطبيق الأصلي</string>
<string name="about_label_original_app">التطبيق الأصلي</string> <string name="about_label_original_app">التطبيق الأصلي</string>
<string name="about_label_website">الموقع الإلكتروني</string> <string name="about_label_website">الموقع الإلكتروني</string>
<string name="about_label_donate_paypal">التبرع (Paypal)</string> <string name="about_label_donate">التبرع</string>
<string name="about_label_donate_bitcoin">التبرع (Bitcoin)</string>
<string name="about_label_contributors">المساهمون</string> <string name="about_label_contributors">المساهمون</string>
<string name="about_label_translators">المترجمون</string> <string name="about_label_translators">المترجمون</string>
<!-- Thumbnail disclaimer --> <!-- Thumbnail disclaimer -->

View file

@ -10,6 +10,7 @@
<string name="backup_title_export_openpgp">النسخ الاحتياطي (أوبن بي جي بي)</string> <string name="backup_title_export_openpgp">النسخ الاحتياطي (أوبن بي جي بي)</string>
<string name="backup_title_import_plain">إسترجاع (نص مجرّد)</string> <string name="backup_title_import_plain">إسترجاع (نص مجرّد)</string>
<string name="backup_title_import_crypt">إسترجاع (مشفّر)</string> <string name="backup_title_import_crypt">إسترجاع (مشفّر)</string>
<string name="backup_title_import_crypt_old">Restore (encrypted, old encryption)</string>
<string name="backup_title_import_openpgp">إسترجاع (أوبن بي جي بي)</string> <string name="backup_title_import_openpgp">إسترجاع (أوبن بي جي بي)</string>
<string name="backup_title_replace">إستبدال البيانات الموجودة</string> <string name="backup_title_replace">إستبدال البيانات الموجودة</string>
<string name="backup_desc_export_plain">أنسخ إحتياطيا لكافة الحسابات في ملف JSON نص مُجرَّد </string> <string name="backup_desc_export_plain">أنسخ إحتياطيا لكافة الحسابات في ملف JSON نص مُجرَّد </string>
@ -17,6 +18,8 @@
<string name="backup_desc_export_openpgp">أنسخ إحتياطيا لكافة الحسابات في ملف JSON مشفّر بواسطة أوبن بي جي بي</string> <string name="backup_desc_export_openpgp">أنسخ إحتياطيا لكافة الحسابات في ملف JSON مشفّر بواسطة أوبن بي جي بي</string>
<string name="backup_desc_import_plain">استعادة حسابات من ملف JSON نص مجرّد</string> <string name="backup_desc_import_plain">استعادة حسابات من ملف JSON نص مجرّد</string>
<string name="backup_desc_import_crypt">استعادة حسابات من ملف JSON محمي بكلمة مرور</string> <string name="backup_desc_import_crypt">استعادة حسابات من ملف JSON محمي بكلمة مرور</string>
<string name="backup_desc_import_crypt_old">Restore accounts from a password-protected JSON file
created with an <b>andOTP version lower than 0.6.3</b></string>
<string name="backup_desc_import_openpgp">استعادة حسابات من ملف JSON (مشفر بتقنية اوبن بي جي بي)</string> <string name="backup_desc_import_openpgp">استعادة حسابات من ملف JSON (مشفر بتقنية اوبن بي جي بي)</string>
<string name="backup_desc_crypt_setup">فشل في تحميل كلمة مرور النسخ الاحتياطي من الإعدادات، هذا أما يعني إنه لم يتم تعيين أية كلمة مرور أو حدث خطأ ما. سيطلب منك إدخال كلمة المرور يدوياً عند إنشاء أو استيراد نسخة احتياطية. <string name="backup_desc_crypt_setup">فشل في تحميل كلمة مرور النسخ الاحتياطي من الإعدادات، هذا أما يعني إنه لم يتم تعيين أية كلمة مرور أو حدث خطأ ما. سيطلب منك إدخال كلمة المرور يدوياً عند إنشاء أو استيراد نسخة احتياطية.
</string> </string>
@ -34,6 +37,11 @@
<string name="backup_receiver_read_permission_failed">الإذن للقراءة لم يمنح. الرجاء تمكينها قبل محاولة النسخ</string> <string name="backup_receiver_read_permission_failed">الإذن للقراءة لم يمنح. الرجاء تمكينها قبل محاولة النسخ</string>
<string name="backup_receiver_write_permission_failed">الإذن للكتابة لم يمنح. الرجاء تمكينها قبل محاولة النسخ</string> <string name="backup_receiver_write_permission_failed">الإذن للكتابة لم يمنح. الرجاء تمكينها قبل محاولة النسخ</string>
<string name="backup_receiver_custom_encryption_failed">التشفير عبر كلمة المرور / PIN غير مدعومة مع البث الإحتياطي</string> <string name="backup_receiver_custom_encryption_failed">التشفير عبر كلمة المرور / PIN غير مدعومة مع البث الإحتياطي</string>
<string name="backup_new_format_dialog_title">New encryption method</string>
<string name="backup_new_format_dialog_msg">Since version 0.6.3 of andOTP, a <b>new and improved
encryption method</b> is used for password-protected backups. The old backups can still be
imported, but it is <b>highly recommended to create new backups with the improved
encryption</b>.\n\nThis message will not be shown again.</string>
<!-- Notification channels --> <!-- Notification channels -->
<string name="notification_channel_name_backup_failed">فشل النسخ التلقائي</string> <string name="notification_channel_name_backup_failed">فشل النسخ التلقائي</string>
<string name="notification_channel_name_backup_success">نجح النسخ التلقائي</string> <string name="notification_channel_name_backup_success">نجح النسخ التلقائي</string>

View file

@ -46,7 +46,7 @@
<string name="settings_desc_backup_directory">دليل النسخ الإحتياطي (أسماء الملف يعتمدون على نوع النسخ الإحتياطي)</string> <string name="settings_desc_backup_directory">دليل النسخ الإحتياطي (أسماء الملف يعتمدون على نوع النسخ الإحتياطي)</string>
<string name="settings_desc_backup_password">إختر كلمة المرور التي سوف تستخدم لتشفير النسخ الإحتياطية</string> <string name="settings_desc_backup_password">إختر كلمة المرور التي سوف تستخدم لتشفير النسخ الإحتياطية</string>
<string name="settings_desc_backup_broadcasts">حدد أنواع النسخ الإحتياطي التي يمكن تشغيلها بواسطة تطبيقات البث</string> <string name="settings_desc_backup_broadcasts">حدد أنواع النسخ الإحتياطي التي يمكن تشغيلها بواسطة تطبيقات البث</string>
<string name="settings_desc_openpgp_key_encrypt">البريد الإلكتلتروني التابع الى مفتاح المستخدم لتشفير النسخ</string> <string name="settings_desc_openpgp_key_encrypt">عنوان البريد الإلكتروني للمفتاح المستخدَم لتشفير النسخ الإحتياطية</string>
<string name="settings_desc_openpgp_verify">النسخ المشفرة تسترد فقط إذا وقعوا بمفتاح صالح</string> <string name="settings_desc_openpgp_verify">النسخ المشفرة تسترد فقط إذا وقعوا بمفتاح صالح</string>
<string name="settings_desc_special_features">قم بإلغاء الخيار لتعطيل الميزات الخاصة مجددا</string> <string name="settings_desc_special_features">قم بإلغاء الخيار لتعطيل الميزات الخاصة مجددا</string>
<string name="settings_desc_enable_screenshot">السماح بالتقاط لقطات للشاشة الرئيسية <string name="settings_desc_enable_screenshot">السماح بالتقاط لقطات للشاشة الرئيسية

View file

@ -1,50 +1,49 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="about_activity_title">Quant a</string> <string name="about_activity_title">Quant a</string>
<string name="about_description">Autenticació de dos factors de codi obert per a Android</string> <string name="about_description">Autenticació de dos factors de codi obert per a Android</string>
<string name="about_tab_about">Acerca de</string> <string name="about_tab_about">Acerca de</string>
<string name="about_tab_libraries">Biblioteques</string> <string name="about_tab_libraries">Biblioteques</string>
<!-- Misc --> <!-- Misc -->
<string name="about_label_changelog">Registre de canvis</string> <string name="about_label_changelog">Registre de canvis</string>
<string name="about_label_license">Llicència</string> <string name="about_label_license">Llicència</string>
<string name="about_label_MIT">Llicència MIT</string> <string name="about_label_MIT">Llicència MIT</string>
<string name="about_label_source">Codi font</string> <string name="about_label_source">Codi font</string>
<string name="about_label_version">Versió</string> <string name="about_label_version">Versió</string>
<!-- Authors --> <!-- Authors -->
<string name="about_title_authors">Autors</string> <string name="about_title_authors">Autors</string>
<string name="about_label_main_developer">Programador principal</string> <string name="about_label_main_developer">Programador principal</string>
<string name="about_label_developer">Autor</string> <string name="about_label_developer">Autor</string>
<string name="about_label_original_author">Autor de l\'aplicació original</string> <string name="about_label_original_author">Autor de l\'aplicació original</string>
<string name="about_label_original_app">Aplicació original</string> <string name="about_label_original_app">Aplicació original</string>
<string name="about_label_website">Lloc web</string> <string name="about_label_website">Lloc web</string>
<string name="about_label_donate_paypal">Donar (PayPal)</string> <string name="about_label_donate">Donar</string>
<string name="about_label_donate_bitcoin">Donar (Bitcoin)</string> <string name="about_label_contributors">Col·laboradors</string>
<string name="about_label_contributors">Col·laboradors</string> <string name="about_label_translators">Traductors</string>
<string name="about_label_translators">Traductors</string> <!-- Thumbnail disclaimer -->
<!-- Thumbnail disclaimer --> <string name="about_title_thumbnail_disclaimer">Avís miniatura</string>
<string name="about_title_thumbnail_disclaimer">Avís miniatura</string> <string name="about_thumbnails_disclaimer_no1"><b>1.</b> totes les miniatures són marques registrades dels seus
<string name="about_thumbnails_disclaimer_no1"><b>1.</b> totes les miniatures són marques registrades dels seus
respectius propietaris.</string> respectius propietaris.</string>
<string name="about_thumbnails_disclaimer_no2"><b>2.</b> l\'ús de les marques comercials no <string name="about_thumbnails_disclaimer_no2"><b>2.</b> l\'ús de les marques comercials no
indica aprovació del titular de la marca per andOTP, ni viceversa.</string> indica aprovació del titular de la marca per andOTP, ni viceversa.</string>
<string name="about_thumbnails_disclaimer_no3"><b>3.</b> Miniatures només usades per <string name="about_thumbnails_disclaimer_no3"><b>3.</b> Miniatures només usades per
representar l\'empresa o producte al qual es refereixen.</string> representar l\'empresa o producte al qual es refereixen.</string>
<string name="about_thumbnails_disclaimer_no4"><b>4. No utilitzeu miniatures per a qualsevol propòsit <string name="about_thumbnails_disclaimer_no4"><b>4. No utilitzeu miniatures per a qualsevol propòsit
excepte per representar aquella marca determinada o servei.</b></string> excepte per representar aquella marca determinada o servei.</b></string>
<!-- Support --> <!-- Support -->
<string name="about_title_support">Doneu suport al desenvolupament</string> <string name="about_title_support">Doneu suport al desenvolupament</string>
<string name="about_label_report_bugs">Informe d\'errors</string> <string name="about_label_report_bugs">Informe d\'errors</string>
<string name="about_label_translate">Tradueix</string> <string name="about_label_translate">Tradueix</string>
<string name="about_desc_report_bugs">Aviseu d\'un error o demaneu funcions noves</string> <string name="about_desc_report_bugs">Aviseu d\'un error o demaneu funcions noves</string>
<string name="about_desc_translate">Com podeu ajudar a traduir andOTP a la vostra llengua</string> <string name="about_desc_translate">Com podeu ajudar a traduir andOTP a la vostra llengua</string>
<string name="about_title_special_features">Característiques especials</string> <string name="about_title_special_features">Característiques especials</string>
<string name="about_dialog_special_features">Esteu segur que voleu habilitar les característiques <string name="about_dialog_special_features">Esteu segur que voleu habilitar les característiques
especials? La major part són algorismes OTP no estàndard que es van implementar especials? La major part són algorismes OTP no estàndard que es van implementar
ad-hoc. <b>No tenen suport oficial</b> i pateixen de <b>certes ad-hoc. <b>No tenen suport oficial</b> i pateixen de <b>certes
limitacions</b>, per favor, llegiu (i assegureu-vos d\'entendre) la pàgina \"característiques especials\" en la wiki de Github limitacions</b>, per favor, llegiu (i assegureu-vos d\'entendre) la pàgina \"característiques especials\" en la wiki de Github
per a saber-ne més abans de fer-les servir.</string> per a saber-ne més abans de fer-les servir.</string>
<string name="about_toast_special_features">Característiques especials habilitades</string> <string name="about_toast_special_features">Característiques especials habilitades</string>
<string name="about_toast_special_features_enabled">Característiques especials ja habilitades</string> <string name="about_toast_special_features_enabled">Característiques especials ja habilitades</string>
<string name="about_toast_copied_to_clipboard">S\'ha copiat l\'enllaç de donació al porta-retalls</string> <string name="about_toast_copied_to_clipboard">S\'ha copiat l\'enllaç de donació al porta-retalls</string>
</resources> </resources>

View file

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="auth_activity_title">Autentica</string> <string name="auth_activity_title">Autentica</string>
<!-- Hints --> <!-- Hints -->
<string name="auth_hint_password">Contrasenya</string> <string name="auth_hint_password">Contrasenya</string>
<string name="auth_hint_pin">PIN</string> <string name="auth_hint_pin">PIN</string>
<!-- Messages --> <!-- Messages -->
<string name="auth_msg_authenticate">Per favor, autentiqueu-vos per a iniciar andOTP!</string> <string name="auth_msg_authenticate">Per favor, autentiqueu-vos per a iniciar andOTP!</string>
<string name="auth_msg_confirm_encryption">Per favor, confirmeu la vostra autenticació per a generar <string name="auth_msg_confirm_encryption">Per favor, confirmeu la vostra autenticació per a generar
la clau de xifratge nova!</string> la clau de xifratge nova!</string>
<!-- Buttons --> <!-- Buttons -->
<string name="auth_button_unlock">Desbloqueja</string> <string name="auth_button_unlock">Desbloqueja</string>
<!-- Toast messages --> <!-- Toast messages -->
<string name="auth_toast_password_missing">Please set a password in the <b>Settings</b>!</string> <string name="auth_toast_password_missing">Per favor, establiu una contrasenya a la <b>configuració</b>!</string>
<string name="auth_toast_pin_missing">Please set a PIN in the <b>Settings</b>!</string> <string name="auth_toast_pin_missing">Per favor, establiu un PIN en la <b>configuració</b>!</string>
<string name="auth_toast_password_again">Contrasenya incorrecta; per favor, torneu-ho a intentar!</string> <string name="auth_toast_password_again">Contrasenya incorrecta; per favor, torneu-ho a intentar!</string>
<string name="auth_toast_pin_again">PIN incorrecte; per favor, torneu-ho a intentar!</string> <string name="auth_toast_pin_again">PIN incorrecte; per favor, torneu-ho a intentar!</string>
</resources> </resources>

View file

@ -1,71 +1,79 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="backup_activity_title">Còpies de seguretat</string> <string name="backup_activity_title">Còpies de seguretat</string>
<string name="backup_category_plain">Còpies de seguretat en text net</string> <string name="backup_category_plain">Còpies de seguretat en text net</string>
<string name="backup_category_crypt">Còpies de seguretat xifrades</string> <string name="backup_category_crypt">Còpies de seguretat xifrades</string>
<string name="backup_category_openpgp">Còpies de seguretat xifrades amb OpenPGP</string> <string name="backup_category_openpgp">Còpies de seguretat xifrades amb OpenPGP</string>
<string name="backup_title_export_plain">Còpia de seguretat (text net)</string> <string name="backup_title_export_plain">Còpia de seguretat (text net)</string>
<string name="backup_title_export_crypt">Còpia de seguretat (xifrada)</string> <string name="backup_title_export_crypt">Còpia de seguretat (xifrada)</string>
<string name="backup_title_export_openpgp">Còpia de seguretat (OpenPGP)</string> <string name="backup_title_export_openpgp">Còpia de seguretat (OpenPGP)</string>
<string name="backup_title_import_plain">Restaura (text net)</string> <string name="backup_title_import_plain">Restaura (text net)</string>
<string name="backup_title_import_crypt">Restaura (xifrada)</string> <string name="backup_title_import_crypt">Restaura (xifrada)</string>
<string name="backup_title_import_openpgp">Restaura (OpenPGP)</string> <string name="backup_title_import_crypt_old">Restaura (encriptat, encriptació vella)</string>
<string name="backup_title_replace">Substitueix els comptes existents</string> <string name="backup_title_import_openpgp">Restaura (OpenPGP)</string>
<string name="backup_desc_export_plain">Fes una còpia de seguretat de tots els comptes en un fitxer de text net JSON</string> <string name="backup_title_replace">Substitueix els comptes existents</string>
<string name="backup_desc_export_crypt">Fes una còpia de seguretat de tots els comptes en un fitxer JSON protegit per contrasenya</string> <string name="backup_desc_export_plain">Fes una còpia de seguretat de tots els comptes en un fitxer de text net JSON</string>
<string name="backup_desc_export_openpgp">Fes una còpia de seguretat tots els comptes en un fitxer JSON encriptat amb OpenPGP</string> <string name="backup_desc_export_crypt">Fes una còpia de seguretat de tots els comptes en un fitxer JSON protegit per contrasenya</string>
<string name="backup_desc_import_plain">Restaura els comptes d\'un fitxer de text net JSON</string> <string name="backup_desc_export_openpgp">Fes una còpia de seguretat tots els comptes en un fitxer JSON encriptat amb OpenPGP</string>
<string name="backup_desc_import_crypt">Restaura els comptes d\'un fitxer JSON protegit amb contrasenya</string> <string name="backup_desc_import_plain">Restaura els comptes d\'un fitxer de text net JSON</string>
<string name="backup_desc_import_openpgp">Restaura els comptes d\'un fitxer JSON xifrat amb OpenPGP</string> <string name="backup_desc_import_crypt">Restaura els comptes d\'un fitxer JSON protegit amb contrasenya</string>
<string name="backup_desc_crypt_setup">Failed to load the backup password from the <b>Settings</b>, <string name="backup_desc_import_crypt_old">Restaura el conte desde un ficher JSON protegit amb contrasenya
creat amb <b>una versió de andOTP prévia a 0.6.3</b></string>
<string name="backup_desc_import_openpgp">Restaura els comptes d\'un fitxer JSON xifrat amb OpenPGP</string>
<string name="backup_desc_crypt_setup">Failed to load the backup password from the <b>Settings</b>,
this either means no password was set or something went wrong. You will be asked to enter this either means no password was set or something went wrong. You will be asked to enter
the password manually when creating or importing a backup. the password manually when creating or importing a backup.
</string> </string>
<string name="backup_desc_openpgp_provider">You need to install an OpenPGP provider and enable <string name="backup_desc_openpgp_provider">You need to install an OpenPGP provider and enable
it in the <b>Settings</b> to use this feature. it in the <b>Settings</b> to use this feature.
</string> </string>
<string name="backup_desc_openpgp_keyid">You need to select an OpenPGP key in the <b>Settings</b> <string name="backup_desc_openpgp_keyid">You need to select an OpenPGP key in the <b>Settings</b>
before you can create encrypted backups. before you can create encrypted backups.
</string> </string>
<string name="backup_desc_replace">Si està activat les entrades antigues són substituïdes quan s\'importa una <string name="backup_desc_replace">Si està activat les entrades antigues són substituïdes quan s\'importa una
còpia de seguretat i només hi queda la còpia. Si no, les entrades velles i les còpies de seguretat còpia de seguretat i només hi queda la còpia. Si no, les entrades velles i les còpies de seguretat
es fusionen.</string> es fusionen.</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="backup_dialog_title_security_warning">Avís de seguretat</string> <string name="backup_dialog_title_security_warning">Avís de seguretat</string>
<string name="backup_dialog_msg_export_warning">Realment voleu exportar la base de dades com a <string name="backup_dialog_msg_export_warning">Realment voleu exportar la base de dades com a
fitxer de text net JSON? Aquest fitxer contindrà les vostres claus secretes; per favor, manteniu-lo <b>ben protegit</b>! fitxer de text net JSON? Aquest fitxer contindrà les vostres claus secretes; per favor, manteniu-lo <b>ben protegit</b>!
</string> </string>
<string name="backup_receiver_title_backup_failed">Backup failed</string> <string name="backup_receiver_title_backup_failed">Backup failed</string>
<string name="backup_receiver_title_backup_success">Backup successful</string> <string name="backup_receiver_title_backup_success">Backup successful</string>
<string name="backup_receiver_plain_disabled">Plain-text backups are currently not allowed, <string name="backup_receiver_plain_disabled">Plain-text backups are currently not allowed,
please go to the Settings to enable them</string> please go to the Settings to enable them</string>
<string name="backup_receiver_encrypted_disabled">Encrypted backups are currently not allowed, <string name="backup_receiver_encrypted_disabled">Encrypted backups are currently not allowed,
please go to the Settings to enable them</string> please go to the Settings to enable them</string>
<string name="backup_receiver_read_permission_failed">Read permission not granted, please do <string name="backup_receiver_read_permission_failed">Read permission not granted, please do
this before attempting backup</string> this before attempting backup</string>
<string name="backup_receiver_write_permission_failed">Write permission not granted, please do <string name="backup_receiver_write_permission_failed">Write permission not granted, please do
this before attempting backup</string> this before attempting backup</string>
<string name="backup_receiver_custom_encryption_failed">Password/PIN based encryption not <string name="backup_receiver_custom_encryption_failed">Password/PIN based encryption not
supported with broadcast backup</string> supported with broadcast backup</string>
<!-- Notification channels --> <string name="backup_new_format_dialog_title">New encryption method</string>
<string name="notification_channel_name_backup_failed">Automatic backup failed</string> <string name="backup_new_format_dialog_msg">Since version 0.6.3 of andOTP, a <b>new and improved
<string name="notification_channel_name_backup_success">Automatic backup successful</string> encryption method</b> is used for password-protected backups. The old backups can still be
<string name="notification_channel_desc_backup_failed">These notifications are shown when an imported, but it is <b>highly recommended to create new backups with the improved
encryption</b>.\n\nThis message will not be shown again.</string>
<!-- Notification channels -->
<string name="notification_channel_name_backup_failed">Automatic backup failed</string>
<string name="notification_channel_name_backup_success">Automatic backup successful</string>
<string name="notification_channel_desc_backup_failed">These notifications are shown when an
automatic backup has failed for some reason</string> automatic backup has failed for some reason</string>
<string name="notification_channel_desc_backup_success">These notifications are shown when an <string name="notification_channel_desc_backup_success">These notifications are shown when an
automatic backup was successful</string> automatic backup was successful</string>
<!-- Toast messages --> <!-- Toast messages -->
<string name="backup_toast_mkdir_failed">No ha pogut crear el directori de còpia de seguretat</string> <string name="backup_toast_mkdir_failed">No ha pogut crear el directori de còpia de seguretat</string>
<string name="backup_toast_export_success">Exportació a l\'emmagatzematge extern correcta</string> <string name="backup_toast_export_success">Exportació a l\'emmagatzematge extern correcta</string>
<string name="backup_toast_export_failed">L\'exportació a emmagatzematge extern ha fallat</string> <string name="backup_toast_export_failed">L\'exportació a emmagatzematge extern ha fallat</string>
<string name="backup_toast_import_success">Importació des de l\'emmagatzematge extern correcta</string> <string name="backup_toast_import_success">Importació des de l\'emmagatzematge extern correcta</string>
<string name="backup_toast_import_save_failed">No s\'han pogut desar les entrades restaurades</string> <string name="backup_toast_import_save_failed">No s\'han pogut desar les entrades restaurades</string>
<string name="backup_toast_import_decryption_failed">El desxifratge de la còpia ha fallat</string> <string name="backup_toast_import_decryption_failed">El desxifratge de la còpia ha fallat</string>
<string name="backup_toast_import_no_entries">No s\'han trobat cap entrada en les dades importades</string> <string name="backup_toast_import_no_entries">No s\'han trobat cap entrada en les dades importades</string>
<string name="backup_toast_storage_not_accessible">L\'emmagatzematge extern no és accessible actualment</string> <string name="backup_toast_storage_not_accessible">L\'emmagatzematge extern no és accessible actualment</string>
<string name="backup_toast_storage_permissions">Permisos d\'emmagatzematge no concedits</string> <string name="backup_toast_storage_permissions">Permisos d\'emmagatzematge no concedits</string>
<string name="backup_toast_openpgp_error">Error OpenPGP: %s</string> <string name="backup_toast_openpgp_error">Error OpenPGP: %s</string>
<string name="backup_toast_openpgp_not_verified">No s\'ha detectat cap signatura verificada</string> <string name="backup_toast_openpgp_not_verified">No s\'ha detectat cap signatura verificada</string>
<string name="backup_toast_crypt_password_not_set">Password not set, check the <b>Settings</b></string> <string name="backup_toast_crypt_password_not_set">Password not set, check the <b>Settings</b></string>
</resources> </resources>

View file

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="intro_slide1_title">Let\'s get started</string> <string name="intro_slide1_title">Let\'s get started</string>
<string name="intro_slide1_desc">Welcome to <b>andOTP</b>, this wizard will guide you through <string name="intro_slide1_desc">Welcome to <b>andOTP</b>, this wizard will guide you through
the initial setup. Please pay attention and read carefully otherwise you could lose data! the initial setup. Please pay attention and read carefully otherwise you could lose data!
\n\nDon\'t worry, you can still change any of the options later in the <b>Settings</b>.</string> \n\nDon\'t worry, you can still change any of the options later in the <b>Settings</b>.</string>
<string name="intro_slide2_desc">To ensure the security of your accounts <b>andOTP</b> only <string name="intro_slide2_desc">To ensure the security of your accounts <b>andOTP</b> only
stores them in encrypted data files. Here you can choose which method of encryption will be stores them in encrypted data files. Here you can choose which method of encryption will be
used.</string> used.</string>
<string name="intro_slide2_desc_keystore">The KeyStore is a system component of Android for <string name="intro_slide2_desc_keystore">The KeyStore is a system component of Android for
securely storing cryptographic keys. The advantage of this method is that the keys are securely storing cryptographic keys. The advantage of this method is that the keys are
stored separated from the data files and can be backed by hardware cryptography (if your stored separated from the data files and can be backed by hardware cryptography (if your
device supports it). However, as the keys are not stored with the apps data, <b>this method device supports it). However, as the keys are not stored with the apps data, <b>this method
@ -17,21 +17,21 @@
\n\n<b>Warning</b>: The KeyStore is known to cause a lot of problems, please only use it if \n\n<b>Warning</b>: The KeyStore is known to cause a lot of problems, please only use it if
you absolutely have to. If you don\'t mind entering a password / PIN every time you start you absolutely have to. If you don\'t mind entering a password / PIN every time you start
<b>andOTP</b> it is <b>highly recommended to use the password-based encryption instead</b>.</string> <b>andOTP</b> it is <b>highly recommended to use the password-based encryption instead</b>.</string>
<string name="intro_slide2_desc_password">This method will encrypt your data with a key <string name="intro_slide2_desc_password">This method will encrypt your data with a key
generated from a password or PIN. The main advantage here is that this will work with generated from a password or PIN. The main advantage here is that this will work with
external backup solutions (like Titanium) and is much less failure-prone than the KeyStore. external backup solutions (like Titanium) and is much less failure-prone than the KeyStore.
However, you will have to enter your credentials every time you start <b>andOTP</b>.</string> However, you will have to enter your credentials every time you start <b>andOTP</b>.</string>
<string name="intro_slide3_desc_keystore">Here you can setup an authentication to lock <string name="intro_slide3_desc_keystore">Here you can setup an authentication to lock
<b>andOTP</b>. Since you have chosen <b>Android KeyStore</b> as encryption method this is <b>andOTP</b>. Since you have chosen <b>Android KeyStore</b> as encryption method this is
optional.</string> optional.</string>
<string name="intro_slide3_desc_password">Here you can setup an authentication to lock <string name="intro_slide3_desc_password">Here you can setup an authentication to lock
<b>andOTP</b>. Since you have chosen <b>Password / PIN</b> as encryption method you need to <b>andOTP</b>. Since you have chosen <b>Password / PIN</b> as encryption method you need to
set either a password or a PIN to proceed.</string> set either a password or a PIN to proceed.</string>
<string name="intro_slide3_warn_no_password">Please set a password to continue!</string> <string name="intro_slide3_warn_no_password">Please set a password to continue!</string>
<string name="intro_slide3_warn_no_pin">Please set a PIN to continue!</string> <string name="intro_slide3_warn_no_pin">Please set a PIN to continue!</string>
<string name="intro_slide3_warn_confirm_password">Please confirm your password to continue!</string> <string name="intro_slide3_warn_confirm_password">Please confirm your password to continue!</string>
<string name="intro_slide3_warn_confirm_pin">Please confirm your PIN to continue!</string> <string name="intro_slide3_warn_confirm_pin">Please confirm your PIN to continue!</string>
<string name="intro_slide4_title">Finished</string> <string name="intro_slide4_title">Finished</string>
<string name="intro_slide4_desc">Your settings have been saved, you are all set to use <string name="intro_slide4_desc">Your settings have been saved, you are all set to use
<b>andOTP</b> now!</string> <b>andOTP</b> now!</string>
</resources> </resources>

View file

@ -1,74 +1,74 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<!-- Buttons --> <!-- Buttons -->
<string name="button_cancel">Cancel·la</string> <string name="button_cancel">Cancel·la</string>
<string name="button_enter_details">Introduïu-ne els detalls</string> <string name="button_enter_details">Introduïu-ne els detalls</string>
<string name="button_scan_qr">Escaneja un codi QR</string> <string name="button_scan_qr">Escaneja un codi QR</string>
<string name="button_save">Desa</string> <string name="button_save">Desa</string>
<string name="button_new_tag">Etiqueta nova</string> <string name="button_new_tag">Etiqueta nova</string>
<string name="button_settings">Configuració</string> <string name="button_settings">Configuració</string>
<string name="button_all_tags">Totes les etiquetes</string> <string name="button_all_tags">Totes les etiquetes</string>
<string name="button_no_tags">Sense etiquetes</string> <string name="button_no_tags">Sense etiquetes</string>
<!-- Custom formatting --> <!-- Custom formatting -->
<string name="format_custom_period">%d s</string> <string name="format_custom_period">%d s</string>
<!-- Hints --> <!-- Hints -->
<string name="hint_label">Etiqueta</string> <string name="hint_label">Etiqueta</string>
<string name="hint_secret">Secret</string> <string name="hint_secret">Secret</string>
<!-- Labels --> <!-- Labels -->
<string name="label_hidden">Ocult</string> <string name="label_hidden">Ocult</string>
<string name="label_type">Tipus</string> <string name="label_type">Tipus</string>
<string name="label_secret">Secret</string> <string name="label_secret">Secret</string>
<string name="label_period">Període</string> <string name="label_period">Període</string>
<string name="label_digits">Dígits</string> <string name="label_digits">Dígits</string>
<string name="label_counter">Counter</string> <string name="label_counter">Comptador</string>
<string name="label_label">Etiqueta</string> <string name="label_label">Etiqueta</string>
<string name="label_algorithm">Algorisme</string> <string name="label_algorithm">Algorisme</string>
<string name="label_tags">Etiquetes</string> <string name="label_tags">Etiquetes</string>
<string name="label_advanced">Opcions avançades</string> <string name="label_advanced">Opcions avançades</string>
<!-- Drawer --> <!-- Drawer -->
<string name="drawer_open">Mostra les etiquetes</string> <string name="drawer_open">Mostra les etiquetes</string>
<string name="drawer_close">Amaga les etiquetes</string> <string name="drawer_close">Amaga les etiquetes</string>
<!-- Menu --> <!-- Menu -->
<string name="menu_main_about">Quant a</string> <string name="menu_main_about">Quant a</string>
<string name="menu_main_backup">Còpia de seguretat</string> <string name="menu_main_backup">Còpia de seguretat</string>
<string name="menu_main_search">Cerca</string> <string name="menu_main_search">Cerca</string>
<string name="menu_main_settings">Configuració</string> <string name="menu_main_settings">Configuració</string>
<string name="menu_main_sort">Ordena</string> <string name="menu_main_sort">Ordena</string>
<string name="menu_sort_none">Sense ordenar</string> <string name="menu_sort_none">Sense ordenar</string>
<string name="menu_sort_label">Etiqueta</string> <string name="menu_sort_label">Etiqueta</string>
<string name="menu_sort_last_used">Últimes utilitzades</string> <string name="menu_sort_last_used">Últimes utilitzades</string>
<string name="menu_popup_edit_label">Edita l\'etiqueta</string> <string name="menu_popup_edit_label">Edita l\'etiqueta</string>
<string name="menu_popup_change_image">Canvia la imatge</string> <string name="menu_popup_change_image">Canvia la imatge</string>
<string name="menu_popup_edit_tags">Edita etiquetes</string> <string name="menu_popup_edit_tags">Edita etiquetes</string>
<string name="menu_popup_remove">Suprimeix</string> <string name="menu_popup_remove">Suprimeix</string>
<!-- Toast messages --> <!-- Toast messages -->
<string name="toast_auth_failed">Error d\'autenticació. Torneu-ho a intentar!</string> <string name="toast_auth_failed">Error d\'autenticació. Torneu-ho a intentar!</string>
<string name="toast_auth_failed_fatal">L\'autenticació ha fallat, andOTP es tancarà!</string> <string name="toast_auth_failed_fatal">L\'autenticació ha fallat, andOTP es tancarà!</string>
<string name="toast_copied_to_clipboard">Copiat al porta-retalls</string> <string name="toast_copied_to_clipboard">Copiat al porta-retalls</string>
<string name="toast_entry_exists">Aquest element ja existeix</string> <string name="toast_entry_exists">Aquest element ja existeix</string>
<string name="toast_invalid_qr_code">Codi QR no vàlid</string> <string name="toast_invalid_qr_code">Codi QR no vàlid</string>
<string name="toast_encryption_key_empty">No s\'ha carregat la clau de xifratge</string> <string name="toast_encryption_key_empty">No s\'ha carregat la clau de xifratge</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="dialog_title_auth">Autentica</string> <string name="dialog_title_auth">Autentica</string>
<string name="dialog_title_manual_entry">Introduïu-ne els detalls</string> <string name="dialog_title_manual_entry">Introduïu-ne els detalls</string>
<string name="dialog_title_remove">Suprimeix</string> <string name="dialog_title_remove">Suprimeix</string>
<string name="dialog_title_rename">Canvia el nom</string> <string name="dialog_title_rename">Canvia el nom</string>
<string name="dialog_title_counter">Counter</string> <string name="dialog_title_counter">Comptador</string>
<string name="dialog_title_last_used">Últimes utilitzades</string> <string name="dialog_title_last_used">Últimes utilitzades</string>
<string name="dialog_title_keystore_error">Error al magatzem de claus</string> <string name="dialog_title_keystore_error">Error al magatzem de claus</string>
<string name="dialog_title_enter_password">Enter password</string> <string name="dialog_title_enter_password">Introduïu la contrasenya</string>
<string name="dialog_label_enter_password">Enter password</string> <string name="dialog_label_enter_password">Introduïu la contrasenya</string>
<string name="dialog_label_confirm_password">Confirm password</string> <string name="dialog_label_confirm_password">Confirmeu la contrasenya</string>
<string name="dialog_msg_auth">Per favor, introduïu les vostres credencials per a iniciar andOTP.</string> <string name="dialog_msg_auth">Per favor, introduïu les vostres credencials per a iniciar andOTP.</string>
<string name="dialog_msg_confirm_delete">Segur que voleu suprimir el compte \"%1$s\"?</string> <string name="dialog_msg_confirm_delete">Segur que voleu suprimir el compte \"%1$s\"?</string>
<string name="dialog_msg_last_used">Per tal que andOTP reconega quin testimoni va ser l\'últim <string name="dialog_msg_last_used">Per tal que andOTP reconega quin testimoni va ser l\'últim
heu d\'habilitar \"toqueu per a mostrar\" o feu servir el botó de copia.\n\nAquest missatge no tornarà heu d\'habilitar \"toqueu per a mostrar\" o feu servir el botó de copia.\n\nAquest missatge no tornarà
a aparéixer.</string> a aparéixer.</string>
<string name="dialog_msg_keystore_error">Failed to load the encryption key from the KeyStore. <string name="dialog_msg_keystore_error">No s\'ha pogut carregar la clau de xifratge del KeyStore.
<b>Any entries that are added will get lost.</b>\n\nTo still be able to use andOTP you can go <b>Qualsevol entrada que s\'hi hagin afegit es perdrà.</b>\n\nPer a continuar usant andOTP, podeu
to the <b>Settings</b> and switch the <b>Database encryption</b> to <b>Password / PIN</b>.</string> anar a la <b>Configuració</b> i canviar el <b>xifratge de la base de dades</b> a <b>Contrasenyes / PIN</b>.</string>
<!-- Shortcuts --> <!-- Shortcuts -->
<string name="shortcut_name_scan_qr">Escaneja un codi QR</string> <string name="shortcut_name_scan_qr">Escaneja un codi QR</string>
<string name="shortcut_name_enter_details">Enter details</string> <string name="shortcut_name_enter_details">Introduïu-ne els detalls</string>
</resources> </resources>

View file

@ -1,158 +1,158 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="settings_activity_title">Configuració</string> <string name="settings_activity_title">Configuració</string>
<!-- Categories --> <!-- Categories -->
<string name="settings_category_title_security">Seguretat</string> <string name="settings_category_title_security">Seguretat</string>
<string name="settings_category_title_ui">Interfície d\'usuari</string> <string name="settings_category_title_ui">Interfície d\'usuari</string>
<string name="settings_category_title_backup">Còpia de seguretat</string> <string name="settings_category_title_backup">Còpia de seguretat</string>
<!-- Titles --> <!-- Titles -->
<string name="settings_title_tap_to_reveal">Toqueu per a mostrar</string> <string name="settings_title_tap_to_reveal">Toqueu per a mostrar</string>
<string name="settings_title_tap_to_reveal_timeout">Temps d\'espera per a \"toqueu per a mostrar\"</string> <string name="settings_title_tap_to_reveal_timeout">Temps d\'espera per a \"toqueu per a mostrar\"</string>
<string name="settings_title_auth">Autenticació</string> <string name="settings_title_auth">Autenticació</string>
<string name="settings_title_auth_password">Contrasenya</string> <string name="settings_title_auth_password">Contrasenya</string>
<string name="settings_title_auth_pin">PIN</string> <string name="settings_title_auth_pin">PIN</string>
<string name="settings_title_encryption">Xifratge de la base de dades</string> <string name="settings_title_encryption">Xifratge de la base de dades</string>
<string name="settings_title_panic">Botó del pànic</string> <string name="settings_title_panic">Botó del pànic</string>
<string name="settings_title_relock_screen_off">Re-lock on screen off</string> <string name="settings_title_relock_screen_off">Re-lock on screen off</string>
<string name="settings_title_lang">Idioma</string> <string name="settings_title_lang">Idioma</string>
<string name="settings_title_theme">Tema</string> <string name="settings_title_theme">Tema</string>
<string name="settings_title_label_size">Mida de la lletra de l\'etiqueta</string> <string name="settings_title_label_size">Mida de la lletra de l\'etiqueta</string>
<string name="settings_title_label_scroll">Permet el desplaçament a les etiquetes</string> <string name="settings_title_label_scroll">Permet el desplaçament a les etiquetes</string>
<string name="settings_title_thumbnail_size_ask">Mida de la miniatura</string> <string name="settings_title_thumbnail_size_ask">Mida de la miniatura</string>
<string name="settings_title_split_group_size">Separa el testimoni amb espais</string> <string name="settings_title_split_group_size">Separa el testimoni amb espais</string>
<string name="settings_title_tag_functionality">Tag selection behavior</string> <string name="settings_title_tag_functionality">Tag selection behavior</string>
<string name="settings_title_backup_append_date">Append date to filename</string> <string name="settings_title_backup_append_date">Append date to filename</string>
<string name="settings_title_backup_ask">Demana el nom de fitxer</string> <string name="settings_title_backup_ask">Demana el nom de fitxer</string>
<string name="settings_title_backup_directory">Directori de còpia de seguretat</string> <string name="settings_title_backup_directory">Directori de còpia de seguretat</string>
<string name="settings_title_backup_password">Contrasenya de la còpia de seguretat</string> <string name="settings_title_backup_password">Contrasenya de la còpia de seguretat</string>
<string name="settings_title_backup_broadcasts">Backup Broadcasts</string> <string name="settings_title_backup_broadcasts">Backup Broadcasts</string>
<string name="settings_title_openpgp_provider">OpenPGP provider</string> <string name="settings_title_openpgp_provider">OpenPGP provider</string>
<string name="settings_title_openpgp_key_encrypt">OpenPGP encryption key</string> <string name="settings_title_openpgp_key_encrypt">OpenPGP encryption key</string>
<string name="settings_title_openpgp_key_sign">OpenPGP signing key (optional)</string> <string name="settings_title_openpgp_key_sign">OpenPGP signing key (optional)</string>
<string name="settings_title_openpgp_verify">Verifica les còpies de seguretat xifrades</string> <string name="settings_title_openpgp_verify">Verifica les còpies de seguretat xifrades</string>
<string name="settings_title_special_features">Habilita les característiques especials</string> <string name="settings_title_special_features">Habilita les característiques especials</string>
<string name="settings_title_enable_screenshot">Permet screenshots</string> <string name="settings_title_enable_screenshot">Permet screenshots</string>
<string name="settings_title_enable_android_backup_service">Enable Android sync</string> <string name="settings_title_enable_android_backup_service">Enable Android sync</string>
<string name="settings_title_clear_keystore">Neteja el magatzem de claus</string> <string name="settings_title_clear_keystore">Neteja el magatzem de claus</string>
<!-- Descriptions --> <!-- Descriptions -->
<string name="settings_desc_tap_to_reveal">Amaga els testimonis OTP per defecte, caldrà <string name="settings_desc_tap_to_reveal">Amaga els testimonis OTP per defecte, caldrà
mostrar-los manualment</string> mostrar-los manualment</string>
<string name="settings_desc_tap_to_reveal_timeout">Indiqueu durant quant de temps (en segons) <string name="settings_desc_tap_to_reveal_timeout">Indiqueu durant quant de temps (en segons)
es mostraran les entrades</string> es mostraran les entrades</string>
<string name="settings_desc_panic">Decidiu què fer quan es prem el botó del pànic</string> <string name="settings_desc_panic">Decidiu què fer quan es prem el botó del pànic</string>
<string name="settings_desc_relock_screen_off">Require authentication after the devices screen <string name="settings_desc_relock_screen_off">Require authentication after the devices screen
has been turned off</string> has been turned off</string>
<string name="settings_desc_label_scroll">Les etiquetes llargues es desplacen en comptes de truncar-les</string> <string name="settings_desc_label_scroll">Les etiquetes llargues es desplacen en comptes de truncar-les</string>
<string name="settings_desc_backup_append_date">Append the current date and time to the suggested <string name="settings_desc_backup_append_date">Append the current date and time to the suggested
backup filename</string> backup filename</string>
<string name="settings_desc_backup_ask">Demana el nom del fitxer cada vegada que es crea o restaura una còpia de seguretat</string> <string name="settings_desc_backup_ask">Demana el nom del fitxer cada vegada que es crea o restaura una còpia de seguretat</string>
<string name="settings_desc_backup_directory">Directori per a les còpies de seguretat (el nom dels fitxers <string name="settings_desc_backup_directory">Directori per a les còpies de seguretat (el nom dels fitxers
depén del tipus de còpia)</string> depén del tipus de còpia)</string>
<string name="settings_desc_backup_password">Contrasenya que s\'usarà per a xifrar les <string name="settings_desc_backup_password">Contrasenya que s\'usarà per a xifrar les
còpies de seguretat</string> còpies de seguretat</string>
<string name="settings_desc_backup_broadcasts">Select which backup types can be triggered by <string name="settings_desc_backup_broadcasts">Select which backup types can be triggered by
3rd-party apps using Broadcasts</string> 3rd-party apps using Broadcasts</string>
<string name="settings_desc_openpgp_key_encrypt">Mail address of the OpenPGP key used to encrypt <string name="settings_desc_openpgp_key_encrypt">Mail address of the OpenPGP key used to encrypt
the backups</string> the backups</string>
<string name="settings_desc_openpgp_verify">Només s\'importaran còipes xifrades si s\'han <string name="settings_desc_openpgp_verify">Només s\'importaran còipes xifrades si s\'han
signat amb una clau vàlida</string> signat amb una clau vàlida</string>
<string name="settings_desc_special_features">Desmarqueu per a deshabilitar les característiques especials</string> <string name="settings_desc_special_features">Desmarqueu per a deshabilitar les característiques especials</string>
<string name="settings_desc_enable_screenshot">Permet fer captures de la pantalla principal <string name="settings_desc_enable_screenshot">Permet fer captures de la pantalla principal
(desactivat per defecte per motius de seguretat)</string> (desactivat per defecte per motius de seguretat)</string>
<string name="settings_desc_enable_android_backup_service">Enables andOTP to use Android\'s <string name="settings_desc_enable_android_backup_service">Enables andOTP to use Android\'s
built in backup service to backup keys and preferences</string> built in backup service to backup keys and preferences</string>
<string name="settings_desc_clear_keystore">Esborra la clau d\'encriptació del magatzem de claus</string> <string name="settings_desc_clear_keystore">Esborra la clau d\'encriptació del magatzem de claus</string>
<!-- Toasts --> <!-- Toasts -->
<string name="settings_toast_auth_device_pre_lollipop">Aquesta característica només funciona amb <string name="settings_toast_auth_device_pre_lollipop">Aquesta característica només funciona amb
Android 5.0 (Lollipop) o superior</string> Android 5.0 (Lollipop) o superior</string>
<string name="settings_toast_auth_device_not_secure">Aquesta característica requereix un bloqueig de pantalla <string name="settings_toast_auth_device_not_secure">Aquesta característica requereix un bloqueig de pantalla
segur (Configuració -&gt; Seguretat -&gt; Bloqueig de pantalla)</string> segur (Configuració -&gt; Seguretat -&gt; Bloqueig de pantalla)</string>
<string name="settings_toast_password_empty">Les contrasenyes buides no són permeses, <string name="settings_toast_password_empty">Les contrasenyes buides no són permeses,
trieu autenticació nul·la per a desactivar-la!</string> trieu autenticació nul·la per a desactivar-la!</string>
<string name="settings_toast_encryption_changing">S\'està mirant de canviar el xifratge de la base de dades; <string name="settings_toast_encryption_changing">S\'està mirant de canviar el xifratge de la base de dades;
per favor, espereu!</string> per favor, espereu!</string>
<string name="settings_toast_encryption_change_success">S\'ha canviat el xifratge de la base de <string name="settings_toast_encryption_change_success">S\'ha canviat el xifratge de la base de
dades amb èxit!</string> dades amb èxit!</string>
<string name="settings_toast_encryption_change_failed">No ha estat possible canviar el xifratge de la <string name="settings_toast_encryption_change_failed">No ha estat possible canviar el xifratge de la
base de dades: romandrà en l\'estat original!</string> base de dades: romandrà en l\'estat original!</string>
<string name="settings_toast_encryption_backup_failed">No ha estat possible crear la còpia <string name="settings_toast_encryption_backup_failed">No ha estat possible crear la còpia
interna, s\'ha interromput!</string> interna, s\'ha interromput!</string>
<string name="settings_toast_encryption_no_key">No ha estat possible obtenir la clau de xifratge, s\'ha interromput!</string> <string name="settings_toast_encryption_no_key">No ha estat possible obtenir la clau de xifratge, s\'ha interromput!</string>
<string name="settings_toast_encryption_auth_failed">Ha fallat l\'autenticació!</string> <string name="settings_toast_encryption_auth_failed">Ha fallat l\'autenticació!</string>
<string name="settings_toast_auth_upgrade_failed">Ha fallat l\'actualització automàtica de la contrasenya / PIN <string name="settings_toast_auth_upgrade_failed">Ha fallat l\'actualització automàtica de la contrasenya / PIN
per al nou xifratge; per favor, reinicialitzeu-la manualment en la configuració!</string> per al nou xifratge; per favor, reinicialitzeu-la manualment en la configuració!</string>
<string name="settings_dialog_title_warning">Warning</string> <string name="settings_dialog_title_warning">Warning</string>
<string name="settings_dialog_title_error">Error</string> <string name="settings_dialog_title_error">Error</string>
<string name="settings_dialog_title_clear_keystore">Voleu neteja el magatzem de claus?</string> <string name="settings_dialog_title_clear_keystore">Voleu neteja el magatzem de claus?</string>
<string name="settings_dialog_title_android_sync">Android sync</string> <string name="settings_dialog_title_android_sync">Android sync</string>
<string name="settings_dialog_msg_encryption_change">andOTP will now try to change the database <string name="settings_dialog_msg_encryption_change">andOTP will now try to change the database
encryption. In case of a failure an internal backup will be restored and the encryption encryption. In case of a failure an internal backup will be restored and the encryption
remains unchanged.\n\n<b>However, it\'s always a good idea to have a backup in case remains unchanged.\n\n<b>However, it\'s always a good idea to have a backup in case
something unexpected happens!</b></string> something unexpected happens!</b></string>
<string name="settings_dialog_msg_auth_invalid_with_encryption">Només podeu usar una contrasenya o un PIN <string name="settings_dialog_msg_auth_invalid_with_encryption">Només podeu usar una contrasenya o un PIN
si el xifratge de la base de dades s\'ha establert a \"contrasenya / PIN\"!</string> si el xifratge de la base de dades s\'ha establert a \"contrasenya / PIN\"!</string>
<string name="settings_dialog_msg_encryption_invalid_with_auth">Primer cal definir l\'autenticació a \"contrasenya\" o \"PIN\"!</string> <string name="settings_dialog_msg_encryption_invalid_with_auth">Primer cal definir l\'autenticació a \"contrasenya\" o \"PIN\"!</string>
<string name="settings_dialog_msg_encryption_invalid_without_credentials">Cal establir una contrasenya o PIN abans de canviar l\'encriptació!</string> <string name="settings_dialog_msg_encryption_invalid_without_credentials">Cal establir una contrasenya o PIN abans de canviar l\'encriptació!</string>
<string name="settings_dialog_msg_clear_keystore_password">En alguns casos, netejar el magatzem de claus <string name="settings_dialog_msg_clear_keystore_password">En alguns casos, netejar el magatzem de claus
pot ajudar a resoldre problemes. Feu-ho només si sabeu què feu!\\n\nAtés que el xifratge de la <b>base de dades</b> està definit a <b>contrasenya / PIN</b> no hauríeu de perdre-hi pot ajudar a resoldre problemes. Feu-ho només si sabeu què feu!\\n\nAtés que el xifratge de la <b>base de dades</b> està definit a <b>contrasenya / PIN</b> no hauríeu de perdre-hi
dades (fer una cópia de seguretat sempre va bé, però).\n\n<b>Segur que voleu netejar dades (fer una cópia de seguretat sempre va bé, però).\n\n<b>Segur que voleu netejar
el magatzem de claus (KeyStore)?</b></string> el magatzem de claus (KeyStore)?</b></string>
<string name="settings_dialog_msg_clear_keystore_keystore">En alguns casos, netejar el magatzem de claus <string name="settings_dialog_msg_clear_keystore_keystore">En alguns casos, netejar el magatzem de claus
pot ajudar a resoldre problemes. Feu-ho només si sabeu què feu!\\n\n<b>Alerta</b>: pot ajudar a resoldre problemes. Feu-ho només si sabeu què feu!\\n\n<b>Alerta</b>:
Atés que el xifratge de la <b>base de dades</b> està definit a <b>Android KeyStore</b> perdreu tots els Atés que el xifratge de la <b>base de dades</b> està definit a <b>Android KeyStore</b> perdreu tots els
comptes. Comproveu que n\'heu fet una còpia!\n\n<b>Segur que voleu netejar el magatzem de claus comptes. Comproveu que n\'heu fet una còpia!\n\n<b>Segur que voleu netejar el magatzem de claus
(KeyStore)?</b></string> (KeyStore)?</b></string>
<string name="settings_dialog_msg_android_sync_disabled_encryption">Android sync can not be used with keystore <string name="settings_dialog_msg_android_sync_disabled_encryption">Android sync can not be used with keystore
encryption, <b>you should perform a manual backup!</b></string> encryption, <b>you should perform a manual backup!</b></string>
<!-- List entries --> <!-- List entries -->
<string-array name="settings_entries_auth"> <string-array name="settings_entries_auth">
<item>Cap</item> <item>Cap</item>
<item>Contrasenya</item> <item>Contrasenya</item>
<item>PIN</item> <item>PIN</item>
<item>Credencials del dispositiu</item> <item>Credencials del dispositiu</item>
</string-array> </string-array>
<string-array name="settings_entries_encryption"> <string-array name="settings_entries_encryption">
<item>Android KeyStore</item> <item>Android KeyStore</item>
<item>Contrasenya / PIN</item> <item>Contrasenya / PIN</item>
</string-array> </string-array>
<string-array name="settings_entries_panic"> <string-array name="settings_entries_panic">
<item>Suprimeix tots els comptes</item> <item>Suprimeix tots els comptes</item>
<item>Reinicialitza les opcions de l\'aplicació</item> <item>Reinicialitza les opcions de l\'aplicació</item>
</string-array> </string-array>
<string-array name="settings_entries_theme"> <string-array name="settings_entries_theme">
<item>Tema clar</item> <item>Tema clar</item>
<item>Tema fosc</item> <item>Tema fosc</item>
<item>Tema negre</item> <item>Tema negre</item>
</string-array> </string-array>
<string-array name="settings_entries_thumbnail_size"> <string-array name="settings_entries_thumbnail_size">
<item>Ocult</item> <item>Ocult</item>
<item>Petita</item> <item>Petita</item>
<item>Per defecte</item> <item>Per defecte</item>
<item>Mitjana</item> <item>Mitjana</item>
<item>Grossa</item> <item>Grossa</item>
</string-array> </string-array>
<string-array name="settings_entries_split_group_size"> <string-array name="settings_entries_split_group_size">
<item>No dividir</item> <item>No dividir</item>
<item>Després de dos caràcters</item> <item>Després de dos caràcters</item>
<item>Després de tres caràcters</item> <item>Després de tres caràcters</item>
</string-array> </string-array>
<string-array name="settings_entries_tag_functionality"> <string-array name="settings_entries_tag_functionality">
<item>Show all entries matching <b>any</b> of the selected tags (or)</item> <item>Show all entries matching <b>any</b> of the selected tags (or)</item>
<item>Only show entries matching <b>all</b> of the selected tags (and)</item> <item>Only show entries matching <b>all</b> of the selected tags (and)</item>
<item>Switch between tags (only allow one tag to be selected at a time)</item> <item>Switch between tags (only allow one tag to be selected at a time)</item>
</string-array> </string-array>
<string-array name="settings_entries_backup_broadcasts"> <string-array name="settings_entries_backup_broadcasts">
<item>Plain-text backups</item> <item>Plain-text backups</item>
<item>Encrypted backups</item> <item>Encrypted backups</item>
</string-array> </string-array>
<!-- Special --> <!-- Special -->
<string name="settings_lang_sys_default">Valor del sistema per defecte</string> <string name="settings_lang_sys_default">Valor del sistema per defecte</string>
<!-- PasswordPreference --> <!-- PasswordPreference -->
<string name="settings_hint_password">Introduïu la contrasenya nova</string> <string name="settings_hint_password">Introduïu la contrasenya nova</string>
<string name="settings_hint_pin">Introduïu el PIN nou</string> <string name="settings_hint_pin">Introduïu el PIN nou</string>
<string name="settings_hint_password_confirm">Confirmeu la contrasenya</string> <string name="settings_hint_password_confirm">Confirmeu la contrasenya</string>
<string name="settings_hint_pin_confirm">Confirmeu el PIN</string> <string name="settings_hint_pin_confirm">Confirmeu el PIN</string>
<string name="settings_label_short_password">La contrasenya ha de tenir, si més no, %1$d caràcters!</string> <string name="settings_label_short_password">La contrasenya ha de tenir, si més no, %1$d caràcters!</string>
<string name="settings_label_short_pin">El PIN ha de tindre, si més no, %1$d xifres!</string> <string name="settings_label_short_pin">El PIN ha de tindre, si més no, %1$d xifres!</string>
</resources> </resources>

View file

@ -18,8 +18,7 @@
<string name="about_label_original_author">Autor původní aplikace</string> <string name="about_label_original_author">Autor původní aplikace</string>
<string name="about_label_original_app">Původní aplikace</string> <string name="about_label_original_app">Původní aplikace</string>
<string name="about_label_website">Webová stránka</string> <string name="about_label_website">Webová stránka</string>
<string name="about_label_donate_paypal">Podpořit přes PayPal</string> <string name="about_label_donate">Podpořit</string>
<string name="about_label_donate_bitcoin">Podpořit Bitcoinem</string>
<string name="about_label_contributors">K vývoji přispěli</string> <string name="about_label_contributors">K vývoji přispěli</string>
<string name="about_label_translators">Překladatelé</string> <string name="about_label_translators">Překladatelé</string>
<!-- Thumbnail disclaimer --> <!-- Thumbnail disclaimer -->

View file

@ -10,6 +10,7 @@
<string name="backup_title_export_openpgp">Zálohovat (OpenPGP)</string> <string name="backup_title_export_openpgp">Zálohovat (OpenPGP)</string>
<string name="backup_title_import_plain">Obnovit zálohu (nechráněnou)</string> <string name="backup_title_import_plain">Obnovit zálohu (nechráněnou)</string>
<string name="backup_title_import_crypt">Obnovit zálohu (šifrovanou)</string> <string name="backup_title_import_crypt">Obnovit zálohu (šifrovanou)</string>
<string name="backup_title_import_crypt_old">Obnova (šifrované, staré šifrování)</string>
<string name="backup_title_import_openpgp">Obnovit zálohu (OpenPGP)</string> <string name="backup_title_import_openpgp">Obnovit zálohu (OpenPGP)</string>
<string name="backup_title_replace">Nahrazovat předchozí záznamy</string> <string name="backup_title_replace">Nahrazovat předchozí záznamy</string>
<string name="backup_desc_export_plain">Zálohovat všechny účty do nechráněného souboru JSON</string> <string name="backup_desc_export_plain">Zálohovat všechny účty do nechráněného souboru JSON</string>
@ -17,6 +18,8 @@
<string name="backup_desc_export_openpgp">Zálohovat všechny účty do souboru JSON šifrovaného OpenPGP</string> <string name="backup_desc_export_openpgp">Zálohovat všechny účty do souboru JSON šifrovaného OpenPGP</string>
<string name="backup_desc_import_plain">Obnovit účty z nechráněného souboru JSON</string> <string name="backup_desc_import_plain">Obnovit účty z nechráněného souboru JSON</string>
<string name="backup_desc_import_crypt">Obnovit účty ze souboru JSON chráněného heslem</string> <string name="backup_desc_import_crypt">Obnovit účty ze souboru JSON chráněného heslem</string>
<string name="backup_desc_import_crypt_old">Obnoví účty z JSON souboru chráněného heslem,
který byl vytvořen pomocí <b>verze andOTP nižší než 0.6.3</b></string>
<string name="backup_desc_import_openpgp">Obnovit účty ze souboru JSON šifrovaného OpenPGP</string> <string name="backup_desc_import_openpgp">Obnovit účty ze souboru JSON šifrovaného OpenPGP</string>
<string name="backup_desc_crypt_setup">Nepodařilo se načíst záložní heslo z <b>Nastavení</b>, to buď znamená, že není nastaveno žádné heslo nebo něco se pokazilo. Budete vyzváni k ručnímu zadání hesla při vytváření nebo importu zálohy. <string name="backup_desc_crypt_setup">Nepodařilo se načíst záložní heslo z <b>Nastavení</b>, to buď znamená, že není nastaveno žádné heslo nebo něco se pokazilo. Budete vyzváni k ručnímu zadání hesla při vytváření nebo importu zálohy.
</string> </string>
@ -33,6 +36,10 @@
<string name="backup_receiver_read_permission_failed">Nebylo uděleno oprávnění ke čtení, prosím udělte ho před pokusem o zálohování</string> <string name="backup_receiver_read_permission_failed">Nebylo uděleno oprávnění ke čtení, prosím udělte ho před pokusem o zálohování</string>
<string name="backup_receiver_write_permission_failed">Nebylo uděleno oprávnění k zápisu, prosím udělte ho před pokusem o zálohování</string> <string name="backup_receiver_write_permission_failed">Nebylo uděleno oprávnění k zápisu, prosím udělte ho před pokusem o zálohování</string>
<string name="backup_receiver_custom_encryption_failed">Šifrování heslem/PINem není podporováno v kombinaci s automatizovaným zálohováním</string> <string name="backup_receiver_custom_encryption_failed">Šifrování heslem/PINem není podporováno v kombinaci s automatizovaným zálohováním</string>
<string name="backup_new_format_dialog_title">Nová metoda šifrování</string>
<string name="backup_new_format_dialog_msg">Od veze 0.6.3 se pro ochranu heslem používá <b>nová a vylepšená metoda šifrování</b>
Stále lze importovat staré zálohy, ale <b> velmi se doporučuje vytvořit novou zálohu s vylepšeným šifrováním</b>.
\n\nTato zpráva se již nezobrazí.</string>
<!-- Notification channels --> <!-- Notification channels -->
<string name="notification_channel_name_backup_failed">Automatické zálohování selhalo</string> <string name="notification_channel_name_backup_failed">Automatické zálohování selhalo</string>
<string name="notification_channel_name_backup_success">Automatické zálohování proběhlo úspěšně</string> <string name="notification_channel_name_backup_success">Automatické zálohování proběhlo úspěšně</string>

View file

@ -18,8 +18,7 @@
<string name="about_label_original_author">Autor der ursprünglichen App</string> <string name="about_label_original_author">Autor der ursprünglichen App</string>
<string name="about_label_original_app">Ursprüngliche App</string> <string name="about_label_original_app">Ursprüngliche App</string>
<string name="about_label_website">Webseite</string> <string name="about_label_website">Webseite</string>
<string name="about_label_donate_paypal">Spenden (PayPal)</string> <string name="about_label_donate">Spenden</string>
<string name="about_label_donate_bitcoin">Spenden (Bitcoin)</string>
<string name="about_label_contributors">Mitwirkende</string> <string name="about_label_contributors">Mitwirkende</string>
<string name="about_label_translators">Übersetzer</string> <string name="about_label_translators">Übersetzer</string>
<!-- Thumbnail disclaimer --> <!-- Thumbnail disclaimer -->

View file

@ -10,6 +10,7 @@
<string name="backup_title_export_openpgp">Datensicherung (OpenPGP)</string> <string name="backup_title_export_openpgp">Datensicherung (OpenPGP)</string>
<string name="backup_title_import_plain">Wiederherstellen (Klartext)</string> <string name="backup_title_import_plain">Wiederherstellen (Klartext)</string>
<string name="backup_title_import_crypt">Wiederherstellen (verschlüsselt)</string> <string name="backup_title_import_crypt">Wiederherstellen (verschlüsselt)</string>
<string name="backup_title_import_crypt_old">Datensicherung (verschlüsselt, alte Verschlüsselungsmethode)</string>
<string name="backup_title_import_openpgp">Wiederherstellen (OpenPGP)</string> <string name="backup_title_import_openpgp">Wiederherstellen (OpenPGP)</string>
<string name="backup_title_replace">Vorhandene Einträge ersetzen</string> <string name="backup_title_replace">Vorhandene Einträge ersetzen</string>
<string name="backup_desc_export_plain">Alle Konten in einer Klartext-JSON-Datei sichern</string> <string name="backup_desc_export_plain">Alle Konten in einer Klartext-JSON-Datei sichern</string>
@ -17,6 +18,8 @@
<string name="backup_desc_export_openpgp">Alle Konten in einer OpenPGP-verschlüsselten JSON-Datei sichern</string> <string name="backup_desc_export_openpgp">Alle Konten in einer OpenPGP-verschlüsselten JSON-Datei sichern</string>
<string name="backup_desc_import_plain">Konten aus einer Klartext-JSON-Datei wiederherstellen</string> <string name="backup_desc_import_plain">Konten aus einer Klartext-JSON-Datei wiederherstellen</string>
<string name="backup_desc_import_crypt">Konten aus einer passwortgeschützten JSON-Datei wiederherstellen</string> <string name="backup_desc_import_crypt">Konten aus einer passwortgeschützten JSON-Datei wiederherstellen</string>
<string name="backup_desc_import_crypt_old">Konten aus einer passwortgeschützten JSON-Datei wiederherstellen
erstellt mit einer <b>andOTP-Version unter 0.6.3</b></string>
<string name="backup_desc_import_openpgp">Konten aus einer OpenPGP-verschlüsselten JSON-Datei wiederherstellen</string> <string name="backup_desc_import_openpgp">Konten aus einer OpenPGP-verschlüsselten JSON-Datei wiederherstellen</string>
<string name="backup_desc_crypt_setup">Laden des Backup-Passworts aus den <b>Einstellungen</b> fehlgeschlagen, <string name="backup_desc_crypt_setup">Laden des Backup-Passworts aus den <b>Einstellungen</b> fehlgeschlagen,
was bedeutet, dass entweder kein Passwort gesetzt wurde oder etwas schiefgelaufen ist. was bedeutet, dass entweder kein Passwort gesetzt wurde oder etwas schiefgelaufen ist.
@ -40,6 +43,11 @@
zum Sichern benötigt</string> zum Sichern benötigt</string>
<string name="backup_receiver_custom_encryption_failed">Passwort/PIN Verschlüsselung ist nicht <string name="backup_receiver_custom_encryption_failed">Passwort/PIN Verschlüsselung ist nicht
unterstützt mit Broadcast Datensicherung</string> unterstützt mit Broadcast Datensicherung</string>
<string name="backup_new_format_dialog_title">Neue Verschlüsselungsmethode</string>
<string name="backup_new_format_dialog_msg">Seit Version 0.6.3 von andOTP, wird eine <b>neue und verbesserte
Verschlüsselungsmethode</b> für passwortgeschützte Datensicherungen benutzt. Alte Datensicherungen
können weiterhin importiert werden, aber es wird <b>nachdrücklich empfohlen neue Datensicherungen mit
der verbesserten Verschlüsselung zu erstellen</b>.\n\nDiese Nachricht wird nicht erneut angezeigt.</string>
<!-- Notification channels --> <!-- Notification channels -->
<string name="notification_channel_name_backup_failed">Automatische Sicherung fehlgeschlagen</string> <string name="notification_channel_name_backup_failed">Automatische Sicherung fehlgeschlagen</string>
<string name="notification_channel_name_backup_success">Automatische Sicherung erfolgreich</string> <string name="notification_channel_name_backup_success">Automatische Sicherung erfolgreich</string>

View file

@ -18,8 +18,7 @@
<string name="about_label_original_author">Autor de la aplicación original</string> <string name="about_label_original_author">Autor de la aplicación original</string>
<string name="about_label_original_app">Aplicación original</string> <string name="about_label_original_app">Aplicación original</string>
<string name="about_label_website">Página web</string> <string name="about_label_website">Página web</string>
<string name="about_label_donate_paypal">Donar (PayPal)</string> <string name="about_label_donate">Donar</string>
<string name="about_label_donate_bitcoin">Donar (Bitcoin)</string>
<string name="about_label_contributors">Contribuidores</string> <string name="about_label_contributors">Contribuidores</string>
<string name="about_label_translators">Traductores</string> <string name="about_label_translators">Traductores</string>
<!-- Thumbnail disclaimer --> <!-- Thumbnail disclaimer -->

View file

@ -10,6 +10,7 @@
<string name="backup_title_export_openpgp">Copia de seguridad (OpenPGP)</string> <string name="backup_title_export_openpgp">Copia de seguridad (OpenPGP)</string>
<string name="backup_title_import_plain">Restaurar (texto plano)</string> <string name="backup_title_import_plain">Restaurar (texto plano)</string>
<string name="backup_title_import_crypt">Restaurar (cifradas)</string> <string name="backup_title_import_crypt">Restaurar (cifradas)</string>
<string name="backup_title_import_crypt_old">Restaurar (cifrado, antiguo cifrado)</string>
<string name="backup_title_import_openpgp">Restaurar (OpenPGP)</string> <string name="backup_title_import_openpgp">Restaurar (OpenPGP)</string>
<string name="backup_title_replace">Reemplazar entradas existentes</string> <string name="backup_title_replace">Reemplazar entradas existentes</string>
<string name="backup_desc_export_plain">Hace copia de seguridad de todas las cuentas en un fichero JSON de texto plano</string> <string name="backup_desc_export_plain">Hace copia de seguridad de todas las cuentas en un fichero JSON de texto plano</string>
@ -17,6 +18,8 @@
<string name="backup_desc_export_openpgp">Hace copia de seguridad de todas las cuentas en un fichero JSON cifrado con OpenPGP</string> <string name="backup_desc_export_openpgp">Hace copia de seguridad de todas las cuentas en un fichero JSON cifrado con OpenPGP</string>
<string name="backup_desc_import_plain">Restaurar cuentas desde fichero JSON de texto plano</string> <string name="backup_desc_import_plain">Restaurar cuentas desde fichero JSON de texto plano</string>
<string name="backup_desc_import_crypt">Restaurar cuentas desde fichero JSON con contraseña</string> <string name="backup_desc_import_crypt">Restaurar cuentas desde fichero JSON con contraseña</string>
<string name="backup_desc_import_crypt_old">Restaurar cuentas de un archivo JSON protegido por contraseña
creado con una <b>versión de andOTP inferior a 0.6.3</b></string>
<string name="backup_desc_import_openpgp">Restaurar cuentas desde fichero JSON cifrado con OpenPGP</string> <string name="backup_desc_import_openpgp">Restaurar cuentas desde fichero JSON cifrado con OpenPGP</string>
<string name="backup_desc_crypt_setup">Error al cargar la contraseña del respaldo de los <b>Ajustes</b>, esto puede deberse a que no se ha establecido una contraseña o a que algo ha salido mal. Se te pedirá que ingreses la contraseña manualmente cuando crees o importes un respaldo. </string> <string name="backup_desc_crypt_setup">Error al cargar la contraseña del respaldo de los <b>Ajustes</b>, esto puede deberse a que no se ha establecido una contraseña o a que algo ha salido mal. Se te pedirá que ingreses la contraseña manualmente cuando crees o importes un respaldo. </string>
<string name="backup_desc_openpgp_provider">Necesitas instalar un proveedor de OpenPGP y activarlo <string name="backup_desc_openpgp_provider">Necesitas instalar un proveedor de OpenPGP y activarlo
@ -43,6 +46,11 @@
hazlo antes de intentar hacer una copia de seguridad</string> hazlo antes de intentar hacer una copia de seguridad</string>
<string name="backup_receiver_custom_encryption_failed">Cifrado basado en clave/PIN no <string name="backup_receiver_custom_encryption_failed">Cifrado basado en clave/PIN no
soportado en la copia de seguridad de difusión</string> soportado en la copia de seguridad de difusión</string>
<string name="backup_new_format_dialog_title">Nuevo método de cifrado</string>
<string name="backup_new_format_dialog_msg">A partir de la versión 0.6.3 de andOTP, se utiliza un <b>nuevo y mejorado
método de cifrado</b> para copias de seguridad protegidas por contraseña. Las copias de seguridad antiguas aún pueden ser
importadas, pero es <b>sumamente recomendable crear nuevas copias de seguridad con
el cifrado mejorado</b>.\n\nEste mensaje no se mostrará nuevamente.</string>
<!-- Notification channels --> <!-- Notification channels -->
<string name="notification_channel_name_backup_failed">Falló la copia de seguridad automática</string> <string name="notification_channel_name_backup_failed">Falló la copia de seguridad automática</string>
<string name="notification_channel_name_backup_success">La copia de seguridad automática se realizó con éxito</string> <string name="notification_channel_name_backup_success">La copia de seguridad automática se realizó con éxito</string>

View file

@ -7,7 +7,7 @@
\n\nNo te preocupes, siempre podrás modificar la configuración en los <b>Ajustes</b>.</string> \n\nNo te preocupes, siempre podrás modificar la configuración en los <b>Ajustes</b>.</string>
<string name="intro_slide2_desc">Para asegurar la seguridad de tus cuentas <b>andOTP</b> solo las almacena <string name="intro_slide2_desc">Para asegurar la seguridad de tus cuentas <b>andOTP</b> solo las almacena
en ficheros cifrados. Aquí puedes elegir qué método de cifrado se usará.</string> en ficheros cifrados. Aquí puedes elegir qué método de cifrado se usará.</string>
<string name="intro_slide2_desc_keystore">El almacén de claves es una herramienta de Android que permite almacenar claves criptográficas con seguridad. La ventaja de este método es que las llaves se almacenan apartadas de los archivos y pueden ser respaldadas con criptografía por hardware (si tienes un dispositivo compatible). Sin embargo, ya que las claves no se almacenan en los archivos de la aplicación, <b>este método no es compatible con copias de seguridad externas (como Titanium) </b>. Si eliges este método, te verás limitado a las copias de respaldo de <b>andOTP</b>. \n\n<b>Atención</b>: El almacén de claves suele causar problemas, por favor, evita usarlo a menos que realmente tengas que hacerlo. Si no te importa ingresar una contraseña / PIN cuando inicias <b>andOTP</b>, es <b>altamente recomendable que utilices la encriptación por contraseña</b>.</string> <string name="intro_slide2_desc_keystore">El almacén de claves es una herramienta de Android que permite almacenar claves criptográficas con seguridad. La ventaja de este método es que las llaves se almacenan apartadas de los archivos y pueden ser respaldadas con criptografía por hardware (si tienes un dispositivo compatible). Sin embargo, ya que las claves no se almacenan en los archivos de la aplicación, &lt;b&gt;este método no es compatible con copias de seguridad externas (como Titanium) &lt;/b&gt;. Si eliges este método, te verás limitado a las copias de respaldo de &lt;b&gt;andOTP&lt;/b&gt;. \n\n&lt;b&gt;Atención&lt;/b&gt;: El almacén de claves suele causar problemas, por favor, evita usarlo a menos que realmente tengas que hacerlo. Si no te importa ingresar una contraseña / PIN cuando inicias &lt;b&gt;andOTP&lt;/b&gt;, es &lt;b&gt;altamente recomendable que utilices la encriptación por contraseña&lt;b&gt;.</string>
<string name="intro_slide2_desc_password">Este método cifrará tus datos con una clave <string name="intro_slide2_desc_password">Este método cifrará tus datos con una clave
generada desde una contraseña o PIN. La ventaja principal es que funcionará con generada desde una contraseña o PIN. La ventaja principal es que funcionará con
herramientas de copia de seguridad externas (como Titanium) y da menos problemas que el almacen de claves. herramientas de copia de seguridad externas (como Titanium) y da menos problemas que el almacen de claves.

View file

@ -18,8 +18,7 @@
<string name="about_label_original_author">سازنده برنامه اصلی</string> <string name="about_label_original_author">سازنده برنامه اصلی</string>
<string name="about_label_original_app">برنامه اصلی</string> <string name="about_label_original_app">برنامه اصلی</string>
<string name="about_label_website">وب‌سایت</string> <string name="about_label_website">وب‌سایت</string>
<string name="about_label_donate_paypal">حمایت مالی (PayPal)</string> <string name="about_label_donate">حمایت مالی</string>
<string name="about_label_donate_bitcoin">حمایت مالی (Bitcoin)</string>
<string name="about_label_contributors">مشارکت‌کنندگان</string> <string name="about_label_contributors">مشارکت‌کنندگان</string>
<string name="about_label_translators">مترجمان</string> <string name="about_label_translators">مترجمان</string>
<!-- Thumbnail disclaimer --> <!-- Thumbnail disclaimer -->

View file

@ -10,6 +10,7 @@
<string name="backup_title_export_openpgp">پشتیبان‌گیری (OpenPGP)</string> <string name="backup_title_export_openpgp">پشتیبان‌گیری (OpenPGP)</string>
<string name="backup_title_import_plain">بازنشانی (متن ساده)</string> <string name="backup_title_import_plain">بازنشانی (متن ساده)</string>
<string name="backup_title_import_crypt">بازنشانی (رمزگذاری شده)</string> <string name="backup_title_import_crypt">بازنشانی (رمزگذاری شده)</string>
<string name="backup_title_import_crypt_old">بازگردانی (رمزگذاری شده، رمزگذاری قدیمی)</string>
<string name="backup_title_import_openpgp">بازنشانی (OpenPGP)</string> <string name="backup_title_import_openpgp">بازنشانی (OpenPGP)</string>
<string name="backup_title_replace">موارد موجود را جایگزین کن</string> <string name="backup_title_replace">موارد موجود را جایگزین کن</string>
<string name="backup_desc_export_plain">پشتیبان‌گیری از همه حساب‌ها در پرونده JSON متن ساده</string> <string name="backup_desc_export_plain">پشتیبان‌گیری از همه حساب‌ها در پرونده JSON متن ساده</string>
@ -17,6 +18,7 @@
<string name="backup_desc_export_openpgp">پشتیبان‌گیری از همه حساب‌ها در پرونده JSON رمزگذاری شده با OpenPGP</string> <string name="backup_desc_export_openpgp">پشتیبان‌گیری از همه حساب‌ها در پرونده JSON رمزگذاری شده با OpenPGP</string>
<string name="backup_desc_import_plain">بازنشانی از پرونده JSON متن ساده</string> <string name="backup_desc_import_plain">بازنشانی از پرونده JSON متن ساده</string>
<string name="backup_desc_import_crypt">بازنشانی از پرونده JSON رمز دار</string> <string name="backup_desc_import_crypt">بازنشانی از پرونده JSON رمز دار</string>
<string name="backup_desc_import_crypt_old">بازگردانی حساب‌خا از پرونده JSON محافظت‌شده با رمز ساخته شده با یک <b>andOTP با نسخه پایین‌تر از ۰.۶.۳</b></string>
<string name="backup_desc_import_openpgp">بازنشانی از پرونده JSON رمزگذاری شده با OpenPGP</string> <string name="backup_desc_import_openpgp">بازنشانی از پرونده JSON رمزگذاری شده با OpenPGP</string>
<string name="backup_desc_crypt_setup">شکست در بارگیری رمز عبور پشتیبان از <b>تنظیمات</b>، این به معنای عدم وجود رمز عبور است یا اشکالی پیش آمده. زمانی که شما یک پشتیبان می‌سازید یا یک پشتیبان وارد می‌کنید، از شما خواسته خواهد شد تا رمز عبور را به صورت دستی وارد کنید. </string> <string name="backup_desc_crypt_setup">شکست در بارگیری رمز عبور پشتیبان از <b>تنظیمات</b>، این به معنای عدم وجود رمز عبور است یا اشکالی پیش آمده. زمانی که شما یک پشتیبان می‌سازید یا یک پشتیبان وارد می‌کنید، از شما خواسته خواهد شد تا رمز عبور را به صورت دستی وارد کنید. </string>
<string name="backup_desc_openpgp_provider">شما نیاز دارید که یک مهیاکننده OpenPGP نصب کنید و آن را در <b>تنظیمات</b> فعال کنید تا از این قابلیت استفاده کنید. </string> <string name="backup_desc_openpgp_provider">شما نیاز دارید که یک مهیاکننده OpenPGP نصب کنید و آن را در <b>تنظیمات</b> فعال کنید تا از این قابلیت استفاده کنید. </string>
@ -32,6 +34,8 @@
<string name="backup_receiver_read_permission_failed">اجازه خواندن داده نشده، لطفا قبل از تلاش برای پشتیبان‌گیری این اجازه را بدهید</string> <string name="backup_receiver_read_permission_failed">اجازه خواندن داده نشده، لطفا قبل از تلاش برای پشتیبان‌گیری این اجازه را بدهید</string>
<string name="backup_receiver_write_permission_failed">اجازه نوشتن داده نشده، لطفا قبل از تلاش برای پشتیبان‌گیری این اجازه را بدهید</string> <string name="backup_receiver_write_permission_failed">اجازه نوشتن داده نشده، لطفا قبل از تلاش برای پشتیبان‌گیری این اجازه را بدهید</string>
<string name="backup_receiver_custom_encryption_failed">رمز عبور / پین بر اساس رمزگذاری، توسط Broadcast Backup پشتیبانی نمی‌شود</string> <string name="backup_receiver_custom_encryption_failed">رمز عبور / پین بر اساس رمزگذاری، توسط Broadcast Backup پشتیبانی نمی‌شود</string>
<string name="backup_new_format_dialog_title">روش رمزگذاری جدید</string>
<string name="backup_new_format_dialog_msg">از نسخه‌ی ۰.۶.۳ ی andOTP، <b>یک روش بهبودیافته و جدید رمزگذاری</b> برای پشتیبان‌های محافظت‌شده با رمز استفاده شده است. پشتیبان‌های قدیمی هنوز می‌توانند وارد شوند، اما <b>بسیار پیشنهاد می‌شود که از روش بهبودیافته‌ی رمزگذاری</b> استفاده کنید.\n\nاین پیام دوباره نشان داده نخواهد شد.</string>
<!-- Notification channels --> <!-- Notification channels -->
<string name="notification_channel_name_backup_failed">شکست در پشتیبان‌گیری خودکار</string> <string name="notification_channel_name_backup_failed">شکست در پشتیبان‌گیری خودکار</string>
<string name="notification_channel_name_backup_success">پشتیبان‌گیری خودکار با موفقیت انجام شد</string> <string name="notification_channel_name_backup_success">پشتیبان‌گیری خودکار با موفقیت انجام شد</string>

View file

@ -1,42 +1,41 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="about_activity_title">À propos</string> <string name="about_activity_title">À propos</string>
<string name="about_description">Authentification à double facteur open source pour Android</string> <string name="about_description">Authentification à double facteur open source pour Android</string>
<string name="about_tab_about">À propos</string> <string name="about_tab_about">À propos</string>
<string name="about_tab_libraries">Bibliothèques</string> <string name="about_tab_libraries">Bibliothèques</string>
<!-- Misc --> <!-- Misc -->
<string name="about_label_changelog">Liste des changements</string> <string name="about_label_changelog">Liste des changements</string>
<string name="about_label_license">Licence</string> <string name="about_label_license">Licence</string>
<string name="about_label_MIT">Licence MIT</string> <string name="about_label_MIT">Licence MIT</string>
<string name="about_label_source">Code source</string> <string name="about_label_source">Code source</string>
<string name="about_label_version">Version</string> <string name="about_label_version">Version</string>
<!-- Authors --> <!-- Authors -->
<string name="about_title_authors">Auteurs</string> <string name="about_title_authors">Auteurs</string>
<string name="about_label_main_developer">Développeur principal</string> <string name="about_label_main_developer">Développeur principal</string>
<string name="about_label_developer">Développeur</string> <string name="about_label_developer">Développeur</string>
<string name="about_label_original_author">Auteur de l\'application originale</string> <string name="about_label_original_author">Auteur de l\'application originale</string>
<string name="about_label_original_app">Application originale</string> <string name="about_label_original_app">Application originale</string>
<string name="about_label_website">Site web</string> <string name="about_label_website">Site web</string>
<string name="about_label_donate_paypal">Faire un don (PayPal)</string> <string name="about_label_donate">Faire un don</string>
<string name="about_label_donate_bitcoin">Faire un don (Bitcoin)</string> <string name="about_label_contributors">Contributeurs</string>
<string name="about_label_contributors">Contributeurs</string> <string name="about_label_translators">Traducteurs</string>
<string name="about_label_translators">Traducteurs</string> <!-- Thumbnail disclaimer -->
<!-- Thumbnail disclaimer --> <string name="about_title_thumbnail_disclaimer">Notice légale abrégée</string>
<string name="about_title_thumbnail_disclaimer">Notice légale abrégée</string> <string name="about_thumbnails_disclaimer_no1"><b>1.</b> Toutes les icônes sont des marques déposées de leur propriétaires respectifs.</string>
<string name="about_thumbnails_disclaimer_no1"><b>1.</b> Toutes les icônes sont des marques déposées de leur propriétaires respectifs.</string> <string name="about_thumbnails_disclaimer_no2"><b>2.</b> L\'utilisation de ces marques déposées n\'implique pas l\'approbation d\'andOTP pour ces marques et réciproquement.</string>
<string name="about_thumbnails_disclaimer_no2"><b>2.</b> L\'utilisation de ces marques déposées n\'implique pas l\'approbation d\'andOTP pour ces marques et réciproquement.</string> <string name="about_thumbnails_disclaimer_no3"><b>3.</b> Les icônes ne doivent être utilisées que pour représenter l\'entreprise ou le produit auquel elles font référence.</string>
<string name="about_thumbnails_disclaimer_no3"><b>3.</b> Les icônes ne doivent être utilisées que pour représenter l\'entreprise ou le produit auquel elles font référence.</string> <string name="about_thumbnails_disclaimer_no4"><b>4. Veillez à ne pas utiliser les icônes pour d\'autre raisons que la représentation de ces marques ou services déterminés.</b></string>
<string name="about_thumbnails_disclaimer_no4"><b>4. Veillez à ne pas utiliser les icônes pour d\'autre raisons que la représentation de ces marques ou services déterminés.</b></string> <!-- Support -->
<!-- Support --> <string name="about_title_support">Aider au développement</string>
<string name="about_title_support">Aider au développement</string> <string name="about_label_report_bugs">Rapporter des bugs</string>
<string name="about_label_report_bugs">Rapporter des bugs</string> <string name="about_label_translate">Traduire</string>
<string name="about_label_translate">Traduire</string> <string name="about_desc_report_bugs">Rapporter des bugs ou demander de nouvelles fonctionnalités</string>
<string name="about_desc_report_bugs">Rapporter des bugs ou demander de nouvelles fonctionnalités</string> <string name="about_desc_translate">Aider à la traduction d\'andOTP dans votre langue</string>
<string name="about_desc_translate">Aider à la traduction d\'andOTP dans votre langue</string> <string name="about_title_special_features">Fonctionnalités spéciales</string>
<string name="about_title_special_features">Fonctionnalités spéciales</string> <string name="about_dialog_special_features">Êtes-vous certain de vouloir activer les fonctionnalités spéciales? La plupart d\'entre elles sont des algorithmes OTP non standard qui ont été implémentés pour des demandes spécifiques. Elles ne sont <b>pas supportées officiellement</b> et peuvent venir avec <b>certaines limitations</b>. Veuillez consulter (et comprendre) la page « Fonctionnalités spéciales » sur le wiki du GitHub pour en apprendre d\'avantage avant de les utiliser.</string>
<string name="about_dialog_special_features">Êtes-vous certain de vouloir activer les fonctionnalités spéciales? La plupart d\'entre elles sont des algorithmes OTP non standard qui ont été implémentés pour des demandes spécifiques. Elles ne sont <b>pas supportées officiellement</b> et peuvent venir avec <b>certaines limitations</b>. Veuillez consulter (et comprendre) la page « Fonctionnalités spéciales » sur le wiki du GitHub pour en apprendre d\'avantage avant de les utiliser.</string> <string name="about_toast_special_features">Fonctionnalités spéciales activées</string>
<string name="about_toast_special_features">Fonctionnalités spéciales activées</string> <string name="about_toast_special_features_enabled">Fonctionnalités spéciales déjà activées</string>
<string name="about_toast_special_features_enabled">Fonctionnalités spéciales déjà activées</string> <string name="about_toast_copied_to_clipboard">Lien de don copié dans le presse-papier</string>
<string name="about_toast_copied_to_clipboard">Lien de don copié dans le presse-papier</string>
</resources> </resources>

View file

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="auth_activity_title">Identifiez-vous</string> <string name="auth_activity_title">Identifiez-vous</string>
<!-- Hints --> <!-- Hints -->
<string name="auth_hint_password">Mot de passe</string> <string name="auth_hint_password">Mot de passe</string>
<string name="auth_hint_pin">Code PIN</string> <string name="auth_hint_pin">Code PIN</string>
<!-- Messages --> <!-- Messages -->
<string name="auth_msg_authenticate">Veuillez vous authentifier pour lancer andOTP !</string> <string name="auth_msg_authenticate">Veuillez vous authentifier pour lancer andOTP !</string>
<string name="auth_msg_confirm_encryption">Veuillez confirmer votre authentification pour générer la <string name="auth_msg_confirm_encryption">Veuillez confirmer votre authentification pour générer la
nouvelle clé de chiffrement !</string> nouvelle clé de chiffrement !</string>
<!-- Buttons --> <!-- Buttons -->
<string name="auth_button_unlock">Déverrouiller</string> <string name="auth_button_unlock">Déverrouiller</string>
<!-- Toast messages --> <!-- Toast messages -->
<string name="auth_toast_password_missing">Veuillez définir un mot de passe dans les <b>paramètres</b> !</string> <string name="auth_toast_password_missing">Veuillez définir un mot de passe dans les <b>paramètres</b> !</string>
<string name="auth_toast_pin_missing">Veuillez définir un code PIN dans les <b>paramètres</b> !</string> <string name="auth_toast_pin_missing">Veuillez définir un code PIN dans les <b>paramètres</b> !</string>
<string name="auth_toast_password_again">Mot de passe incorrect, veuillez réessayer !</string> <string name="auth_toast_password_again">Mot de passe incorrect, veuillez réessayer !</string>
<string name="auth_toast_pin_again">Code PIN incorrect, veuillez réessayer !</string> <string name="auth_toast_pin_again">Code PIN incorrect, veuillez réessayer !</string>
</resources> </resources>

View file

@ -1,55 +1,64 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="backup_activity_title">Sauvegardes</string> <string name="backup_activity_title">Sauvegardes</string>
<string name="backup_category_plain">Sauvegardes en clair</string> <string name="backup_category_plain">Sauvegardes en clair</string>
<string name="backup_category_crypt">Sauvegardes chiffrées</string> <string name="backup_category_crypt">Sauvegardes chiffrées</string>
<string name="backup_category_openpgp">Sauvegardes avec OpenPGP</string> <string name="backup_category_openpgp">Sauvegardes avec OpenPGP</string>
<string name="backup_title_export_plain">Sauvegarde (en clair)</string> <string name="backup_title_export_plain">Sauvegarde (en clair)</string>
<string name="backup_title_export_crypt">Sauvegarde (chiffrée)</string> <string name="backup_title_export_crypt">Sauvegarde (chiffrée)</string>
<string name="backup_title_export_openpgp">Sauvegarde (OpenPGP)</string> <string name="backup_title_export_openpgp">Sauvegarde (OpenPGP)</string>
<string name="backup_title_import_plain">Restauration (en clair)</string> <string name="backup_title_import_plain">Restauration (en clair)</string>
<string name="backup_title_import_crypt">Restauration (chiffrée)</string> <string name="backup_title_import_crypt">Restauration (chiffrée)</string>
<string name="backup_title_import_openpgp">Restauration (OpenPGP)</string> <string name="backup_title_import_crypt_old">Restaurer (chiffré, ancien chiffrement)</string>
<string name="backup_title_replace">Remplacer les entrées existantes</string> <string name="backup_title_import_openpgp">Restauration (OpenPGP)</string>
<string name="backup_desc_export_plain">Sauvegarder tous les comptes en clair dans un fichier JSON</string> <string name="backup_title_replace">Remplacer les entrées existantes</string>
<string name="backup_desc_export_crypt">Sauvegarder tous les comptes dans un fichier JSON protégé par un mot de passe</string> <string name="backup_desc_export_plain">Sauvegarder tous les comptes en clair dans un fichier JSON</string>
<string name="backup_desc_export_openpgp">Sauvegarder tous les comptes dans un fichier JSON chiffré avec OpenPGP</string> <string name="backup_desc_export_crypt">Sauvegarder tous les comptes dans un fichier JSON protégé par un mot de passe</string>
<string name="backup_desc_import_plain">Restaurer tous les comptes à partir d\'un fichier JSON en clair</string> <string name="backup_desc_export_openpgp">Sauvegarder tous les comptes dans un fichier JSON chiffré avec OpenPGP</string>
<string name="backup_desc_import_crypt">Restaurer tous les comptes à partir d\'un fichier JSON protégé par un mot de passe</string> <string name="backup_desc_import_plain">Restaurer tous les comptes à partir d\'un fichier JSON en clair</string>
<string name="backup_desc_import_openpgp">Restaurer tous les comptes à partir d\'un fichier JSON chiffré avec OpenPGP</string> <string name="backup_desc_import_crypt">Restaurer tous les comptes à partir d\'un fichier JSON protégé par un mot de passe</string>
<string name="backup_desc_crypt_setup">Le mot de passe de sauvegarde n\'a pas été chargé à partir des <b>Réglages</b>, <string name="backup_desc_import_crypt_old">Restaurer les comptes depuis un fichier JSON protégé par un mot de passe
créé avec une version <b>andOTP inférieure à 0.6.3</b></string>
<string name="backup_desc_import_openpgp">Restaurer tous les comptes à partir d\'un fichier JSON chiffré avec OpenPGP</string>
<string name="backup_desc_crypt_setup">Le mot de passe de sauvegarde n\'a pas été chargé à partir des <b>Réglages</b>,
cela signifie soit qu\'aucun mot de passe n\'a été défini, soit que quelque chose n\'a pas fonctionné. Il vous sera demandé d\'entrer cela signifie soit qu\'aucun mot de passe n\'a été défini, soit que quelque chose n\'a pas fonctionné. Il vous sera demandé d\'entrer
le mot de passe manuellement lors de la création ou de l\'importation d\'une sauvegarde. </string> le mot de passe manuellement lors de la création ou de l\'importation d\'une sauvegarde. </string>
<string name="backup_desc_openpgp_provider">Vous devez installer un fournisseur OpenPGP et l\'activer dans les <b>paramètres</b> pour utiliser cette fonctionnalité.</string> <string name="backup_desc_openpgp_provider">Vous devez installer un fournisseur OpenPGP et l\'activer dans les <b>paramètres</b> pour utiliser cette fonctionnalité.</string>
<string name="backup_desc_openpgp_keyid">Vous devez sélectionner un fournisseur OpenPGP dans les <b>paramètres</b> afin de pouvoir créer des sauvegardes chiffrées.</string> <string name="backup_desc_openpgp_keyid">Vous devez sélectionner un fournisseur OpenPGP dans les <b>paramètres</b> afin de pouvoir créer des sauvegardes chiffrées.</string>
<string name="backup_desc_replace">Si activé, à l\'import d\'une sauvegarde toutes les entrées seront supprimées et remplacées par les entrées de la sauvegarde. Si désactivé, les entrées seront fusionnées avec celles de la sauvegarde.</string> <string name="backup_desc_replace">Si activé, à l\'import d\'une sauvegarde toutes les entrées seront supprimées et remplacées par les entrées de la sauvegarde. Si désactivé, les entrées seront fusionnées avec celles de la sauvegarde.</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="backup_dialog_title_security_warning">Avertissement de sécurité</string> <string name="backup_dialog_title_security_warning">Avertissement de sécurité</string>
<string name="backup_dialog_msg_export_warning">Êtes-vous sûr de vouloir exporter la base de données en clair dans un fichier JSON ? Ce fichier contiendra toutes vos clés privées, <b>veuillez le placer dans un endroit sûr</b> ! </string> <string name="backup_dialog_msg_export_warning">Êtes-vous sûr de vouloir exporter la base de données en clair dans un fichier JSON ? Ce fichier contiendra toutes vos clés privées, <b>veuillez le placer dans un endroit sûr</b> ! </string>
<string name="backup_receiver_title_backup_failed">La sauvegarde a échoué</string> <string name="backup_receiver_title_backup_failed">La sauvegarde a échoué</string>
<string name="backup_receiver_title_backup_success">Sauvegarde réussie</string> <string name="backup_receiver_title_backup_success">Sauvegarde réussie</string>
<string name="backup_receiver_plain_disabled">Les sauvegardes en clair ne sont actuellement pas autorisées, veuillez aller dans les Paramètres afin de les activer</string> <string name="backup_receiver_plain_disabled">Les sauvegardes en clair ne sont actuellement pas autorisées, veuillez aller dans les Paramètres afin de les activer</string>
<string name="backup_receiver_encrypted_disabled">Les sauvegardes chiffrées ne sont actuellement pas autorisées, veuillez aller dans les Paramètres afin de les activer</string> <string name="backup_receiver_encrypted_disabled">Les sauvegardes chiffrées ne sont actuellement pas autorisées, veuillez aller dans les Paramètres afin de les activer</string>
<string name="backup_receiver_read_permission_failed">L\'autorisation de lecture n\'est pas accordée, veuillez le faire avant deffectuer la sauvegarde</string> <string name="backup_receiver_read_permission_failed">L\'autorisation de lecture n\'est pas accordée, veuillez le faire avant deffectuer la sauvegarde</string>
<string name="backup_receiver_write_permission_failed">L\'autorisation d\'écriture n\'est pas accordée, veuillez le faire avant deffectuer la sauvegarde</string> <string name="backup_receiver_write_permission_failed">L\'autorisation d\'écriture n\'est pas accordée, veuillez le faire avant deffectuer la sauvegarde</string>
<string name="backup_receiver_custom_encryption_failed">Le chiffrement à base de mot de passe ou code PIN n\'est pas supporté par la sauvegarde par diffusion</string> <string name="backup_receiver_custom_encryption_failed">Le chiffrement à base de mot de passe ou code PIN n\'est pas supporté par la sauvegarde par diffusion</string>
<!-- Notification channels --> <string name="backup_new_format_dialog_title">Nouvelle méthode de chiffrement</string>
<string name="notification_channel_name_backup_failed">Échec de la sauvegarde automatique</string> <string name="backup_new_format_dialog_msg">Depuis la version 0.6.3 de andOTP, une <b>nouvelle méthode
<string name="notification_channel_name_backup_success">Succès de la sauvegarde automatique</string> de chiffrement améliorée</b> est utilisée pour les sauvegardres protégées par mot de passe
<string name="notification_channel_desc_backup_failed">Ces notifications sont affichées quand une sauvegarde automatique a échoué pour une raison quelconque</string> . Les anciennes sauvegardes peuvent jours être importées mais il est <b>hautement
<string name="notification_channel_desc_backup_success">Ces notifications sont affichées quand une sauvegarde automatique a réussi</string> recommandé de créer de nouvelles sauvegardes avec le chiffrement amélioré</b>.\n\nCe
<!-- Toast messages --> message ne sera pas affiché une seconde fois.</string>
<string name="backup_toast_mkdir_failed">Échec de la création du répertoire de sauvegarde</string> <!-- Notification channels -->
<string name="backup_toast_export_success">Sauvegarde vers le stockage externe effectuée avec succès</string> <string name="notification_channel_name_backup_failed">Échec de la sauvegarde automatique</string>
<string name="backup_toast_export_failed">La sauvegarde vers le stockage externe a échoué</string> <string name="notification_channel_name_backup_success">Succès de la sauvegarde automatique</string>
<string name="backup_toast_import_success">Restauration depuis le stockage externe effectuée avec succès</string> <string name="notification_channel_desc_backup_failed">Ces notifications sont affichées quand une sauvegarde automatique a échoué pour une raison quelconque</string>
<string name="backup_toast_import_save_failed">Échec de l\'enregistrement des entrées restaurées</string> <string name="notification_channel_desc_backup_success">Ces notifications sont affichées quand une sauvegarde automatique a réussi</string>
<string name="backup_toast_import_decryption_failed">Échec du déchiffrement de la sauvegarde</string> <!-- Toast messages -->
<string name="backup_toast_import_no_entries">Aucune entrée trouvée dans les données importées</string> <string name="backup_toast_mkdir_failed">Échec de la création du répertoire de sauvegarde</string>
<string name="backup_toast_storage_not_accessible">Stockage externe non disponible</string> <string name="backup_toast_export_success">Sauvegarde vers le stockage externe effectuée avec succès</string>
<string name="backup_toast_storage_permissions">Permission d\'accéder au stockage refusée</string> <string name="backup_toast_export_failed">La sauvegarde vers le stockage externe a échoué</string>
<string name="backup_toast_openpgp_error">Erreur OpenPGP : %s</string> <string name="backup_toast_import_success">Restauration depuis le stockage externe effectuée avec succès</string>
<string name="backup_toast_openpgp_not_verified">Aucune signature vérifiée n\'a été trouvée</string> <string name="backup_toast_import_save_failed">Échec de l\'enregistrement des entrées restaurées</string>
<string name="backup_toast_crypt_password_not_set">Aucun mot de passe défini, vérifiez les <b>paramètres</b></string> <string name="backup_toast_import_decryption_failed">Échec du déchiffrement de la sauvegarde</string>
<string name="backup_toast_import_no_entries">Aucune entrée trouvée dans les données importées</string>
<string name="backup_toast_storage_not_accessible">Stockage externe non disponible</string>
<string name="backup_toast_storage_permissions">Permission d\'accéder au stockage refusée</string>
<string name="backup_toast_openpgp_error">Erreur OpenPGP : %s</string>
<string name="backup_toast_openpgp_not_verified">Aucune signature vérifiée n\'a été trouvée</string>
<string name="backup_toast_crypt_password_not_set">Aucun mot de passe défini, vérifiez les <b>paramètres</b></string>
</resources> </resources>

View file

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="intro_slide1_title">C\'est parti</string> <string name="intro_slide1_title">C\'est parti</string>
<string name="intro_slide1_desc">Bienvenue sur <b>andOTP</b>, cet assistant vous guidera lors <string name="intro_slide1_desc">Bienvenue sur <b>andOTP</b>, cet assistant vous guidera lors
de la configuration initiale. Veuillez prêter attention et lire attentivement sous peine de perdre des données ! de la configuration initiale. Veuillez prêter attention et lire attentivement sous peine de perdre des données !
\n\nNe vous inquiétez pas, vous pouvez toujours modifier ces options ultérieurement dans les <b>paramètres</b>.</string> \n\nNe vous inquiétez pas, vous pouvez toujours modifier ces options ultérieurement dans les <b>paramètres</b>.</string>
<string name="intro_slide2_desc">Pour assurer la sécurité de vos comptes, <b>andOTP</b> ne les <string name="intro_slide2_desc">Pour assurer la sécurité de vos comptes, <b>andOTP</b> ne les
stocke uniquement dans des fichiers de données chiffrés. Ici, vous pouvez choisir quelle méthode de chiffrement sera stocke uniquement dans des fichiers de données chiffrés. Ici, vous pouvez choisir quelle méthode de chiffrement sera
utilisée.</string> utilisée.</string>
<string name="intro_slide2_desc_keystore">Le KeyStore est un composant système d\'Android pour <string name="intro_slide2_desc_keystore">Le KeyStore est un composant système d\'Android pour
stocker de façon sécurisée les clés de chiffrage. L\'avantage de cette méthode est que les clés sont stocker de façon sécurisée les clés de chiffrage. L\'avantage de cette méthode est que les clés sont
stockées séparément des fichiers de données et peuvent être sauvegardées par un matériel cryptographique (si votre stockées séparément des fichiers de données et peuvent être sauvegardées par un matériel cryptographique (si votre
appareil le supporte). Cependant, comme les clés ne sont pas stockée avec les données des applis, <b>cette méthode appareil le supporte). Cependant, comme les clés ne sont pas stockée avec les données des applis, <b>cette méthode
@ -16,21 +16,21 @@
méthode, vous devrez vous reposer sur les fonctionnalités de sauvegarde internes fournies par <b>andOTP</b>. méthode, vous devrez vous reposer sur les fonctionnalités de sauvegarde internes fournies par <b>andOTP</b>.
\n\n<b>Avertissement</b> : le KeyStore est connu pour être problématique, ne l\'utilisez que si vous êtes obligé. Si saisir un mot de passe / code PIN à chaque démarrage de <b>andOTP</b> ne vous dérange pas, \n\n<b>Avertissement</b> : le KeyStore est connu pour être problématique, ne l\'utilisez que si vous êtes obligé. Si saisir un mot de passe / code PIN à chaque démarrage de <b>andOTP</b> ne vous dérange pas,
il est <b>fortement recommandé d\'utiliser un chiffrement basé sur un mot de passe </b>.</string> il est <b>fortement recommandé d\'utiliser un chiffrement basé sur un mot de passe </b>.</string>
<string name="intro_slide2_desc_password">Cette méthode va chiffrer vos données avec une clé <string name="intro_slide2_desc_password">Cette méthode va chiffrer vos données avec une clé
générée à partir d\'un mot de passe ou code PIN. Le principal avantage ici est que cela fonctionnera avec générée à partir d\'un mot de passe ou code PIN. Le principal avantage ici est que cela fonctionnera avec
des solutions de sauvegarde externes (comme Titanium) et est bien moins propice aux erreurs que le KeyStore. des solutions de sauvegarde externes (comme Titanium) et est bien moins propice aux erreurs que le KeyStore.
Cependant, vous devrez saisir vos identifiants à chaque lancement de <b>andOTP</b>.</string> Cependant, vous devrez saisir vos identifiants à chaque lancement de <b>andOTP</b>.</string>
<string name="intro_slide3_desc_keystore">Ici vous pouvez définir une authentification pour verrouiller <string name="intro_slide3_desc_keystore">Ici vous pouvez définir une authentification pour verrouiller
<b>andOTP</b>. Puisque vous avez choisi le <b>KeyStore Android</b> comme méthode de chiffrement, ceci est <b>andOTP</b>. Puisque vous avez choisi le <b>KeyStore Android</b> comme méthode de chiffrement, ceci est
optionnel.</string> optionnel.</string>
<string name="intro_slide3_desc_password">Ici vous pouvez définir une authentification pour verrouiller <string name="intro_slide3_desc_password">Ici vous pouvez définir une authentification pour verrouiller
<b>andOTP</b>. Puisque vous avez choisi un <b>mot de passe / code PIN</b> comme méthode de chiffrement, vous devez <b>andOTP</b>. Puisque vous avez choisi un <b>mot de passe / code PIN</b> comme méthode de chiffrement, vous devez
définir un mot de passe ou un code PIN pour continuer.</string> définir un mot de passe ou un code PIN pour continuer.</string>
<string name="intro_slide3_warn_no_password">Veuillez définir un mot de passe pour continuer !</string> <string name="intro_slide3_warn_no_password">Veuillez définir un mot de passe pour continuer !</string>
<string name="intro_slide3_warn_no_pin">Veuillez définir un code PIN pour continuer !</string> <string name="intro_slide3_warn_no_pin">Veuillez définir un code PIN pour continuer !</string>
<string name="intro_slide3_warn_confirm_password">Veuillez confirmer votre mot de passe pour continuer !</string> <string name="intro_slide3_warn_confirm_password">Veuillez confirmer votre mot de passe pour continuer !</string>
<string name="intro_slide3_warn_confirm_pin">Veuillez confirmer votre code PIN pour continuer !</string> <string name="intro_slide3_warn_confirm_pin">Veuillez confirmer votre code PIN pour continuer !</string>
<string name="intro_slide4_title">Terminé</string> <string name="intro_slide4_title">Terminé</string>
<string name="intro_slide4_desc">Vos paramètres ont été enregistrés, vous pouvez maintenant utiliser <string name="intro_slide4_desc">Vos paramètres ont été enregistrés, vous pouvez maintenant utiliser
<b>andOTP</b> !</string> <b>andOTP</b> !</string>
</resources> </resources>

View file

@ -1,71 +1,71 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<!-- Buttons --> <!-- Buttons -->
<string name="button_cancel">Annuler</string> <string name="button_cancel">Annuler</string>
<string name="button_enter_details">Ajouter les détails</string> <string name="button_enter_details">Ajouter les détails</string>
<string name="button_scan_qr">Scanner un code QR</string> <string name="button_scan_qr">Scanner un QR-Code</string>
<string name="button_save">Enregistrer</string> <string name="button_save">Enregistrer</string>
<string name="button_new_tag">Nouveau tag</string> <string name="button_new_tag">Nouveau tag</string>
<string name="button_settings">Paramètres</string> <string name="button_settings">Paramètres</string>
<string name="button_all_tags">Tous les tags</string> <string name="button_all_tags">Tous les tags</string>
<string name="button_no_tags">Aucun tag</string> <string name="button_no_tags">Aucun tag</string>
<!-- Custom formatting --> <!-- Custom formatting -->
<string name="format_custom_period">%d s</string> <string name="format_custom_period">%d s</string>
<!-- Hints --> <!-- Hints -->
<string name="hint_label">Titre</string> <string name="hint_label">Titre</string>
<string name="hint_secret">Secret</string> <string name="hint_secret">Secret</string>
<!-- Labels --> <!-- Labels -->
<string name="label_hidden">Cachés</string> <string name="label_hidden">Cachés</string>
<string name="label_type">Type</string> <string name="label_type">Type</string>
<string name="label_secret">Secret</string> <string name="label_secret">Secret</string>
<string name="label_period">Période</string> <string name="label_period">Période</string>
<string name="label_digits">Nombre de chiffres</string> <string name="label_digits">Nombre de chiffres</string>
<string name="label_counter">Compteur</string> <string name="label_counter">Compteur</string>
<string name="label_label">Titre</string> <string name="label_label">Titre</string>
<string name="label_algorithm">Algorithme</string> <string name="label_algorithm">Algorithme</string>
<string name="label_tags">Tags</string> <string name="label_tags">Tags</string>
<string name="label_advanced">Options avancées</string> <string name="label_advanced">Options avancées</string>
<!-- Drawer --> <!-- Drawer -->
<string name="drawer_open">Afficher les tags</string> <string name="drawer_open">Afficher les tags</string>
<string name="drawer_close">Cacher les tags</string> <string name="drawer_close">Cacher les tags</string>
<!-- Menu --> <!-- Menu -->
<string name="menu_main_about">À propos</string> <string name="menu_main_about">À propos</string>
<string name="menu_main_backup">Sauvegarde</string> <string name="menu_main_backup">Sauvegarde</string>
<string name="menu_main_search">Recherche</string> <string name="menu_main_search">Recherche</string>
<string name="menu_main_settings">Paramètres</string> <string name="menu_main_settings">Paramètres</string>
<string name="menu_main_sort">Trier</string> <string name="menu_main_sort">Trier</string>
<string name="menu_sort_none">Non trié</string> <string name="menu_sort_none">Non trié</string>
<string name="menu_sort_label">Titre</string> <string name="menu_sort_label">Titre</string>
<string name="menu_sort_last_used">Dernier utilisé</string> <string name="menu_sort_last_used">Dernier utilisé</string>
<string name="menu_popup_edit_label">Renommer</string> <string name="menu_popup_edit_label">Renommer</string>
<string name="menu_popup_change_image">Modifier l\'image</string> <string name="menu_popup_change_image">Modifier l\'image</string>
<string name="menu_popup_edit_tags">Éditer les tags</string> <string name="menu_popup_edit_tags">Éditer les tags</string>
<string name="menu_popup_remove">Supprimer</string> <string name="menu_popup_remove">Supprimer</string>
<!-- Toast messages --> <!-- Toast messages -->
<string name="toast_auth_failed">Échec d\'authentification, veuillez réessayer !</string> <string name="toast_auth_failed">Échec d\'authentification, veuillez réessayer !</string>
<string name="toast_auth_failed_fatal">Échec d\'authentification, fermeture d\'andOTP !</string> <string name="toast_auth_failed_fatal">Échec d\'authentification, fermeture d\'andOTP !</string>
<string name="toast_copied_to_clipboard">Copié dans le presse-papier</string> <string name="toast_copied_to_clipboard">Copié dans le presse-papier</string>
<string name="toast_entry_exists">Cette entrée existe déjà</string> <string name="toast_entry_exists">Cette entrée existe déjà</string>
<string name="toast_invalid_qr_code">Code QR invalide</string> <string name="toast_invalid_qr_code">QR-Code invalide</string>
<string name="toast_encryption_key_empty">Clé de chiffrement non chargée</string> <string name="toast_encryption_key_empty">Clé de chiffrement non chargée</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="dialog_title_auth">Identifiez-vous</string> <string name="dialog_title_auth">Identifiez-vous</string>
<string name="dialog_title_manual_entry">Ajouter les détails</string> <string name="dialog_title_manual_entry">Ajouter les détails</string>
<string name="dialog_title_remove">Supprimer</string> <string name="dialog_title_remove">Supprimer</string>
<string name="dialog_title_rename">Renommer</string> <string name="dialog_title_rename">Renommer</string>
<string name="dialog_title_counter">Compteur</string> <string name="dialog_title_counter">Compteur</string>
<string name="dialog_title_last_used">Dernier utilisé</string> <string name="dialog_title_last_used">Dernier utilisé</string>
<string name="dialog_title_keystore_error">Erreur KeyStore</string> <string name="dialog_title_keystore_error">Erreur KeyStore</string>
<string name="dialog_title_enter_password">Saisir le mot de passe</string> <string name="dialog_title_enter_password">Saisir le mot de passe</string>
<string name="dialog_label_enter_password">Saisir le mot de passe</string> <string name="dialog_label_enter_password">Saisir le mot de passe</string>
<string name="dialog_label_confirm_password">Confirmer le mot de passe</string> <string name="dialog_label_confirm_password">Confirmer le mot de passe</string>
<string name="dialog_msg_auth">Veuillez entrer les informations d\'identification du périphérique pour démarrer andOTP.</string> <string name="dialog_msg_auth">Veuillez entrer les informations d\'identification du périphérique pour démarrer andOTP.</string>
<string name="dialog_msg_confirm_delete">Êtes-vous sûr(e) de vouloir supprimer le compte \"%1$s\" ?</string> <string name="dialog_msg_confirm_delete">Êtes-vous sûr(e) de vouloir supprimer le compte \"%1$s\" ?</string>
<string name="dialog_msg_last_used">Afin que andOTP puisse reconnaitre le dernier jeton utilisé vous devez activer l\'option \"appuyer pour afficher\" ou utiliser le bouton de copie.\n\nCe message ne s\'affichera plus.</string> <string name="dialog_msg_last_used">Afin que andOTP puisse reconnaitre le dernier jeton utilisé vous devez activer l\'option \"appuyer pour afficher\" ou utiliser le bouton de copie.\n\nCe message ne s\'affichera plus.</string>
<string name="dialog_msg_keystore_error">Échec du chargement de la clé de chiffrement à partir de l\'armoire à clés. <string name="dialog_msg_keystore_error">Échec du chargement de la clé de chiffrement à partir de l\'armoire à clés.
<b>Toute entrée ajoutée sera perdue.</b>\n\nPour continuer à utiliser andOTP, vous pouvez aller dans les <b>paramètres</b> pour passer de <b>Chiffrement de la base de données</b> à <b>Mot de passe / Code PIN</b>.</string> <b>Toute entrée ajoutée sera perdue.</b>\n\nPour continuer à utiliser andOTP, vous pouvez aller dans les <b>paramètres</b> pour passer de <b>Chiffrement de la base de données</b> à <b>Mot de passe / Code PIN</b>.</string>
<!-- Shortcuts --> <!-- Shortcuts -->
<string name="shortcut_name_scan_qr">Scanner le code QR</string> <string name="shortcut_name_scan_qr">Scanner le QR-code</string>
<string name="shortcut_name_enter_details">Ajouter les détails</string> <string name="shortcut_name_enter_details">Ajouter les détails</string>
</resources> </resources>

View file

@ -1,142 +1,141 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="settings_activity_title">Paramètres</string> <string name="settings_activity_title">Paramètres</string>
<!-- Categories --> <!-- Categories -->
<string name="settings_category_title_security">Sécurité</string> <string name="settings_category_title_security">Sécurité</string>
<string name="settings_category_title_ui">Interface</string> <string name="settings_category_title_ui">Interface</string>
<string name="settings_category_title_backup">Sauvegarde</string> <string name="settings_category_title_backup">Sauvegarde</string>
<!-- Titles --> <!-- Titles -->
<string name="settings_title_tap_to_reveal">Appuyer pour afficher</string> <string name="settings_title_tap_to_reveal">Appuyer pour afficher</string>
<string name="settings_title_tap_to_reveal_timeout">Durée d\'affichage des jetons</string> <string name="settings_title_tap_to_reveal_timeout">Durée d\'affichage des jetons</string>
<string name="settings_title_auth">Identification</string> <string name="settings_title_auth">Identification</string>
<string name="settings_title_auth_password">Mot de passe</string> <string name="settings_title_auth_password">Mot de passe</string>
<string name="settings_title_auth_pin">Code PIN</string> <string name="settings_title_auth_pin">Code PIN</string>
<string name="settings_title_encryption">Chiffrement de la base de données</string> <string name="settings_title_encryption">Chiffrement de la base de données</string>
<string name="settings_title_panic">Bouton d\'urgence</string> <string name="settings_title_panic">Bouton d\'urgence</string>
<string name="settings_title_relock_screen_off">Re-verouiller à l\'extinction de l\'écran</string> <string name="settings_title_relock_screen_off">Re-verouiller à l\'extinction de l\'écran</string>
<string name="settings_title_lang">Langage</string> <string name="settings_title_lang">Langage</string>
<string name="settings_title_theme">Thème</string> <string name="settings_title_theme">Thème</string>
<string name="settings_title_label_size">Taille de la police des titres</string> <string name="settings_title_label_size">Taille de la police des titres</string>
<string name="settings_title_label_scroll">Défilement des libellés</string> <string name="settings_title_label_scroll">Défilement des libellés</string>
<string name="settings_title_thumbnail_size_ask">Taille des miniatures</string> <string name="settings_title_thumbnail_size_ask">Taille des miniatures</string>
<string name="settings_title_split_group_size">Séparer le jeton avec des espaces</string> <string name="settings_title_split_group_size">Séparer le jeton avec des espaces</string>
<string name="settings_title_tag_functionality">Comportement de la sélection par tag</string> <string name="settings_title_tag_functionality">Comportement de la sélection par tag</string>
<string name="settings_title_backup_append_date">Ajouter la date au nom de fichier</string> <string name="settings_title_backup_append_date">Ajouter la date au nom de fichier</string>
<string name="settings_title_backup_ask">Demander le nom du fichier</string> <string name="settings_title_backup_ask">Demander le nom du fichier</string>
<string name="settings_title_backup_directory">Répertoire de sauvegarde</string> <string name="settings_title_backup_directory">Répertoire de sauvegarde</string>
<string name="settings_title_backup_password">Mot de passe de sauvegarde</string> <string name="settings_title_backup_password">Mot de passe de sauvegarde</string>
<string name="settings_title_backup_broadcasts">Sauvegardes par diffusion</string> <string name="settings_title_backup_broadcasts">Sauvegardes par diffusion</string>
<string name="settings_title_openpgp_provider">Fournisseur OpenPGP</string> <string name="settings_title_openpgp_provider">Fournisseur OpenPGP</string>
<string name="settings_title_openpgp_key_encrypt">Clé de chiffrage OpenPGP</string> <string name="settings_title_openpgp_key_encrypt">Clé de chiffrage OpenPGP</string>
<string name="settings_title_openpgp_key_sign">Clé de signature OpenPGP (optionnel)</string> <string name="settings_title_openpgp_key_sign">Clé de signature OpenPGP (optionnel)</string>
<string name="settings_title_openpgp_verify">Vérifier les sauvegardes chiffrées</string> <string name="settings_title_openpgp_verify">Vérifier les sauvegardes chiffrées</string>
<string name="settings_title_special_features">Activer les fonctionnalités spéciales</string> <string name="settings_title_special_features">Activer les fonctionnalités spéciales</string>
<string name="settings_title_enable_screenshot">Permettre les copies d\'écran</string> <string name="settings_title_enable_screenshot">Permettre les copies d\'écran</string>
<string name="settings_title_enable_android_backup_service">Activer la synchronisation Android</string> <string name="settings_title_enable_android_backup_service">Activer la synchronisation Android</string>
<string name="settings_title_clear_keystore">Effacer le KeyStore</string> <string name="settings_title_clear_keystore">Effacer le KeyStore</string>
<!-- Descriptions --> <!-- Descriptions -->
<string name="settings_desc_tap_to_reveal">Cacher les jetons OTP par défaut et les afficher manuellement</string> <string name="settings_desc_tap_to_reveal">Cacher les jetons OTP par défaut et les afficher manuellement</string>
<string name="settings_desc_tap_to_reveal_timeout">Sélectionnez la durée (en secondes) après laquelle cacher à nouveau les entrées révélées</string> <string name="settings_desc_tap_to_reveal_timeout">Sélectionnez la durée (en secondes) après laquelle cacher à nouveau les entrées révélées</string>
<string name="settings_desc_panic">Choisir quoi faire lorsque que le bouton d\'urgence est déclenché</string> <string name="settings_desc_panic">Choisir quoi faire lorsque que le bouton d\'urgence est déclenché</string>
<string name="settings_desc_relock_screen_off">Exiger une authentification après l\'extinction de l\'écran</string> <string name="settings_desc_relock_screen_off">Exiger une authentification après l\'extinction de l\'écran</string>
<string name="settings_desc_label_scroll">Faire défiler les libellés trop longs plutôt que de les tronquer</string> <string name="settings_desc_label_scroll">Faire défiler les libellés trop longs plutôt que de les tronquer</string>
<string name="settings_desc_backup_append_date">Ajouter la date et l\'heure au nom de fichier de sauvegarde proposé</string> <string name="settings_desc_backup_append_date">Ajouter la date et l\'heure au nom de fichier de sauvegarde proposé</string>
<string name="settings_desc_backup_ask">Demander le nom du fichier à chaque fois qu\'une sauvegarde est créée ou restaurée</string> <string name="settings_desc_backup_ask">Demander le nom du fichier à chaque fois qu\'une sauvegarde est créée ou restaurée</string>
<string name="settings_desc_backup_directory">Répertoire de sauvegarde (les noms de fichier dépendront du type de sauvegarde)</string> <string name="settings_desc_backup_directory">Répertoire de sauvegarde (les noms de fichier dépendront du type de sauvegarde)</string>
<string name="settings_desc_backup_password">Configurer le mot de passe utilisé pour chiffrer les sauvegardes</string> <string name="settings_desc_backup_password">Configurer le mot de passe utilisé pour chiffrer les sauvegardes</string>
<string name="settings_desc_backup_broadcasts">Sélectionner quelles types de sauvegardes peuvent être appelés pas les applications tiers en utilisant la diffusion</string> <string name="settings_desc_backup_broadcasts">Sélectionner quelles types de sauvegardes peuvent être appelés pas les applications tiers en utilisant la diffusion</string>
<string name="settings_desc_openpgp_key_encrypt">Adresse mail de la clé OpenPGP utilisée pour chiffrer <string name="settings_desc_openpgp_key_encrypt">Adresse mail de la clé OpenPGP utilisée pour chiffrer
les sauvegardes</string> les sauvegardes</string>
<string name="settings_desc_openpgp_verify">Les sauvegardes chiffrées ne sont restaurées que lorsqu\'elles sont signées avec une clé valide</string> <string name="settings_desc_openpgp_verify">Les sauvegardes chiffrées ne sont restaurées que lorsqu\'elles sont signées avec une clé valide</string>
<string name="settings_desc_special_features">Décochez pour désactiver les fonctionnalités spéciales</string> <string name="settings_desc_special_features">Décochez pour désactiver les fonctionnalités spéciales</string>
<string name="settings_desc_enable_screenshot">Permettre de prendre des copies d\'écran de la vue principale (désactivé par défaut pour des raisons de sécurité)</string> <string name="settings_desc_enable_screenshot">Permettre de prendre des copies d\'écran de la vue principale (désactivé par défaut pour des raisons de sécurité)</string>
<string name="settings_desc_enable_android_backup_service">Permet à AndOTP d\'utiliser le service de sauvegarde Android natif pour la sauvegarde des clés et préférences</string> <string name="settings_desc_enable_android_backup_service">Permet à AndOTP d\'utiliser le service de sauvegarde Android natif pour la sauvegarde des clés et préférences</string>
<string name="settings_desc_clear_keystore">Supprimer la clé de chiffrement depuis le KeyStore</string> <string name="settings_desc_clear_keystore">Supprimer la clé de chiffrement depuis le KeyStore</string>
<!-- Toasts --> <!-- Toasts -->
<string name="settings_toast_auth_device_pre_lollipop">Cette fonctionnalité n\'est disponible que sur Android 5.0 (Lollipop) ou supérieur</string> <string name="settings_toast_auth_device_pre_lollipop">Cette fonctionnalité n\'est disponible que sur Android 5.0 (Lollipop) ou supérieur</string>
<string name="settings_toast_auth_device_not_secure">Cette fonctionnalité nécessite l\'activation du verrouillage de lécran (Paramètres -&gt; Sécurité -&gt; Verrouillage de l\'écran)</string> <string name="settings_toast_auth_device_not_secure">Cette fonctionnalité nécessite l\'activation du verrouillage de lécran (Paramètres -&gt; Sécurité -&gt; Verrouillage de l\'écran)</string>
<string name="settings_toast_password_empty">Un mot de passe vide n\'est pas autorisé, définissez l\'Authentification sur \"Aucune\" pour la désactiver !</string> <string name="settings_toast_password_empty">Un mot de passe vide n\'est pas autorisé, définissez l\'Authentification sur \"Aucune\" pour la désactiver !</string>
<string name="settings_toast_encryption_changing">Changement du chiffrement de la base de données, veuillez patienter !</string> <string name="settings_toast_encryption_changing">Changement du chiffrement de la base de données, veuillez patienter !</string>
<string name="settings_toast_encryption_change_success">Chiffrement de la base de données changé avec succès !</string> <string name="settings_toast_encryption_change_success">Chiffrement de la base de données changé avec succès !</string>
<string name="settings_toast_encryption_change_failed">Impossible de changer le chiffrement de la base de données, retour à l\'état original !</string> <string name="settings_toast_encryption_change_failed">Impossible de changer le chiffrement de la base de données, retour à l\'état original !</string>
<string name="settings_toast_encryption_backup_failed">Échec de la création d\'une sauvegarde interne, annulation !</string> <string name="settings_toast_encryption_backup_failed">Échec de la création d\'une sauvegarde interne, annulation !</string>
<string name="settings_toast_encryption_no_key">Impossible dobtenir la clé de chiffrement, abandon !</string> <string name="settings_toast_encryption_no_key">Impossible dobtenir la clé de chiffrement, abandon !</string>
<string name="settings_toast_encryption_auth_failed">Échec de l\'authentification !</string> <string name="settings_toast_encryption_auth_failed">Échec de l\'authentification !</string>
<string name="settings_toast_auth_upgrade_failed">Échec de la mise à jour de votre mot de passe / code PIN <string name="settings_toast_auth_upgrade_failed">Échec de la mise à jour de votre mot de passe / code PIN
pour le nouveau chiffrement, veuillez le réinitialiser manuellement depuis les paramètres !</string> pour le nouveau chiffrement, veuillez le réinitialiser manuellement depuis les paramètres !</string>
<string name="settings_dialog_title_warning">Attention</string> <string name="settings_dialog_title_warning">Attention</string>
<string name="settings_dialog_title_error">Erreur</string> <string name="settings_dialog_title_error">Erreur</string>
<string name="settings_dialog_title_clear_keystore">Vider le KeyStore ?</string> <string name="settings_dialog_title_clear_keystore">Vider le KeyStore ?</string>
<string name="settings_dialog_title_android_sync">Synchronisation Android</string> <string name="settings_dialog_title_android_sync">Synchronisation Android</string>
<string name="settings_dialog_msg_encryption_change">andOTP va maintenant essayer de changer le chiffrement de la base de données. En cas d\'échec, une sauvegarde interne sera restaurée et le chiffrement restera inchangé.\n\n<b>Cependant, cest toujours une bonne idée davoir une sauvegarde au cas où quelque chose dinattendu arrive !</b></string> <string name="settings_dialog_msg_encryption_change">andOTP va maintenant essayer de changer le chiffrement de la base de données. En cas d\'échec, une sauvegarde interne sera restaurée et le chiffrement restera inchangé.\n\n<b>Cependant, cest toujours une bonne idée davoir une sauvegarde au cas où quelque chose dinattendu arrive !</b></string>
<string name="settings_dialog_msg_auth_invalid_with_encryption">Vous pouvez seulement utiliser un mot de passe ou un code PIN si <string name="settings_dialog_msg_auth_invalid_with_encryption">Vous pouvez seulement utiliser un mot de passe ou un code PIN si
le chiffrement de la base de données est défini sur \"Mot de passe / Code PIN\" !</string> le chiffrement de la base de données est défini sur \"Mot de passe / Code PIN\" !</string>
<string name="settings_dialog_msg_encryption_invalid_with_auth">Vous devez d\'abord définir <string name="settings_dialog_msg_encryption_invalid_with_auth">Vous devez d\'abord définir
l\'authentification sur \"Mot de passe / Code PIN\" !</string> l\'authentification sur \"Mot de passe / Code PIN\" !</string>
<string name="settings_dialog_msg_encryption_invalid_without_credentials">Vous devez d\'abord définir un <string name="settings_dialog_msg_encryption_invalid_without_credentials">Vous devez d\'abord définir un
mot de passe ou code PIN avant de changer le chiffrement !</string> mot de passe ou code PIN avant de changer le chiffrement !</string>
<string name="settings_dialog_msg_clear_keystore_password">Dans certains cas, effacer le KeyStore <string name="settings_dialog_msg_clear_keystore_password">Dans certains cas, effacer le KeyStore
peut aider à résoudre des problèmes. Vous ne devriez seulement le faire si vous savez ce que vous faites !\n\nVu que peut aider à résoudre des problèmes. Vous ne devriez seulement le faire si vous savez ce que vous faites !\n\nVu que
le <b>chiffrement de la base de données</b> est défini sur <b>Mot de passe / Code PIN</b>, vous ne devriez perdre aucune donnée le <b>chiffrement de la base de données</b> est défini sur <b>Mot de passe / Code PIN</b>, vous ne devriez perdre aucune donnée
en le faisant (mais ça ne fait jamais de mal de faire une sauvegarde).\n\n<b>Êtes-vous sûr(e) de vouloir en le faisant (mais ça ne fait jamais de mal de faire une sauvegarde).\n\n<b>Êtes-vous sûr(e) de vouloir
effacer le KeyStore ?</b></string> effacer le KeyStore ?</b></string>
<string name="settings_dialog_msg_clear_keystore_keystore">Dans certains cas, effacer le KeyStore <string name="settings_dialog_msg_clear_keystore_keystore">Dans certains cas, effacer le KeyStore
peut aider à résoudre des problèmes. Vous ne devriez seulement le faire si vous savez ce que vous faites !\n\n<b>Attention</b>: peut aider à résoudre des problèmes. Vous ne devriez seulement le faire si vous savez ce que vous faites !\n\n<b>Attention</b>:
Vu que le <b>chiffrement de la base de données</b> est défini sur <b>KeyStore Android</b>, vous allez perdre tous Vu que le <b>chiffrement de la base de données</b> est défini sur <b>KeyStore Android</b>, vous allez perdre tous
vos comptes. Assurez-vous d\'avoir une sauvegarde !\n\n<b>Êtes-vous sûr(e) de vouloir effacer le vos comptes. Assurez-vous d\'avoir une sauvegarde !\n\n<b>Êtes-vous sûr(e) de vouloir effacer le
KeyStore ?</b></string> KeyStore ?</b></string>
<string name="settings_dialog_msg_android_sync_disabled_encryption">La synchronisation Android ne peut être utilisée avec le chiffrement de l\'armoire à clés, <b>vous devriez effectuer une sauvegarde manuelle !</b></string> <string name="settings_dialog_msg_android_sync_disabled_encryption">La synchronisation Android ne peut être utilisée avec le chiffrement de l\'armoire à clés, <b>vous devriez effectuer une sauvegarde manuelle !</b></string>
<!-- List entries --> <!-- List entries -->
<string-array name="settings_entries_auth"> <string-array name="settings_entries_auth">
<item>Aucune</item> <item>Aucune</item>
<item>Mot de passe</item> <item>Mot de passe</item>
<item>Code PIN</item> <item>Code PIN</item>
<item>Identification du périphérique</item> <item>Identification du périphérique</item>
</string-array> </string-array>
<string-array name="settings_entries_encryption"> <string-array name="settings_entries_encryption">
<item>KeyStore Android</item> <item>KeyStore Android</item>
<item>Mot de passe / PIN</item> <item>Mot de passe / PIN</item>
</string-array> </string-array>
<string-array name="settings_entries_panic"> <string-array name="settings_entries_panic">
<item>Supprimer l\'ensemble des comptes</item> <item>Supprimer l\'ensemble des comptes</item>
<item>Réinitialiser les paramètres de l\'application</item> <item>Réinitialiser les paramètres de l\'application</item>
</string-array> </string-array>
<string-array name="settings_entries_theme"> <string-array name="settings_entries_theme">
<item>Thème clair</item> <item>Thème clair</item>
<item>Thème sombre</item> <item>Thème sombre</item>
<item>Thème noir</item> <item>Thème noir</item>
</string-array> </string-array>
<string-array name="settings_entries_thumbnail_size"> <string-array name="settings_entries_thumbnail_size">
<item>Caché</item> <item>Caché</item>
<item>Petit</item> <item>Petit</item>
<item>Par défaut</item> <item>Par défaut</item>
<item>Moyen</item> <item>Moyen</item>
<item>Grand</item> <item>Grand</item>
</string-array> </string-array>
<string-array name="settings_entries_split_group_size"> <string-array name="settings_entries_split_group_size">
<item>Ne pas séparer</item> <item>Ne pas séparer</item>
<item>Après deux caractères</item> <item>Après deux caractères</item>
<item>Après trois caractères</item> <item>Après trois caractères</item>
</string-array> </string-array>
<string-array name="settings_entries_tag_functionality"> <string-array name="settings_entries_tag_functionality">
<item>Afficher les entrées correspondant à <b>au moins une</b> des balises sélectionnées (ou)</item> <item>Afficher les entrées correspondant à <b>au moins une</b> des balises sélectionnées (ou)</item>
<item>Afficher les entrées correspondant à <b>toutes</b> les balises sélectionnées (et)</item> <item>Afficher les entrées correspondant à <b>toutes</b> les balises sélectionnées (et)</item>
<item>Basculer entre les tags (seul un tag ne peut être sélectionné à la fois)</item> <item>Basculer entre les tags (seul un tag ne peut être sélectionné à la fois)</item>
</string-array> </string-array>
<string-array name="settings_entries_backup_broadcasts"> <string-array name="settings_entries_backup_broadcasts">
<item>Sauvegardes en clair</item> <item>Sauvegardes en clair</item>
<item>Sauvegardes chiffrées</item> <item>Sauvegardes chiffrées</item>
</string-array> </string-array>
<!-- Special --> <!-- Special -->
<string name="settings_lang_sys_default">Par défaut du système</string> <string name="settings_lang_sys_default">Par défaut du système</string>
<!-- PasswordPreference --> <!-- PasswordPreference -->
<string name="settings_hint_password">Saisir le nouveau mot de passe</string> <string name="settings_hint_password">Saisir le nouveau mot de passe</string>
<string name="settings_hint_pin">Saisir le nouveau code PIN</string> <string name="settings_hint_pin">Saisir le nouveau code PIN</string>
<string name="settings_hint_password_confirm"> <string name="settings_hint_password_confirm"> Confirmer le mot de passe
Confirmer le mot de passe
</string> </string>
<string name="settings_hint_pin_confirm">Confirmer le code PIN</string> <string name="settings_hint_pin_confirm">Confirmer le code PIN</string>
<string name="settings_label_short_password">Le mot de passe doit comporter au moins %1$d caractères !</string> <string name="settings_label_short_password">Le mot de passe doit comporter au moins %1$d caractères !</string>
<string name="settings_label_short_pin">Le code PIN doit comporter au moins %1$d chiffres !</string> <string name="settings_label_short_pin">Le code PIN doit comporter au moins %1$d chiffres !</string>
</resources> </resources>

View file

@ -1,50 +1,49 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="about_activity_title">Sobre</string> <string name="about_activity_title">Sobre</string>
<string name="about_description">Autenticación de doble-factor de código aberto para Android</string> <string name="about_description">Autenticación de dobre-factor de código aberto para Android</string>
<string name="about_tab_about">Sobre</string> <string name="about_tab_about">Sobre</string>
<string name="about_tab_libraries">Librerías</string> <string name="about_tab_libraries">Librerías</string>
<!-- Misc --> <!-- Misc -->
<string name="about_label_changelog">Cambios</string> <string name="about_label_changelog">Cambios</string>
<string name="about_label_license">Licenza</string> <string name="about_label_license">Licenza</string>
<string name="about_label_MIT">Licenza MIT</string> <string name="about_label_MIT">Licenza MIT</string>
<string name="about_label_source">Código fonte</string> <string name="about_label_source">Código fonte</string>
<string name="about_label_version">Versión</string> <string name="about_label_version">Versión</string>
<!-- Authors --> <!-- Authors -->
<string name="about_title_authors">Autores</string> <string name="about_title_authors">Autores</string>
<string name="about_label_main_developer">Desenvolvedor principal</string> <string name="about_label_main_developer">Desenvolvedor principal</string>
<string name="about_label_developer">Desenvolvedor</string> <string name="about_label_developer">Desenvolvedor</string>
<string name="about_label_original_author">Autor do aplicativo orixinal</string> <string name="about_label_original_author">Autor do aplicativo orixinal</string>
<string name="about_label_original_app">Aplicativo orixinal</string> <string name="about_label_original_app">Aplicativo orixinal</string>
<string name="about_label_website">Páxina web</string> <string name="about_label_website">Páxina web</string>
<string name="about_label_donate_paypal">Doar (PayPal)</string> <string name="about_label_donate">Doar</string>
<string name="about_label_donate_bitcoin">Doar (Bitcoin)</string> <string name="about_label_contributors">Colaboradores</string>
<string name="about_label_contributors">Colaboradores</string> <string name="about_label_translators">Tradutores/as</string>
<string name="about_label_translators">Tradutores/as</string> <!-- Thumbnail disclaimer -->
<!-- Thumbnail disclaimer --> <string name="about_title_thumbnail_disclaimer">Rexeitamento de responsabilidade</string>
<string name="about_title_thumbnail_disclaimer">Rexeitamento de responsabilidade</string> <string name="about_thumbnails_disclaimer_no1"><b>1.</b> Todas as imaxes son marcas rexistradas dos
<string name="about_thumbnails_disclaimer_no1"><b>1.</b> Todas as imaxes son marcas rexistradas dos
seus respectivos donos.</string> seus respectivos donos.</string>
<string name="about_thumbnails_disclaimer_no2"><b>2.</b> A utilización de estas marcas rexistradas non <string name="about_thumbnails_disclaimer_no2"><b>2.</b> A utilización de estas marcas rexistradas non
representa unha recomendación de dita marca por parte de andOTP, nin viceversa.</string> representa unha recomendación de dita marca por parte de andOTP, nin viceversa.</string>
<string name="about_thumbnails_disclaimer_no3"><b>3.</b> As imaxes só deberán ser utilizadas para <string name="about_thumbnails_disclaimer_no3"><b>3.</b> As imaxes só deberán ser utilizadas para
representar a empresa ou producto aos que se refiren.</string> representar a empresa ou producto aos que se refiren.</string>
<string name="about_thumbnails_disclaimer_no4"><b>4. Por favor non utilice estas imaxes para ningún propósito <string name="about_thumbnails_disclaimer_no4"><b>4. Por favor non utilice estas imaxes para ningún propósito
excepto representar unha marca ou servizo particulares.</b></string> excepto representar unha marca ou servizo particulares.</b></string>
<!-- Support --> <!-- Support -->
<string name="about_title_support">Apoiar o desenvolvemento</string> <string name="about_title_support">Apoiar o desenvolvemento</string>
<string name="about_label_report_bugs">Informar dun fallo</string> <string name="about_label_report_bugs">Informar dun fallo</string>
<string name="about_label_translate">Traducir</string> <string name="about_label_translate">Traducir</string>
<string name="about_desc_report_bugs">Informar dun fallo ou solicitar novas funcionalidades</string> <string name="about_desc_report_bugs">Informar dun fallo ou solicitar novas funcionalidades</string>
<string name="about_desc_translate">Axuda a traducir andOTP á túa lingua</string> <string name="about_desc_translate">Axuda a traducir andOTP á túa lingua</string>
<string name="about_title_special_features">Funcionalidades especiais</string> <string name="about_title_special_features">Funcionalidades especiais</string>
<string name="about_dialog_special_features">Queres activar as funcionalidades <string name="about_dialog_special_features">Queres activar as funcionalidades
especiais? A maioría delas son algoritmos OTP non estándar que foron implementados por petición especiais? A maioría delas son algoritmos OTP non estándar que foron implementados por petición
especial. <b>Non están oficialmente soportados</b> e poden ter <b>certas especial. <b>Non están oficialmente soportados</b> e poden ter <b>certas
limitacións</b>, por favor lea (e comprenda) a páxina \"Special features\" na wiki Github limitacións</b>, por favor lea (e comprenda) a páxina \"Special features\" na wiki Github
para aprender máis antes de usalas.</string> para aprender máis antes de usalas.</string>
<string name="about_toast_special_features">Funcionalidades especiais activadas</string> <string name="about_toast_special_features">Funcionalidades especiais activadas</string>
<string name="about_toast_special_features_enabled">As funcionalidades especiais xa están activadas</string> <string name="about_toast_special_features_enabled">As funcionalidades especiais xa están activadas</string>
<string name="about_toast_copied_to_clipboard">Ligazón de doazóns copiada ao portapapeis</string> <string name="about_toast_copied_to_clipboard">Ligazón de doazóns copiada ao portapapeis</string>
</resources> </resources>

View file

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="auth_activity_title">Autenticación</string> <string name="auth_activity_title">Autenticación</string>
<!-- Hints --> <!-- Hints -->
<string name="auth_hint_password">Contrasinal</string> <string name="auth_hint_password">Contrasinal</string>
<string name="auth_hint_pin">PIN</string> <string name="auth_hint_pin">PIN</string>
<!-- Messages --> <!-- Messages -->
<string name="auth_msg_authenticate">Por favor autentíquese para iniciar andOTP!</string> <string name="auth_msg_authenticate">Por favor autentíquese para iniciar andOTP!</string>
<string name="auth_msg_confirm_encryption">Por favor confirme a súa autenticación para xerar <string name="auth_msg_confirm_encryption">Por favor confirme a súa autenticación para xerar
a nova chave de cifrado!</string> a nova chave de cifrado!</string>
<!-- Buttons --> <!-- Buttons -->
<string name="auth_button_unlock">Desbloquear</string> <string name="auth_button_unlock">Desbloquear</string>
<!-- Toast messages --> <!-- Toast messages -->
<string name="auth_toast_password_missing">Establecer un contrasinal en <b>axustes</b>!</string> <string name="auth_toast_password_missing">Establecer un contrasinal en <b>axustes</b>!</string>
<string name="auth_toast_pin_missing">Establecer un PIN en <b>axustes</b>!</string> <string name="auth_toast_pin_missing">Establecer un PIN en <b>axustes</b>!</string>
<string name="auth_toast_password_again">Contrasinal incorrecto, téntao de novo!</string> <string name="auth_toast_password_again">Contrasinal incorrecto, téntao de novo!</string>
<string name="auth_toast_pin_again">PIN incorrecto, téntao de novo!</string> <string name="auth_toast_pin_again">PIN incorrecto, téntao de novo!</string>
</resources> </resources>

View file

@ -1,70 +1,78 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="backup_activity_title">Copias de seguranza</string> <string name="backup_activity_title">Copias de seguranza</string>
<string name="backup_category_plain">Copias de seguranza en texto plano</string> <string name="backup_category_plain">Copias de seguranza en texto plano</string>
<string name="backup_category_crypt">Copias de seguranza cifradas</string> <string name="backup_category_crypt">Copias de seguranza cifradas</string>
<string name="backup_category_openpgp">Copias de seguranza OpenPGP</string> <string name="backup_category_openpgp">Copias de seguranza OpenPGP</string>
<string name="backup_title_export_plain">Copia de seguranza (texto plano)</string> <string name="backup_title_export_plain">Copia de seguranza (texto plano)</string>
<string name="backup_title_export_crypt">Copia de seguranza (cifrada)</string> <string name="backup_title_export_crypt">Copia de seguranza (cifrada)</string>
<string name="backup_title_export_openpgp">Copia de seguranza (OpenPGP)</string> <string name="backup_title_export_openpgp">Copia de seguranza (OpenPGP)</string>
<string name="backup_title_import_plain">Restaurar (texto plano)</string> <string name="backup_title_import_plain">Restaurar (texto plano)</string>
<string name="backup_title_import_crypt">Restaurar (cifrada)</string> <string name="backup_title_import_crypt">Restaurar (cifrada)</string>
<string name="backup_title_import_openpgp">Restaurar (OpenPGP)</string> <string name="backup_title_import_crypt_old">Restaurar (cifrado, cifrado antigo)</string>
<string name="backup_title_replace">Substituír as entradas existentes</string> <string name="backup_title_import_openpgp">Restaurar (OpenPGP)</string>
<string name="backup_desc_export_plain">Facer copia de seguranza de todas as contas nun ficheiro de texto plano JSON</string> <string name="backup_title_replace">Substituír as entradas existentes</string>
<string name="backup_desc_export_crypt">Facer copia de seguranza de todas as contas nun ficheiro JSON con contrasinal</string> <string name="backup_desc_export_plain">Facer copia de seguranza de todas as contas nun ficheiro de texto plano JSON</string>
<string name="backup_desc_export_openpgp">Facer copia de seguranza de todas as contas nun ficheiro JSON cifrado con OpenPGP</string> <string name="backup_desc_export_crypt">Facer copia de seguranza de todas as contas nun ficheiro JSON con contrasinal</string>
<string name="backup_desc_import_plain">Restaurar contas desde un ficheiro JSON de texto plano</string> <string name="backup_desc_export_openpgp">Facer copia de seguranza de todas as contas nun ficheiro JSON cifrado con OpenPGP</string>
<string name="backup_desc_import_crypt">Restaurar contas desde un ficheiro JSON con contrasinal</string> <string name="backup_desc_import_plain">Restaurar contas desde un ficheiro JSON de texto plano</string>
<string name="backup_desc_import_openpgp">Restaurar contas desde un ficheiro JSON cifrado con OpenPGP</string> <string name="backup_desc_import_crypt">Restaurar contas desde un ficheiro JSON con contrasinal</string>
<string name="backup_desc_crypt_setup">Houbo un erro ao cargar o contrasinal de respaldo desde os <b>Axustes</b>, <string name="backup_desc_import_crypt_old">Restuarar contas dun ficheiro JSON protexido por contrasinal
creado cunha <b>versión de andOTP inferior a 0.6.3</b></string>
<string name="backup_desc_import_openpgp">Restaurar contas desde un ficheiro JSON cifrado con OpenPGP</string>
<string name="backup_desc_crypt_setup">Houbo un erro ao cargar o contrasinal de respaldo desde os <b>Axustes</b>,
ou ben non se estableceu o contrasinal ou algo fallou. Pediráselle introducir ou ben non se estableceu o contrasinal ou algo fallou. Pediráselle introducir
o contrasinal manualmente ao crear ou importar un respaldo. o contrasinal manualmente ao crear ou importar un respaldo.
</string> </string>
<string name="backup_desc_openpgp_provider">Necesitas instalar un aplicarivo OpenPGP e activalo <string name="backup_desc_openpgp_provider">Necesitas instalar un aplicarivo OpenPGP e activalo
na <b>configuración</b> para usar esta opción. na <b>configuración</b> para usar esta opción.
</string> </string>
<string name="backup_desc_openpgp_keyid">Necesitas seleccionar unha chave OpenPGP nos <b>Axustes</b> <string name="backup_desc_openpgp_keyid">Necesitas seleccionar unha chave OpenPGP nos <b>Axustes</b>
antes de crear unha copia de seguranza cifrada. antes de crear unha copia de seguranza cifrada.
</string> </string>
<string name="backup_desc_replace">Si se habilita todas as entradas antigas reemplazaranse ao importar <string name="backup_desc_replace">Si se habilita todas as entradas antigas reemplazaranse ao importar
o respaldo e só aparecerán as do respaldo. Si se deshabilita aparecerán tanto as entradas antigas como as do respaldo.</string> o respaldo e só aparecerán as do respaldo. Si se deshabilita aparecerán tanto as entradas antigas como as do respaldo.</string>
<!-- Dialogs --> <!-- Dialogs -->
<string name="backup_dialog_title_security_warning">Advertencia de seguranza</string> <string name="backup_dialog_title_security_warning">Advertencia de seguranza</string>
<string name="backup_dialog_msg_export_warning">¿Queres exportar a base de datos como <string name="backup_dialog_msg_export_warning">¿Queres exportar a base de datos como
ficheiro de texto plano JSON? Este ficheiro inclúe as túas chaves secretas, por favor <b>manteno seguro</b>! ficheiro de texto plano JSON? Este ficheiro inclúe as túas chaves secretas, por favor <b>manteno seguro</b>!
</string> </string>
<string name="backup_receiver_title_backup_failed">Erro na copia de seguranza</string> <string name="backup_receiver_title_backup_failed">Erro na copia de seguranza</string>
<string name="backup_receiver_title_backup_success">Respaldo realizado correctamente</string> <string name="backup_receiver_title_backup_success">Respaldo realizado correctamente</string>
<string name="backup_receiver_plain_disabled">Actualmente non se permiten os respaldos en texto plano, <string name="backup_receiver_plain_disabled">Actualmente non se permiten os respaldos en texto plano,
vaia aos Axustes para activalos</string> vaia aos Axustes para activalos</string>
<string name="backup_receiver_encrypted_disabled">Actualmente non se permiten os respaldos cifrados, <string name="backup_receiver_encrypted_disabled">Actualmente non se permiten os respaldos cifrados,
vaia aos Axustes para activalos</string> vaia aos Axustes para activalos</string>
<string name="backup_receiver_read_permission_failed">Non se obtivo permiso de lectura, por favor <string name="backup_receiver_read_permission_failed">Non se obtivo permiso de lectura, por favor
axuste esto antes de intentar o respaldo</string> axuste esto antes de intentar o respaldo</string>
<string name="backup_receiver_write_permission_failed">Non ten permiso de escritura, por favor <string name="backup_receiver_write_permission_failed">Non ten permiso de escritura, por favor
arranxe esto ante de intentas o respaldo</string> arranxe esto ante de intentas o respaldo</string>
<string name="backup_receiver_custom_encryption_failed">O cifrado con Contrasinal/PIN non <string name="backup_receiver_custom_encryption_failed">O cifrado con Contrasinal/PIN non
está soportado con respaldo remoto</string> está soportado con respaldo remoto</string>
<!-- Notification channels --> <string name="backup_new_format_dialog_title">Novo método de cifrado</string>
<string name="notification_channel_name_backup_failed">Fallo no respaldo automático</string> <string name="backup_new_format_dialog_msg">Dende a versión 0.6.3 de andOTP, úsase un <b>novo e mellorado
<string name="notification_channel_name_backup_success">Respaldo automático correcto</string> método de cifrado</b> para copias de seguridade protexidas por contrasinal. As copias de seguridade antigas
<string name="notification_channel_desc_backup_failed">Estas notificacións móstranse cando un respaldo aínd poden ser importadas, pero é <b>moi recomendable crear novas copias de seguridade co novo cifrado
mellorado</b>.\n\nEsta mensaxe non se mostrará de novo.</string>
<!-- Notification channels -->
<string name="notification_channel_name_backup_failed">Fallo no respaldo automático</string>
<string name="notification_channel_name_backup_success">Respaldo automático correcto</string>
<string name="notification_channel_desc_backup_failed">Estas notificacións móstranse cando un respaldo
automático fallou por algunha razón</string> automático fallou por algunha razón</string>
<string name="notification_channel_desc_backup_success">Estas notificacións mótranse cando <string name="notification_channel_desc_backup_success">Estas notificacións mótranse cando
un respaldo automático se realizou correctamente</string> un respaldo automático se realizou correctamente</string>
<!-- Toast messages --> <!-- Toast messages -->
<string name="backup_toast_mkdir_failed">Erro ao crear o directorio de copia de seguranza</string> <string name="backup_toast_mkdir_failed">Erro ao crear o directorio de copia de seguranza</string>
<string name="backup_toast_export_success">Exportado correctamente ao almacenamento externo</string> <string name="backup_toast_export_success">Exportado correctamente ao almacenamento externo</string>
<string name="backup_toast_export_failed">Fallo ao exportar ao almacenamento externo</string> <string name="backup_toast_export_failed">Fallo ao exportar ao almacenamento externo</string>
<string name="backup_toast_import_success">Importado correctamente desde o almacenamento externo</string> <string name="backup_toast_import_success">Importado correctamente desde o almacenamento externo</string>
<string name="backup_toast_import_save_failed">Erro ao gardar os elementos restaurados</string> <string name="backup_toast_import_save_failed">Erro ao gardar os elementos restaurados</string>
<string name="backup_toast_import_decryption_failed">Erro ao descifrar a copia de seguranza</string> <string name="backup_toast_import_decryption_failed">Erro ao descifrar a copia de seguranza</string>
<string name="backup_toast_import_no_entries">Non se atoparon elementos nos datos importados</string> <string name="backup_toast_import_no_entries">Non se atoparon elementos nos datos importados</string>
<string name="backup_toast_storage_not_accessible">O almacenamento externo non é accesible actualmente</string> <string name="backup_toast_storage_not_accessible">O almacenamento externo non é accesible actualmente</string>
<string name="backup_toast_storage_permissions">Permiso de almacenamento non concedido</string> <string name="backup_toast_storage_permissions">Permiso de almacenamento non concedido</string>
<string name="backup_toast_openpgp_error">Error OpenPGP: %s</string> <string name="backup_toast_openpgp_error">Error OpenPGP: %s</string>
<string name="backup_toast_openpgp_not_verified">Non se detectou unha sinatura verificable</string> <string name="backup_toast_openpgp_not_verified">Non se detectou unha sinatura verificable</string>
<string name="backup_toast_crypt_password_not_set">No se estableceu un contrasinal, revisa os <b>axustes</b></string> <string name="backup_toast_crypt_password_not_set">No se estableceu un contrasinal, revisa os <b>axustes</b></string>
</resources> </resources>

View file

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com--> <!--Generated by crowdin.com-->
<resources> <resources>
<string name="intro_slide1_title">Comecemos</string> <string name="intro_slide1_title">Comecemos</string>
<string name="intro_slide1_desc">Ben vido a <b>andOTP</b>, este asistente guiarao a través da configuración <string name="intro_slide1_desc">Ben vido a <b>andOTP</b>, este asistente guiarao a través da configuración
inicial. Poña atención e lea coidadosamente xa que pode perder datos importantes! inicial. Poña atención e lea coidadosamente xa que pode perder datos importantes!
\n\nNon se preocupe, pode mudar as opcións a posteriori nos <b>Axustes</b>.</string> \n\nNon se preocupe, pode mudar as opcións a posteriori nos <b>Axustes</b>.</string>
<string name="intro_slide2_desc">Para asegurar a seguridade das súas contas <b>andOTP</b> <string name="intro_slide2_desc">Para asegurar a seguridade das súas contas <b>andOTP</b>
garda información en ficheiros cifrados. Aquí pode escoller o método de cifrado que se garda información en ficheiros cifrados. Aquí pode escoller o método de cifrado que se
utilizará.</string> utilizará.</string>
<string name="intro_slide2_desc_keystore">A KeyStore é un compoñente do sistema Android para <string name="intro_slide2_desc_keystore">A KeyStore é un compoñente do sistema Android para
gardar de xeito seguro chaves de cifrado. A vantaxe de este método é que as chaves gárdanse gardar de xeito seguro chaves de cifrado. A vantaxe de este método é que as chaves gárdanse
de xeito separado dos ficheiros de datos e poden ser respaldadas por cifrado de hardware (si o seu dispositivo de xeito separado dos ficheiros de datos e poden ser respaldadas por cifrado de hardware (si o seu dispositivo
o admite). Porén, as chaves non se gardan cos datos do aplicativo, <b>este método o admite). Porén, as chaves non se gardan cos datos do aplicativo, <b>este método
@ -16,19 +16,19 @@
deberá confiar nas funcións internas de respaldo proporcionadas por <b>andOTP</b>. deberá confiar nas funcións internas de respaldo proporcionadas por <b>andOTP</b>.
\n\n<b>Aviso:</b>: A KeyStore sábese que da problemas, utilícea só si non lle queda alternativa. \n\n<b>Aviso:</b>: A KeyStore sábese que da problemas, utilícea só si non lle queda alternativa.
Si non lle importa introducir un contrasinal/PIN cada vez que inicia <b>andOTP</b> é moito <b>máis recomendable utilizar o cifrado baseado en contrasinal</b>.</string> Si non lle importa introducir un contrasinal/PIN cada vez que inicia <b>andOTP</b> é moito <b>máis recomendable utilizar o cifrado baseado en contrasinal</b>.</string>
<string name="intro_slide2_desc_password">Este método cifrará os seus datos con unha chave <string name="intro_slide2_desc_password">Este método cifrará os seus datos con unha chave
xerada por un contrasinal ou PIN. A principal vantaxe é que esto é compatible con xerada por un contrasinal ou PIN. A principal vantaxe é que esto é compatible con
solucións externas de respaldo (como Titanium) e é moito menos proclive ao fallo que a KeyStore. solucións externas de respaldo (como Titanium) e é moito menos proclive ao fallo que a KeyStore.
Porén, deberá introducir as súas credenciais cada vez que inicia <b>andOTP</b>.</string> Porén, deberá introducir as súas credenciais cada vez que inicia <b>andOTP</b>.</string>
<string name="intro_slide3_desc_keystore">Aquí pode configurar a autenticación para asegurar <string name="intro_slide3_desc_keystore">Aquí pode configurar a autenticación para asegurar
<b>andOTP</b>. Esto é opcional xa que escolleu <b>Android KeyStore</b> como método de cifrado.</string> <b>andOTP</b>. Esto é opcional xa que escolleu <b>Android KeyStore</b> como método de cifrado.</string>
<string name="intro_slide3_desc_password">Aquí pode configurar a autenticación da seguranza <string name="intro_slide3_desc_password">Aquí pode configurar a autenticación da seguranza
de <b>andOTP</b>. Debe establecer un Contrasinal ou PIN xa que escolleu <b>Contrasinal/PIN</b> como método de cifrado.</string> de <b>andOTP</b>. Debe establecer un Contrasinal ou PIN xa que escolleu <b>Contrasinal/PIN</b> como método de cifrado.</string>
<string name="intro_slide3_warn_no_password">Por favor estableza un contrasinal para continuar!</string> <string name="intro_slide3_warn_no_password">Por favor estableza un contrasinal para continuar!</string>
<string name="intro_slide3_warn_no_pin">Por favor escolla un PIN para continuar!</string> <string name="intro_slide3_warn_no_pin">Por favor escolla un PIN para continuar!</string>
<string name="intro_slide3_warn_confirm_password">Confirme o contrasinal para continuar!</string> <string name="intro_slide3_warn_confirm_password">Confirme o contrasinal para continuar!</string>
<string name="intro_slide3_warn_confirm_pin">Confirme o PIN para continuar!</string> <string name="intro_slide3_warn_confirm_pin">Confirme o PIN para continuar!</string>
<string name="intro_slide4_title">Rematou</string> <string name="intro_slide4_title">Rematou</string>
<string name="intro_slide4_desc">Gardáronse os seus axustes, xa pode utilizar <string name="intro_slide4_desc">Gardáronse os seus axustes, xa pode utilizar
<b>andOTP</b> agora!</string> <b>andOTP</b> agora!</string>
</resources> </resources>

Some files were not shown because too many files have changed in this diff Show more