Compare commits

...

134 Commits

Author SHA1 Message Date
Philipp Crocoll
8468049935 manifest for 1.06f release 2018-11-10 08:38:13 +01:00
Philipp Crocoll
7cef6c8566 Merge branch 'nonet' of https://github.com/PhilippC/keepass2android into nonet
# Conflicts:
#	src/keepass2android/Properties/AndroidManifest_nonet.xml
#	src/keepass2android/keepass2android.csproj
2018-11-08 05:23:10 +01:00
Philipp Crocoll
98f2a139e9 Merge remote-tracking branch 'remotes/origin/1.06' into nonet
# Conflicts:
#	src/keepass2android/Properties/AndroidManifest_nonet.xml
2018-11-08 04:55:44 +01:00
Philipp Crocoll
135d7ebda5 keep old keyboard dialog for Android <= 8, fix bugs with keyboard labels, release 1.06f 2018-09-10 09:51:53 +02:00
Philipp Crocoll
337297e3e0 manifest for 1.06d 2018-08-28 20:54:56 +02:00
Philipp Crocoll
26def9805f avoid potential OutOfBounds exception 2018-08-28 20:47:50 +02:00
Philipp Crocoll
5429876cde fix potential NullPointerExceptions 2018-08-28 05:39:28 +02:00
Philipp Crocoll
d13b2d236b manifest for 1.06c 2018-08-27 12:14:07 +02:00
Philipp Crocoll
9dce637d22 fix potential crash in FileSelectActivity 2018-08-27 12:06:04 +02:00
Philipp Crocoll
dbb291fb86 implement a new way to select additional fields in the keyboard, closes https://github.com/PhilippC/keepass2android/issues/377 2018-08-27 11:18:46 +02:00
Philipp Crocoll
bc2dc1b2e9 manifest for 1.06b 2018-08-23 07:01:36 +02:00
PhilippC
2d9429d688 Merge pull request #514 from PhilippC/l10n_master
New Crowdin translations
2018-08-21 20:35:40 +02:00
PhilippC
62f3ff1902 New translations strings.xml (German) 2018-08-21 20:32:04 +02:00
PhilippC
36735cdfbe New translations strings.xml (Chinese Traditional) 2018-08-21 20:31:51 +02:00
PhilippC
f57db90d7b New translations strings.xml (Portuguese, Brazilian) 2018-08-21 20:31:23 +02:00
Philipp Crocoll
97aec23384 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-08-21 20:27:59 +02:00
PhilippC
eb3bcf04ea Merge pull request #467 from PhilippC/l10n_master
New Crowdin translations
2018-08-21 20:27:13 +02:00
PhilippC
40626ba708 New translations strings.xml (Chinese Simplified) 2018-08-21 20:23:42 +02:00
PhilippC
882597365b New translations strings.xml (Portuguese) 2018-08-21 20:23:16 +02:00
PhilippC
6b456c2f57 New translations strings.xml (German) 2018-08-21 19:41:08 +02:00
PhilippC
515ae57e88 New translations strings.xml (French) 2018-08-21 19:41:04 +02:00
PhilippC
9cc9d6ab66 New translations strings.xml (Croatian) 2018-08-21 19:40:55 +02:00
PhilippC
40b4fd210a New translations strings.xml (Chinese Traditional) 2018-08-21 19:40:53 +02:00
PhilippC
2ce2d0efab New translations strings.xml (Portuguese, Brazilian) 2018-08-21 19:40:24 +02:00
PhilippC
97a863293d New translations strings.xml (Polish) 2018-08-21 19:40:20 +02:00
PhilippC
d45426a4c1 New translations strings.xml (Persian) 2018-08-21 19:40:17 +02:00
Philipp Crocoll
d5a49db782 Prevent users from accidentally opening the local backup, closes #479 2018-08-21 19:34:22 +02:00
Philipp Crocoll
4b393f412c avoid exception with new Keyboard dialog on some devices 2018-08-21 07:25:31 +02:00
Philipp Crocoll
8cc77fbe1d hide password input fields from accessibility services 2018-08-20 16:56:20 +02:00
PhilippC
673632bd92 Merge pull request #487 from mohammadnaseri/master
Password should be invisible to the accessibility services: fixed for entering online storage credentials
2018-08-20 16:47:08 +02:00
Philipp Crocoll
d2b9a5d1a9 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-08-20 16:45:34 +02:00
Philipp Crocoll
2bc46b0a0e fix a local build issue 2018-08-20 16:44:32 +02:00
Philipp Crocoll
74200daf90 finish transition to custom activity as dialog instead of using AlertDialog which is no longer working in Android P, closes #377 2018-08-20 16:44:23 +02:00
Philipp Crocoll
b89c127df4 try to introduce an activity as dialog for string selection, not yet working 2018-08-20 15:44:22 +02:00
Philipp Crocoll
67bbbb2097 handle empty initialPath in sftp dialog to close #499 2018-08-18 06:08:08 +02:00
PhilippC
c6ddf0de87 New translations strings.xml (Vietnamese) 2018-08-16 19:10:06 +02:00
Philipp Crocoll
0ef73952b1 fix crash when no FingerprintManager is available, fixes #474 2018-08-15 04:47:38 +02:00
PhilippC
0e02a3aeee New translations strings.xml (Croatian) 2018-08-12 16:00:05 +02:00
Mohammad Naseri
1558a7c386 Password should be invisible to the accessibility services 2018-08-03 12:38:48 +02:00
PhilippC
b72becd328 New translations strings.xml (Swedish) 2018-08-03 11:40:06 +02:00
PhilippC
df2ac8e203 New translations strings.xml (Portuguese) 2018-07-26 12:00:09 +02:00
PhilippC
c6c230002c New translations strings.xml (Portuguese) 2018-07-26 11:50:06 +02:00
PhilippC
885503b5fa New translations strings.xml (Persian) 2018-07-24 21:10:10 +02:00
PhilippC
40fd91257e New translations strings.xml (Vietnamese) 2018-07-23 13:40:11 +02:00
PhilippC
02ece3cf41 New translations strings.xml (Chinese Simplified) 2018-07-23 13:40:08 +02:00
PhilippC
901c879647 New translations strings.xml (Catalan) 2018-07-23 13:40:05 +02:00
PhilippC
990a73f4a4 New translations strings.xml (Chinese Traditional) 2018-07-23 13:31:16 +02:00
PhilippC
73169d339d New translations strings.xml (Croatian) 2018-07-23 13:31:14 +02:00
PhilippC
265b86c031 New translations strings.xml (Czech) 2018-07-23 13:31:11 +02:00
PhilippC
7c29c23015 New translations strings.xml (Danish) 2018-07-23 13:31:08 +02:00
PhilippC
538e579477 New translations strings.xml (Dutch) 2018-07-23 13:31:06 +02:00
PhilippC
73db5f55e2 New translations strings.xml (Finnish) 2018-07-23 13:31:02 +02:00
PhilippC
31a9980343 New translations strings.xml (French) 2018-07-23 13:31:00 +02:00
PhilippC
02c50f510f New translations strings.xml (Galician) 2018-07-23 13:30:57 +02:00
PhilippC
3541ee0512 New translations strings.xml (German) 2018-07-23 13:30:54 +02:00
PhilippC
e72821ba1e New translations strings.xml (Greek) 2018-07-23 13:30:51 +02:00
PhilippC
3af00871a5 New translations strings.xml (Hebrew) 2018-07-23 13:30:48 +02:00
PhilippC
22fe4ca790 New translations strings.xml (Bulgarian) 2018-07-23 13:30:46 +02:00
PhilippC
72d0570c15 New translations strings.xml (Hungarian) 2018-07-23 13:30:43 +02:00
PhilippC
62e0cc0867 New translations strings.xml (Italian) 2018-07-23 13:30:40 +02:00
PhilippC
8987480491 New translations strings.xml (Japanese) 2018-07-23 13:30:38 +02:00
PhilippC
70bb4c2478 New translations strings.xml (Korean) 2018-07-23 13:30:35 +02:00
PhilippC
cf079a6be4 New translations strings.xml (Portuguese, Brazilian) 2018-07-23 13:30:33 +02:00
PhilippC
f153cdcba1 New translations strings.xml (Russian) 2018-07-23 13:30:30 +02:00
PhilippC
4e048240c5 New translations strings.xml (Serbian (Cyrillic)) 2018-07-23 13:30:27 +02:00
PhilippC
c098bb1ca0 New translations strings.xml (Slovak) 2018-07-23 13:30:24 +02:00
PhilippC
e02ded734c New translations strings.xml (Slovenian) 2018-07-23 13:30:22 +02:00
PhilippC
e721f29f5a New translations strings.xml (Spanish) 2018-07-23 13:30:19 +02:00
PhilippC
f763d5f936 New translations strings.xml (Swedish) 2018-07-23 13:30:17 +02:00
PhilippC
a3368eb557 New translations strings.xml (Turkish) 2018-07-23 13:30:14 +02:00
PhilippC
b5758347c2 New translations strings.xml (Ukrainian) 2018-07-23 13:30:11 +02:00
PhilippC
775a6d92aa New translations strings.xml (Indonesian) 2018-07-23 13:30:09 +02:00
PhilippC
2ab5995177 New translations strings.xml (Basque) 2018-07-23 13:30:06 +02:00
PhilippC
f6e847d43f New translations strings.xml (Portuguese) 2018-07-23 13:28:28 +02:00
PhilippC
cac2ca3d18 New translations strings.xml (Polish) 2018-07-23 13:28:26 +02:00
PhilippC
d1e870cee0 New translations strings.xml (Persian) 2018-07-23 13:28:24 +02:00
PhilippC
ca0f65767b New translations strings.xml (Norwegian Nynorsk) 2018-07-23 13:28:22 +02:00
PhilippC
7968bfc262 New translations strings.xml (Norwegian Bokmal) 2018-07-23 13:28:19 +02:00
PhilippC
ed4bbe9814 New translations strings.xml (Romanian) 2018-07-23 13:28:16 +02:00
PhilippC
6e83eb6da2 New translations strings.xml (Arabic) 2018-07-23 13:28:14 +02:00
PhilippC
00949b6135 Update Crowdin configuration file 2018-07-23 11:37:54 +02:00
Philipp Crocoll
f3a857f26f Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-07-23 11:00:38 +02:00
PhilippC
4bd03372aa Update Crowdin configuration file 2018-07-23 10:36:20 +02:00
Philipp Crocoll
dcc589c57a Changelog for 1.06 2018-07-23 10:29:55 +02:00
Philipp Crocoll
3018ec8cf0 update translations from crowdin 2018-07-23 10:29:48 +02:00
Philipp Crocoll
c452a66a4f don't try to use samsung api if Fingprint Unlock with Android API is set up, should fix #126 2018-07-23 10:07:30 +02:00
Philipp Crocoll
7a860f8564 fix #460 ("Lookup entry with "%1$s"") 2018-07-20 21:44:29 +02:00
Philipp Crocoll
94f6f4bdff fix string error 2018-07-16 13:07:43 +02:00
Philipp Crocoll
a627dac4b7 remove internal YubiChallenge activity in favor of ykdroid (allows to reduce required permissions) 2018-07-16 13:07:29 +02:00
Philipp Crocoll
848b6862be harmonize wording for caching, closes #86 2018-07-13 06:47:48 +02:00
Philipp Crocoll
d181575e93 improve wording for file caching at more places (see discussion in #86) 2018-07-12 21:23:06 +02:00
Philipp Crocoll
778775055f suggest to enable fingerprint if hardware is detected but fingerprint unlock not configured, closes #426 and closes #355 2018-07-12 06:44:02 +02:00
Philipp Crocoll
22ccda8d34 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-07-12 05:29:08 +02:00
Philipp Crocoll
c5fc6fd72e manifest for next release 2018-07-12 05:28:59 +02:00
Philipp Crocoll
c8a4978b5f improve wording for file caching, considering that this is also used for the offline version (see discussion in #86) 2018-07-12 05:27:01 +02:00
PhilippC
9e88f8c884 Merge pull request #449 from pp3345/ykdroid-keyboard-configuration
Mark keyboard configuration changes as handled in PasswordActivity
2018-07-10 22:25:06 +02:00
Yussuf Khalil
2e543bf4d3 Mark keyboard configuration changes as handled in PasswordActivity
This is required to avoid screen flickering due to recreation of the
activity when the ykDroid overlay is presented.
2018-07-10 19:30:08 +02:00
Philipp Crocoll
caf42d423f make sure the underlying stream is only written when the write transaction is commited. Avoids corrupted files when cancelling Yubichallenge during saving (#4) 2018-07-09 12:34:21 +02:00
Philipp Crocoll
dc39f874ac fix potential null reference exception when displaying error message 2018-07-09 12:27:29 +02:00
Philipp Crocoll
d1c7a124cf don't return empty strings for filename without path and ext in content storage, fixes #446 2018-07-09 11:03:10 +02:00
Philipp Crocoll
8ec17ce9a6 add timeout to fix #444 2018-07-09 10:22:44 +02:00
Philipp Crocoll
012af35e87 fix potential crash in SearchProvider, fixes #429 2018-07-03 19:38:59 +02:00
Philipp Crocoll
78bd1f4a5d update translations from crowdin, activates KeepassXC-challenge-response for all languages, add Changelog for 1.06-pre1 2018-07-02 12:54:25 +02:00
Philipp Crocoll
4477158182 editing groups was not possible, fixed. fixes #434 2018-07-02 12:10:28 +02:00
Philipp Crocoll
6e96021047 allow to use ykDroid instead of built-in activity 2018-07-02 12:03:32 +02:00
Philipp Crocoll
48f57eea66 fix bug with progress dialog not disappearing somtimes 2018-07-02 12:01:47 +02:00
Philipp Crocoll
4b6cfefaf3 Merge branch '1.05b' 2018-06-30 22:14:03 +02:00
Philipp Crocoll
0e34cc7f26 change manifest version to 1.06-pre 2018-06-30 22:13:16 +02:00
Philipp Crocoll
27fb2870ab check if file is trashed, do not load trashed files, fixes #165 2018-06-30 22:13:00 +02:00
Philipp Crocoll
ee6b7c4fe0 Merge branch 'master' of https://github.com/PhilippC/keepass2android 2018-06-30 21:45:13 +02:00
Philipp Crocoll
0464cecde5 add roundIcon property for app, now round icon should work on Android 7 2018-06-30 21:21:48 +02:00
Philipp Crocoll
b237259599 fix incorrect folder icon (fixes #433) 2018-06-30 21:10:56 +02:00
Philipp Crocoll
8c379739f0 refactoring of ProgressTask and OnFinish classes, allowing to access the currently active activity from the task handlers. This fixes #33 and is required to correctly manage the activity recreation caused by the NFC activity coming to foreground with KeepassXC challenge (#4) 2018-06-26 13:44:48 +02:00
Philipp Crocoll
4fb8db982c add missing calls to base.OnActivityResult() in *EditActivity, leading to errors saving with YubiChallenge (#4). 2018-06-25 13:24:22 +02:00
Philipp Crocoll
921b50b642 add NFC permission to debug manifest also 2018-06-25 13:23:34 +02:00
Philipp Crocoll
031332e8ab re-add KeepassXC-style challenge response support 2018-06-25 13:23:24 +02:00
Philipp Crocoll
f03ccced8d Merge branch 'master' into 1.05b 2018-06-25 12:21:34 +02:00
Philipp Crocoll
51973d225c switch to suggested Native TLS implementation and HttpClient stack (https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/http-stack?tabs=windows) 2018-06-23 13:08:32 +02:00
Philipp Crocoll
a59666e752 workaround to fix #420, based on https://stackoverflow.com/questions/28411153/jsch-suppressed-java-lang-classnotfoundexception-lorg-ietf-jgss-oid/28965796#28965796 and https://github.com/zeapo/Android-Password-Store/issues/49 2018-06-23 13:03:51 +02:00
PhilippC
8259191e50 Merge pull request #415 from jakseb/docfix
Fix broken links to screenshots in documentation
2018-06-23 12:08:44 +02:00
Philipp Crocoll
832d3b3a95 1.05d release for nonet 2018-06-23 09:07:47 +02:00
Philipp Crocoll
37867634cd Merge branch 'master' into nonet
Conflicts:
	src/keepass2android/Properties/AndroidManifest_nonet.xml
2018-06-18 13:08:07 +02:00
Sebastian Jakubiak
82f28bfc8c Update links to screenshots in docs
Fixes #366 and #396
2018-06-16 11:04:02 +02:00
Philipp Crocoll
a1d6347db3 create own YubiChallenge activity 2018-05-28 10:39:09 +02:00
PhilippC
e66a8a0b21 Merge pull request #367 from gacelperfinian/patch-1
Updated Documentation.md to GitHub-flavoured MarkDown
2018-05-07 10:56:10 +02:00
Gacel Perfinian
186fa35f70 Updated Documentation.md to GitHub-flavoured MarkDown
Changes:
- Changed last bullet in **What you should know and think about** into two bullet points due to change 2.
- Changed MarkDown so it renders correctly on GitHub Parser.
- Changed wording into bullet 2.2 to emphasise storing any second-factor authentication (if any was used).
2018-05-04 14:13:02 +08:00
Philipp Crocoll
d9713f8e18 switch to using Release build type instead of ReleaseNoNet (separation no longer required because a custom branch exists for the offline variant) 2018-02-28 06:06:26 +01:00
Philipp Crocoll
c583b58cb9 adjust manifest version for 1.04b release 2018-02-27 06:06:35 +01:00
Philipp Crocoll
bfeaf5dbf5 Merge branch '1.04' into nonet
Conflicts:
	src/keepass2android/Properties/AndroidManifest_nonet.xml
2018-02-21 05:58:01 +01:00
Philipp Crocoll
0907fa5685 manifest for 1.03-nonet release 2017-12-02 15:30:04 +01:00
Philipp Crocoll
ff8dc76c75 Merge branch 'master' into nonet
Conflicts:
	docs/README.md
2017-12-02 14:25:37 +01:00
Philipp Crocoll
0b09e2790f remove online file storages from project file 2017-10-25 06:49:02 +02:00
Philipp Crocoll
781350aa5f manifest for 1.02 release 2017-10-25 06:24:01 +02:00
Philipp Crocoll
9716130336 remove references to libraries only required for online build, adjust build script and README 2017-10-25 06:23:53 +02:00
151 changed files with 9059 additions and 1973 deletions

6
crowdin.yml Normal file
View File

@@ -0,0 +1,6 @@
files:
- source: src/keepass2android/Resources/values/strings.xml
translation: >-
/src/keepass2android/Resources/values-%two_letters_code%/%original_file_name%
translate_attributes: '0'
content_segmentation: '0'

View File

@@ -7,11 +7,12 @@ If you think something is missing in the documentation, please create an issue a
If you store important information using Keepass2Android, you should know a little bit about what's going on:
* Keepass2Android stores your password in an encrypted file. It is *your responsibility* to backup this file regularly and safely.
* There is no way for anyone, including the app's author, to access the information stored in your password database without
** having the database file
** knowing the master password (and additional second factor if you chose one)
This means that **if you forget the master password, your database is lost**! So make sure you remember the password. You might also want to think about:
** What happens if I have an accident? Should any trusted person be able to access my database?
** What happens if my phone gets lost or stolen? Do I know how to recover my database from a backup or the cloud?
* having the database file
* knowing the master password (and additional second factor if you chose one)
This means that **if you forget the master password, your database is lost**! So make sure you remember the password and retain any second factor method (if one is used).
* You might also want to think about:
* What happens if I have an accident? Should any trusted person be able to access my database?
* What happens if my phone gets lost or stolen? Do I know how to recover my database from a backup or the cloud?
# Getting started

View File

@@ -4,28 +4,28 @@
on how to set up a Keepass 2 database with Yubikey/OTP protection.<br>
<br>
After successful setup you should have the database file, e.g. yubi.kdbx, and the OTP auxiliary file, e.g. yubi.otp.xml, both in the same folder.<br>
<a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767825"><img title="OTPAuxFile" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767826" alt="OTPAuxFile" width="513" height="40" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
<a href="How to use Keepass2Android with YubiKey NEO_OTPAuxFile_2.png"><img title="OTPAuxFile" src="How to use Keepass2Android with YubiKey NEO_OTPAuxFile_thumb.png" alt="OTPAuxFile" width="513" height="40" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
<p>Make sure you make <strong>both files</strong> available to Keepass2Android, e.g. by placing them both in your Dropbox.</p>
<p>Now you should check your NDEF setup of the Yubikey NEO. Therefore, go to the Tools menu in the Yubico Personalization Utility. Select the same slot as used for OTPs with Keepass 2. The default setting for NDEF type and payload should work. If you experience
problems, you may use the configuration as shown in this screenshot or simply press the &ldquo;Reset&rdquo; button:</p>
<p><a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767911"><img title="image" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767912" alt="image" width="760" height="622" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
<p><a href="How to use Keepass2Android with YubiKey NEO_image_2.png"><img title="image" src="How to use Keepass2Android with YubiKey NEO_image_thumb.png" alt="image" width="760" height="622" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
<p><br>
<br>
In Keepass2Android, select &quot;Open file&quot; and locate your database file, e.g. yubi.kdbx.<br>
<br>
In the password screen under &quot;Select master key type&quot; select &quot;Password &#43; OTP&quot;.</p>
<p><a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767913"><img title="Screenshot_2013-12-13-06-38-50" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767914" alt="Screenshot_2013-12-13-06-38-50" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
<p><a href="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-50_2.png"><img title="Screenshot_2013-12-13-06-38-50" src="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-50_thumb.png" alt="Screenshot_2013-12-13-06-38-50" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
<p>Click &quot;Load auxiliary OTP file&quot;. This is required to load the information how many OTPs must be entered. As loading the file might require user action in some cases, this is not performed automatically.<br>
<a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767915"><img title="Screenshot_2013-12-13-06-38-12" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767916" alt="Screenshot_2013-12-13-06-38-12" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a><br>
<a href="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-12_2.png"><img title="Screenshot_2013-12-13-06-38-12" src="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-12_thumb.png" alt="Screenshot_2013-12-13-06-38-12" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a><br>
After loading the OTP auxiliary file, you should see a few text fields for entering the OTPs. Now swipe your YubiKey NEO at the back of your Android device. If you have multiple apps which can handle NFC actions, you might be prompted to select which app to
use. Select Keepass2Android in this case. Swipe your YubiKey again until all OTP fields are filled. Note: You don't need to select the next text field, this is done automatically!<br>
<a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767917"><img title="Screenshot_2013-12-13-06-38-36" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767918" alt="Screenshot_2013-12-13-06-38-36" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a><br>
<a href="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-36_2.png"><img title="Screenshot_2013-12-13-06-38-36" src="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-38-36_thumb.png" alt="Screenshot_2013-12-13-06-38-36" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a><br>
Don't forget to also enter your password and click OK. You will see the &ldquo;Saving auxiliary OTP file&hellip;&rdquo; dialog. Note that there is some encryption envolved which is probably fast on your PC but might take some time on your mobile device. You
can reduce the look-ahead window length to speed this up.<br>
<a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767919"><img title="Screenshot_2013-12-13-06-39-47" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=keepass2android&DownloadId=767920" alt="Screenshot_2013-12-13-06-39-47" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
<a href="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-39-47_2.png"><img title="Screenshot_2013-12-13-06-39-47" src="How to use Keepass2Android with YubiKey NEO_Screenshot_2013-12-13-06-39-47_thumb.png" alt="Screenshot_2013-12-13-06-39-47" width="204" height="360" border="0" style="padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border:0px"></a></p>
<h2>&nbsp;</h2>
<h2>A note about offline access</h2>
<p>If your database is stored in the cloud or on the web, you can still access it if you have enabled file caching (which is on by default). With OTPs, this becomes a little bit more complicated: If you repeatedly open your datbase while being offline, the
OTP counter stored on the Yubikey will be increased. Don&rsquo;t forget to synchronize the database (which will also synchronize the OTP auxiliary file) as soon as possible to avoid problems with accessing your database on other devices! If you often need
to open the database while you&rsquo;re offline, consider increasing the look-ahead window length!</p>
</div><div class="ClearBoth"></div>
</div><div class="ClearBoth"></div>

View File

@@ -15,4 +15,4 @@ Beta-releases can be obtained by opting in to the [Beta testing channel](https:/
# How do I learn more?
Please see the [documentation](Documentation.md).
[![Build Status](https://www.bitrise.io/app/43a23ab54dee9f7e/status.svg?token=2vryTsMQzTX3XRPikhgRwA&branch=master)](https://www.bitrise.io/app/43a23ab54dee9f7e)
[![Build Status](https://www.bitrise.io/app/43a23ab54dee9f7e/status.svg?token=2vryTsMQzTX3XRPikhgRwA&branch=nonet)](https://www.bitrise.io/app/43a23ab54dee9f7e)

View File

@@ -26,6 +26,7 @@
android:hint="@string/http_auth_dialog_password"
android:inputType="textPassword"
android:paddingTop="10dp"
android:paddingBottom="20dp" />
android:paddingBottom="20dp"
android:importantForAccessibility="no" />
</LinearLayout>

View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2009
VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
EndProject
@@ -13,8 +13,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aBusinessLogic", "Kp2aBu
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwofishCipher", "TwofishCipher\TwofishCipher.csproj", "{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaFileStorageBindings", "JavaFileStorageBindings\JavaFileStorageBindings.csproj", "{48574278-4779-4B3A-A9E4-9CF1BC285D0B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidFileChooserBinding", "AndroidFileChooserBinding\AndroidFileChooserBinding.csproj", "{3C0F7FE5-639F-4422-A087-8B26CF862D1B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KP2AKdbLibraryBinding", "KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj", "{70D3844A-D9FA-4A64-B205-A84C6A822196}"
@@ -23,8 +21,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginSdkBinding", "PluginS
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZlibAndroid", "ZlibAndroid\ZlibAndroid.csproj", "{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.FtpClient.Android", "netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj", "{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}"
EndProject
Global
@@ -109,8 +105,8 @@ Global
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|Win32.Build.0 = Release|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.ActiveCfg = Release|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.Release|x64.Build.0 = Release|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = Debug|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = Debug|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{A8779D4D-7C49-4C2F-82BD-2CDC448391DA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
@@ -151,24 +147,6 @@ Global
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|Win32.ActiveCfg = Debug|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Debug|x64.ActiveCfg = Debug|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Any CPU.Build.0 = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|Win32.ActiveCfg = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.Release|x64.ActiveCfg = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{48574278-4779-4B3A-A9E4-9CF1BC285D0B}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -181,8 +159,8 @@ Global
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|Win32.ActiveCfg = Release|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.Release|x64.ActiveCfg = Release|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{3C0F7FE5-639F-4422-A087-8B26CF862D1B}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
@@ -199,8 +177,8 @@ Global
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|Win32.ActiveCfg = Release|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.Release|x64.ActiveCfg = Release|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
@@ -217,8 +195,8 @@ Global
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|Win32.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Release|x64.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
@@ -247,24 +225,6 @@ Global
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Win32.ActiveCfg = Debug|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|x64.ActiveCfg = Debug|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Any CPU.Build.0 = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|Win32.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Release|x64.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU

View File

@@ -10,6 +10,7 @@ using Android.OS;
using Android.Provider;
using Java.IO;
using KeePassLib.Serialization;
using KeePassLib.Utility;
using Console = System.Console;
namespace keepass2android.Io
@@ -77,8 +78,9 @@ namespace keepass2android.Io
public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc)
{
return "";
}
return UrlUtil.StripExtension(
UrlUtil.GetFileName(ioc.Path));
}
public bool RequiresCredentials(IOConnectionInfo ioc)
{

View File

@@ -345,57 +345,7 @@ namespace keepass2android.Io
private class CachedWriteTransaction: IWriteTransaction
{
private class CachedWriteMemoryStream : MemoryStream
{
private readonly IOConnectionInfo ioc;
private readonly CachingFileStorage _cachingFileStorage;
private readonly bool _useFileTransaction;
private bool _closed;
public CachedWriteMemoryStream(IOConnectionInfo ioc, CachingFileStorage cachingFileStorage, bool useFileTransaction)
{
this.ioc = ioc;
_cachingFileStorage = cachingFileStorage;
_useFileTransaction = useFileTransaction;
}
public override void Close()
{
if (_closed) return;
//write file to cache:
//(note: this might overwrite local changes. It's assumed that a sync operation or check was performed before
string hash;
using (var hashingStream = new HashingStreamEx(File.Create(_cachingFileStorage.CachedFilePath(ioc)), true, new SHA256Managed()))
{
Position = 0;
CopyTo(hashingStream);
hashingStream.Close();
hash = MemUtil.ByteArrayToHexString(hashingStream.Hash);
}
File.WriteAllText(_cachingFileStorage.VersionFilePath(ioc), hash);
//update file on remote. This might overwrite changes there as well, see above.
Position = 0;
if (_cachingFileStorage.IsCached(ioc))
{
//if the file already is in the cache, it's ok if writing to remote fails.
_cachingFileStorage.TryUpdateRemoteFile(this, ioc, _useFileTransaction, hash);
}
else
{
//if not, we don't accept a failure (e.g. invalid credentials would always remain a problem)
_cachingFileStorage.UpdateRemoteFile(this, ioc, _useFileTransaction, hash);
}
base.Close();
_closed = true;
}
}
private readonly IOConnectionInfo _ioc;
private readonly bool _useFileTransaction;
@@ -429,17 +379,48 @@ namespace keepass2android.Io
public Stream OpenFile()
{
_memoryStream = new CachedWriteMemoryStream(_ioc, _cachingFileStorage, _useFileTransaction);
_memoryStream = new MemoryStream();
return _memoryStream;
}
public void CommitWrite()
{
//the transaction is committed in the stream's Close
_committed = true;
_memoryStream.Close();
//write file to cache:
//(note: this might overwrite local changes. It's assumed that a sync operation or check was performed before
byte[] output = _memoryStream.ToArray();
string hash;
using (var hashingStream = new HashingStreamEx(File.Create(_cachingFileStorage.CachedFilePath(_ioc)), true, new SHA256Managed()))
{
hashingStream.Write(output, 0, output.Length);
hashingStream.Close();
hash = MemUtil.ByteArrayToHexString(hashingStream.Hash);
}
File.WriteAllText(_cachingFileStorage.VersionFilePath(_ioc), hash);
//create another memory stream which is open for reading again
MemoryStream openMemStream = new MemoryStream(output);
//update file on remote. This might overwrite changes there as well, see above.
if (_cachingFileStorage.IsCached(_ioc))
{
//if the file already is in the cache, it's ok if writing to remote fails.
_cachingFileStorage.TryUpdateRemoteFile(openMemStream, _ioc, _useFileTransaction, hash);
}
else
{
//if not, we don't accept a failure (e.g. invalid credentials would always remain a problem)
_cachingFileStorage.UpdateRemoteFile(openMemStream, _ioc, _useFileTransaction, hash);
}
openMemStream.Dispose();
}
}
}
public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction)

View File

@@ -31,7 +31,7 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<DefineConstants>TRACE;NoNet;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
@@ -53,7 +53,6 @@
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
<Reference Include="Xamarin.Android.Arch.Core.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
@@ -106,20 +105,12 @@
<Compile Include="Io\AndroidContentStorage.cs" />
<Compile Include="Io\BuiltInFileStorage.cs" />
<Compile Include="Io\CachingFileStorage.cs" />
<Compile Include="Io\DropboxFileStorage.cs" />
<Compile Include="Io\DropboxFileStorageKeys.cs" />
<Compile Include="Io\FileDescription.cs" />
<Compile Include="Io\FileStorageSetupActivity.cs" />
<Compile Include="Io\FileStorageSetupInitiatorActivity.cs" />
<Compile Include="Io\GDriveFileStorage.cs" />
<Compile Include="Io\IFileStorage.cs" />
<Compile Include="Io\IoUtil.cs" />
<Compile Include="Io\JavaFileStorage.cs" />
<Compile Include="Io\NetFtpFileStorage.cs" />
<Compile Include="Io\OfflineSwitchableFileStorage.cs" />
<Compile Include="Io\SftpFileStorage.cs" />
<Compile Include="Io\OneDriveFileStorage.cs" />
<Compile Include="Io\WebDavFileStorage.cs" />
<Compile Include="IProgressDialog.cs" />
<Compile Include="PreferenceKey.cs" />
<Compile Include="SelectStorageLocationActivityBase.cs" />
@@ -155,10 +146,6 @@
<Compile Include="Utils\Spr\SprEngine.PickChars.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\JavaFileStorageBindings\JavaFileStorageBindings.csproj">
<Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project>
<Name>JavaFileStorageBindings</Name>
</ProjectReference>
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
<Name>KeePassLib2Android</Name>
@@ -167,10 +154,6 @@
<Project>{70D3844A-D9FA-4A64-B205-A84C6A822196}</Project>
<Name>KP2AKdbLibraryBinding</Name>
</ProjectReference>
<ProjectReference Include="..\netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj">
<Project>{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}</Project>
<Name>System.Net.FtpClient.Android</Name>
</ProjectReference>
<ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj">
<Project>{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}</Project>
<Name>TwofishCipher</Name>

View File

@@ -30,8 +30,12 @@ namespace keepass2android
readonly IKp2aApp _app;
private readonly Handler _handler;
private string _message = "";
private string _submessage;
public ProgressDialogStatusLogger() {
public String SubMessage => _submessage;
public String Message => _message;
public ProgressDialogStatusLogger() {
}
@@ -56,6 +60,7 @@ namespace keepass2android
public void UpdateSubMessage(String submessage)
{
_submessage = submessage;
if (_app != null && _progressDialog != null && _handler != null)
{
_handler.Post(() =>

View File

@@ -25,39 +25,107 @@ namespace keepass2android
/// <summary>
/// Class to run a task while a progress dialog is shown
/// </summary>
public class ProgressTask {
private readonly Handler _handler;
public class ProgressTask
{
//for handling Activity recreation situations, we need access to the currently active task. It must hold that there is no more than one active task.
private static ProgressTask _currentTask = null;
public static void SetNewActiveActivity(Activity activeActivity)
{
if (_currentTask != null)
{
_currentTask.ActiveActivity = activeActivity;
}
}
public static void RemoveActiveActivity(Activity activity)
{
if ((_currentTask != null) && (_currentTask._activeActivity == activity))
_currentTask.ActiveActivity = null;
}
public Activity ActiveActivity
{
get { return _activeActivity; }
private set
{
_activeActivity = value;
if (_task != null)
_task.ActiveActivity = _activeActivity;
if (_activeActivity != null)
{
SetupProgressDialog(_app);
_progressDialog.Show();
}
}
}
private readonly Handler _handler;
private readonly RunnableOnFinish _task;
private readonly IProgressDialog _progressDialog;
private IProgressDialog _progressDialog;
private readonly IKp2aApp _app;
private Thread _thread;
private Activity _activeActivity;
private ProgressDialogStatusLogger _progressDialogStatusLogger;
public ProgressTask(IKp2aApp app, Context ctx, RunnableOnFinish task) {
public ProgressTask(IKp2aApp app, Activity activity, RunnableOnFinish task)
{
_activeActivity = activity;
_task = task;
_handler = app.UiThreadHandler;
_app = app;
// Show process dialog
_progressDialog = app.CreateProgressDialog(ctx);
_progressDialog.SetTitle(_app.GetResourceString(UiStringKey.progress_title));
_progressDialog.SetMessage("Initializing...");
// Set code to run when this is finished
_task.OnFinishToRun = new AfterTask(task.OnFinishToRun, _handler, _progressDialog);
_task.SetStatusLogger(new ProgressDialogStatusLogger(_app, _handler, _progressDialog));
SetupProgressDialog(app);
// Set code to run when this is finished
_task.OnFinishToRun = new AfterTask(activity, task.OnFinishToRun, _handler, this);
_task.SetStatusLogger(_progressDialogStatusLogger);
}
public void Run() {
// Show process dialog
_progressDialog.Show();
private void SetupProgressDialog(IKp2aApp app)
{
string currentMessage = "Initializing...";
string currentSubmessage = "";
if (_progressDialogStatusLogger != null)
{
currentMessage = _progressDialogStatusLogger.Message;
currentSubmessage = _progressDialogStatusLogger.SubMessage;
}
if (_progressDialog != null)
{
var pd = _progressDialog;
app.UiThreadHandler.Post(() =>
{
pd.Dismiss();
});
}
// Show process dialog
_progressDialog = app.CreateProgressDialog(_activeActivity);
_progressDialog.SetTitle(_app.GetResourceString(UiStringKey.progress_title));
_progressDialogStatusLogger = new ProgressDialogStatusLogger(_app, _handler, _progressDialog);
_progressDialogStatusLogger.UpdateMessage(currentMessage);
_progressDialogStatusLogger.UpdateSubMessage(currentSubmessage);
}
public void Run(bool allowOverwriteCurrentTask = false)
{
if ((!allowOverwriteCurrentTask) && (_currentTask != null))
throw new Exception("Cannot start another ProgressTask while ProgressTask is already running! " + _task.GetType().Name + "/" + _currentTask._task.GetType().Name);
_currentTask = this;
// Show process dialog
_progressDialog.Show();
// Start Thread to Run task
_thread = new Thread(_task.Run);
_thread.Start();
}
public void JoinWorkerThread()
@@ -66,11 +134,11 @@ namespace keepass2android
}
private class AfterTask : OnFinish {
readonly IProgressDialog _progressDialog;
readonly ProgressTask _progressTask;
public AfterTask (OnFinish finish, Handler handler, IProgressDialog pd): base(finish, handler)
public AfterTask (Activity activity, OnFinish finish, Handler handler, ProgressTask pt): base(activity, finish, handler)
{
_progressDialog = pd;
_progressTask = pt;
}
public override void Run() {
@@ -79,17 +147,22 @@ namespace keepass2android
if (Handler != null) //can be null in tests
{
// Remove the progress dialog
Handler.Post(delegate { _progressDialog.Dismiss(); });
Handler.Post(delegate
{
_progressTask._progressDialog.Dismiss();
});
}
else
{
_progressDialog.Dismiss();
_progressTask._progressDialog.Dismiss();
}
_currentTask = null;
}
}
}
}

View File

@@ -18,8 +18,8 @@ namespace keepass2android
private readonly IKp2aApp _app;
public CheckDatabaseForChanges(Context context, IKp2aApp app, OnFinish finish)
: base(finish)
public CheckDatabaseForChanges(Activity context, IKp2aApp app, OnFinish finish)
: base(context, finish)
{
_context = context;
_app = app;

View File

@@ -21,7 +21,6 @@ using System.IO;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Text;
using Android.Content;
using Java.Lang;
using KeePassLib;
using KeePassLib.Keys;
@@ -218,7 +217,7 @@ namespace keepass2android
}
public void SaveData(Context ctx) {
public void SaveData() {
KpDatabase.UseFileTransactions = _app.GetBooleanPreference(PreferenceKey.UseFileTransactions);
using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, KpDatabase.UseFileTransactions))

View File

@@ -11,12 +11,12 @@ namespace keepass2android
{
public class SynchronizeCachedDatabase: RunnableOnFinish
{
private readonly Context _context;
private readonly Activity _context;
private readonly IKp2aApp _app;
private SaveDb _saveDb;
public SynchronizeCachedDatabase(Context context, IKp2aApp app, OnFinish finish)
: base(finish)
public SynchronizeCachedDatabase(Activity context, IKp2aApp app, OnFinish finish)
: base(context, finish)
{
_context = context;
_app = app;
@@ -59,7 +59,7 @@ namespace keepass2android
if (cachingFileStorage.HasLocalChanges(ioc))
{
//conflict! need to merge
_saveDb = new SaveDb(_context, _app, new ActionOnFinish((success, result) =>
_saveDb = new SaveDb(_context, _app, new ActionOnFinish(ActiveActivity, (success, result, activity) =>
{
if (!success)
{

View File

@@ -16,41 +16,37 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
*/
using System;
using Android.App;
using Android.OS;
namespace keepass2android
{
public class ActionOnFinish: OnFinish
{
public delegate void ActionToPerformOnFinsh(bool success, String message);
public delegate void ActionToPerformOnFinsh(bool success, String message, Activity activeActivity);
readonly ActionToPerformOnFinsh _actionToPerform;
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform) : base(null, null)
public ActionOnFinish(Activity activity, ActionToPerformOnFinsh actionToPerform) : base(activity, null, null)
{
_actionToPerform = actionToPerform;
}
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, OnFinish finish) : base(finish)
public ActionOnFinish(Activity activity, ActionToPerformOnFinsh actionToPerform, OnFinish finish) : base(activity, finish)
{
_actionToPerform = actionToPerform;
}
public ActionOnFinish(ActionToPerformOnFinsh actionToPerform, Handler handler) : base(handler)
{
_actionToPerform = actionToPerform;
}
public override void Run()
{
if (Message == null)
Message = "";
if (Handler != null)
{
Handler.Post(() => {_actionToPerform(Success, Message);});
Handler.Post(() => {_actionToPerform(Success, Message, ActiveActivity);});
}
else
_actionToPerform(Success, Message);
_actionToPerform(Success, Message, ActiveActivity);
base.Run();
}
}

View File

@@ -15,6 +15,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using Android.App;
using Android.Content;
using KeePassLib;
@@ -29,20 +30,20 @@ namespace keepass2android
private readonly IKp2aApp _app;
private readonly PwEntry _entry;
private readonly PwGroup _parentGroup;
private readonly Context _ctx;
private readonly Activity _ctx;
public static AddEntry GetInstance(Context ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish) {
public static AddEntry GetInstance(Activity ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish) {
return new AddEntry(ctx, app, entry, parentGroup, finish);
}
protected AddEntry(Context ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(finish) {
protected AddEntry(Activity ctx, IKp2aApp app, PwEntry entry, PwGroup parentGroup, OnFinish finish):base(ctx, finish) {
_ctx = ctx;
_parentGroup = parentGroup;
_app = app;
_entry = entry;
_onFinishToRun = new AfterAdd(app.GetDb(), entry, OnFinishToRun);
_onFinishToRun = new AfterAdd(ctx, app.GetDb(), entry, OnFinishToRun);
}
@@ -68,7 +69,7 @@ namespace keepass2android
private readonly Database _db;
private readonly PwEntry _entry;
public AfterAdd(Database db, PwEntry entry, OnFinish finish):base(finish) {
public AfterAdd(Activity activity, Database db, PwEntry entry, OnFinish finish):base(activity, finish) {
_db = db;
_entry = entry;

View File

@@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using Android.App;
using Android.Content;
using KeePassLib;
@@ -34,16 +35,16 @@ namespace keepass2android
internal PwGroup Group;
internal PwGroup Parent;
protected bool DontSave;
readonly Context _ctx;
readonly Activity _ctx;
public static AddGroup GetInstance(Context ctx, IKp2aApp app, string name, int iconid, PwUuid groupCustomIconId, PwGroup parent, OnFinish finish, bool dontSave) {
public static AddGroup GetInstance(Activity ctx, IKp2aApp app, string name, int iconid, PwUuid groupCustomIconId, PwGroup parent, OnFinish finish, bool dontSave) {
return new AddGroup(ctx, app, name, iconid, groupCustomIconId, parent, finish, dontSave);
}
private AddGroup(Context ctx, IKp2aApp app, String name, int iconid, PwUuid groupCustomIconId, PwGroup parent, OnFinish finish, bool dontSave)
: base(finish)
private AddGroup(Activity ctx, IKp2aApp app, String name, int iconid, PwUuid groupCustomIconId, PwGroup parent, OnFinish finish, bool dontSave)
: base(ctx, finish)
{
_ctx = ctx;
_name = name;
@@ -53,7 +54,7 @@ namespace keepass2android
DontSave = dontSave;
_app = app;
_onFinishToRun = new AfterAdd(this, OnFinishToRun);
_onFinishToRun = new AfterAdd(ctx, this, OnFinishToRun);
}
@@ -76,7 +77,7 @@ namespace keepass2android
private class AfterAdd : OnFinish {
readonly AddGroup _addGroup;
public AfterAdd(AddGroup addGroup,OnFinish finish): base(finish) {
public AfterAdd(Activity activity, AddGroup addGroup,OnFinish finish): base(activity, finish) {
_addGroup = addGroup;
}

View File

@@ -18,6 +18,7 @@ This file is part of Keepass2Android, Copyright 2016 Philipp Crocoll. This file
using System;
using System.Collections.Generic;
using System.Linq;
using Android.App;
using Android.Content;
using KeePassLib;
using KeePassLib.Security;
@@ -128,10 +129,10 @@ namespace keepass2android
}
private readonly IKp2aApp _app;
private readonly Context _ctx;
private readonly Activity _ctx;
public AddTemplateEntries(Context ctx, IKp2aApp app, OnFinish finish)
: base(finish)
public AddTemplateEntries(Activity ctx, IKp2aApp app, OnFinish finish)
: base(ctx, finish)
{
_ctx = ctx;
_app = app;
@@ -358,7 +359,7 @@ namespace keepass2android
private readonly Database _db;
private readonly List<PwEntry> _entries;
public AfterAdd(Database db, List<PwEntry> entries, OnFinish finish):base(finish) {
public AfterAdd(Activity activity, Database db, List<PwEntry> entries, OnFinish finish):base(activity, finish) {
_db = db;
_entries = entries;

View File

@@ -16,7 +16,7 @@ namespace keepass2android.database.edit
{
public class CopyEntry: AddEntry
{
public CopyEntry(Context ctx, IKp2aApp app, PwEntry entry, OnFinish finish)
public CopyEntry(Activity ctx, IKp2aApp app, PwEntry entry, OnFinish finish)
: base(ctx, app, CreateCopy(entry, app), entry.ParentGroup, finish)
{
}

View File

@@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System.Collections.Generic;
using Android.App;
using Android.Content;
using KeePassLib;
using KeePassLib.Cryptography.KeyDerivation;
@@ -31,19 +32,19 @@ namespace keepass2android
private readonly IOConnectionInfo _ioc;
private readonly bool _dontSave;
private readonly Context _ctx;
private readonly Activity _ctx;
private readonly IKp2aApp _app;
private CompositeKey _key;
public CreateDb(IKp2aApp app, Context ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(finish) {
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave): base(ctx, finish) {
_ctx = ctx;
_ioc = ioc;
_dontSave = dontSave;
_app = app;
}
public CreateDb(IKp2aApp app, Context ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave, CompositeKey key)
: base(finish)
public CreateDb(IKp2aApp app, Activity ctx, IOConnectionInfo ioc, OnFinish finish, bool dontSave, CompositeKey key)
: base(ctx, finish)
{
_ctx = ctx;
_ioc = ioc;

View File

@@ -17,6 +17,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using KeePassLib;
using KeePassLib.Interfaces;
@@ -28,8 +29,8 @@ namespace keepass2android
private readonly PwEntry _entry;
private UiStringKey _statusMessage;
public DeleteEntry(Context ctx, IKp2aApp app, PwEntry entry, OnFinish finish):base(finish, app) {
Ctx = ctx;
public DeleteEntry(Activity activiy, IKp2aApp app, PwEntry entry, OnFinish finish):base(activiy, finish, app) {
Ctx = activiy;
Db = app.GetDb();
_entry = entry;

View File

@@ -17,6 +17,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using KeePassLib;
@@ -28,10 +29,10 @@ namespace keepass2android
private PwGroup _group;
protected bool DontSave;
public DeleteGroup(Context ctx, IKp2aApp app, PwGroup group, OnFinish finish)
: base(finish, app)
public DeleteGroup(Activity activity, IKp2aApp app, PwGroup group, OnFinish finish)
: base(activity, finish, app)
{
SetMembers(ctx, app, group, false);
SetMembers(activity, app, group, false);
}
/*
public DeleteGroup(Context ctx, Database db, PwGroup group, Activity act, OnFinish finish, bool dontSave)
@@ -44,9 +45,9 @@ namespace keepass2android
SetMembers(ctx, db, group, null, dontSave);
}
*/
private void SetMembers(Context ctx, IKp2aApp app, PwGroup group, bool dontSave)
private void SetMembers(Activity activity, IKp2aApp app, PwGroup group, bool dontSave)
{
base.SetMembers(ctx, app.GetDb());
base.SetMembers(activity, app.GetDb());
_group = group;
DontSave = dontSave;

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Android.App;
using Android.Content;
using KeePassLib;
using KeePassLib.Interfaces;
@@ -11,11 +12,11 @@ namespace keepass2android
private readonly List<IStructureItem> _elementsToDelete;
private readonly bool _canRecycle;
public DeleteMultipleItems(Context ctx, Database db, List<IStructureItem> elementsToDelete, OnFinish finish, IKp2aApp app)
: base(finish, app)
public DeleteMultipleItems(Activity activity, Database db, List<IStructureItem> elementsToDelete, OnFinish finish, IKp2aApp app)
: base(activity, finish, app)
{
_elementsToDelete = elementsToDelete;
SetMembers(ctx, db);
SetMembers(activity, db);
//determine once. The property is queried for each delete operation, but might return false
//after one entry/group is deleted (and thus in recycle bin and thus can't be recycled anymore)

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using KeePassLib;
@@ -7,8 +8,8 @@ namespace keepass2android
{
public abstract class DeleteRunnable : RunnableOnFinish
{
protected DeleteRunnable(OnFinish finish, IKp2aApp app)
: base(finish)
protected DeleteRunnable(Activity activity, OnFinish finish, IKp2aApp app)
: base(activity, finish)
{
App = app;
}
@@ -17,11 +18,11 @@ namespace keepass2android
protected Database Db;
protected Context Ctx;
protected Activity Ctx;
protected void SetMembers(Context ctx, Database db)
protected void SetMembers(Activity activity, Database db)
{
Ctx = ctx;
Ctx = activity;
Db = db;
}
@@ -209,7 +210,7 @@ namespace keepass2android
Android.Util.Log.Debug("KP2A", "Calling PerformDelete..");
PerformDelete(touchedGroups, permanentlyDeletedGroups);
_onFinishToRun = new ActionOnFinish((success, message) =>
_onFinishToRun = new ActionOnFinish(ActiveActivity,(success, message, activity) =>
{
if (success)
{

View File

@@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using Android.App;
using Android.Content;
using KeePassLib;
@@ -32,10 +33,10 @@ namespace keepass2android
private readonly PwIcon _iconId;
private readonly PwUuid _customIconId;
internal PwGroup Group;
readonly Context _ctx;
readonly Activity _ctx;
public EditGroup(Context ctx, IKp2aApp app, String name, PwIcon iconid, PwUuid customIconId, PwGroup group, OnFinish finish)
: base(finish)
public EditGroup(Activity ctx, IKp2aApp app, String name, PwIcon iconid, PwUuid customIconId, PwGroup group, OnFinish finish)
: base(ctx, finish)
{
_ctx = ctx;
_name = name;
@@ -44,7 +45,7 @@ namespace keepass2android
_customIconId = customIconId;
_app = app;
_onFinishToRun = new AfterEdit(this, OnFinishToRun);
_onFinishToRun = new AfterEdit(ctx, this, OnFinishToRun);
}
@@ -64,8 +65,8 @@ namespace keepass2android
private class AfterEdit : OnFinish {
readonly EditGroup _editGroup;
public AfterEdit(EditGroup editGroup, OnFinish finish)
: base(finish)
public AfterEdit(Activity ctx, EditGroup editGroup, OnFinish finish)
: base(ctx, finish)
{
_editGroup = editGroup;
}

View File

@@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using Android.App;
namespace keepass2android
{
@@ -23,7 +24,7 @@ namespace keepass2android
public abstract class FileOnFinish : OnFinish {
private String _filename = "";
protected FileOnFinish(FileOnFinish finish):base(finish) {
protected FileOnFinish(Activity activity, FileOnFinish finish):base(activity, finish) {
}
public string Filename

View File

@@ -20,6 +20,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Android.App;
using KeePassLib;
using KeePassLib.Keys;
using KeePassLib.Serialization;
@@ -35,7 +36,7 @@ namespace keepass2android
private readonly bool _rememberKeyfile;
IDatabaseFormat _format;
public LoadDb(IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, String keyfileOrProvider, OnFinish finish): base(finish)
public LoadDb(Activity activity, IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, String keyfileOrProvider, OnFinish finish): base(activity, finish)
{
_app = app;
_ioc = ioc;

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Android.App;
using Android.Content;
using KeePassLib;
using KeePassLib.Interfaces;
@@ -12,10 +13,10 @@ namespace keepass2android.database.edit
{
private readonly List<IStructureItem> _elementsToMove;
private readonly PwGroup _targetGroup;
private readonly Context _ctx;
private readonly Activity _ctx;
private readonly IKp2aApp _app;
public MoveElements(List<IStructureItem> elementsToMove, PwGroup targetGroup, Context ctx, IKp2aApp app, OnFinish finish) : base(finish)
public MoveElements(List<IStructureItem> elementsToMove, PwGroup targetGroup, Activity ctx, IKp2aApp app, OnFinish finish) : base(ctx, finish)
{
_elementsToMove = elementsToMove;
_targetGroup = targetGroup;
@@ -82,7 +83,7 @@ namespace keepass2android.database.edit
}
_onFinishToRun = new ActionOnFinish((success, message) =>
_onFinishToRun = new ActionOnFinish(ActiveActivity, (success, message, activity) =>
{
if (!success)
{ // Let's not bother recovering from a failure.

View File

@@ -16,6 +16,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
*/
using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
@@ -31,27 +32,47 @@ namespace keepass2android
protected OnFinish BaseOnFinish;
protected Handler Handler;
private ProgressDialogStatusLogger _statusLogger = new ProgressDialogStatusLogger(); //default: no logging but not null -> can be used whenever desired
private Activity _activeActivity;
public ProgressDialogStatusLogger StatusLogger
public ProgressDialogStatusLogger StatusLogger
{
get { return _statusLogger; }
set { _statusLogger = value; }
}
public Activity ActiveActivity
{
get { return _activeActivity; }
set
{
_activeActivity = value;
if (BaseOnFinish != null)
{
BaseOnFinish.ActiveActivity = value;
}
}
}
protected OnFinish(Handler handler) {
protected OnFinish(Activity activeActivity, Handler handler)
{
ActiveActivity = activeActivity;
BaseOnFinish = null;
Handler = handler;
}
protected OnFinish(OnFinish finish, Handler handler) {
protected OnFinish(Activity activeActivity, OnFinish finish, Handler handler)
{
ActiveActivity = activeActivity;
BaseOnFinish = finish;
Handler = handler;
}
protected OnFinish(OnFinish finish) {
protected OnFinish(Activity activeActivity, OnFinish finish)
{
ActiveActivity = activeActivity;
BaseOnFinish = finish;
Handler = null;
}
@@ -86,7 +107,7 @@ namespace keepass2android
{
if ( !String.IsNullOrEmpty(message) ) {
Kp2aLog.Log("OnFinish message: "+message);
Toast.MakeText(ctx, message, ToastLength.Long).Show();
Toast.MakeText(ctx ?? Application.Context, message, ToastLength.Long).Show();
}
}
}

View File

@@ -15,6 +15,8 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using Android.App;
using Android.Content;
namespace keepass2android
{
@@ -23,8 +25,11 @@ namespace keepass2android
protected OnFinish _onFinishToRun;
public ProgressDialogStatusLogger StatusLogger = new ProgressDialogStatusLogger(); //default: empty but not null
private Activity _activeActivity;
protected RunnableOnFinish(OnFinish finish) {
protected RunnableOnFinish(Activity activeActivity, OnFinish finish)
{
_activeActivity = activeActivity;
_onFinishToRun = finish;
}
@@ -34,7 +39,18 @@ namespace keepass2android
set { _onFinishToRun = value; }
}
protected void Finish(bool result, String message, Exception exception = null) {
public Activity ActiveActivity
{
get { return _activeActivity; }
set
{
_activeActivity = value;
if (_onFinishToRun != null)
_onFinishToRun.ActiveActivity = _activeActivity;
}
}
protected void Finish(bool result, String message, Exception exception = null) {
if ( OnFinishToRun != null ) {
OnFinishToRun.SetResult(result, message, exception);
OnFinishToRun.Run();
@@ -56,7 +72,7 @@ namespace keepass2android
StatusLogger = status;
}
abstract public void Run();
public abstract void Run();
}
}

View File

@@ -18,6 +18,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
using System;
using System.IO;
using System.Security.Cryptography;
using Android.App;
using Android.Content;
using Android.OS;
using Java.Lang;
@@ -42,8 +43,8 @@ namespace keepass2android
private readonly Context _ctx;
private Thread _workerThread;
public SaveDb(Context ctx, IKp2aApp app, OnFinish finish, bool dontSave)
: base(finish)
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish, bool dontSave)
: base(ctx, finish)
{
_ctx = ctx;
_app = app;
@@ -58,8 +59,8 @@ namespace keepass2android
/// <param name="finish"></param>
/// <param name="dontSave"></param>
/// <param name="streamForOrigFile">Stream for reading the data from the (changed) original location</param>
public SaveDb(Context ctx, IKp2aApp app, OnFinish finish, bool dontSave, Stream streamForOrigFile)
: base(finish)
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish, bool dontSave, Stream streamForOrigFile)
: base(ctx, finish)
{
_ctx = ctx;
_app = app;
@@ -67,8 +68,8 @@ namespace keepass2android
_streamForOrigFile = streamForOrigFile;
}
public SaveDb(Context ctx, IKp2aApp app, OnFinish finish)
: base(finish)
public SaveDb(Activity ctx, IKp2aApp app, OnFinish finish)
: base(ctx, finish)
{
_ctx = ctx;
_app = app;
@@ -248,7 +249,7 @@ namespace keepass2android
private void PerformSaveWithoutCheck(IFileStorage fileStorage, IOConnectionInfo ioc)
{
StatusLogger.UpdateSubMessage("");
_app.GetDb().SaveData(_ctx);
_app.GetDb().SaveData();
_app.GetDb().LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
}

View File

@@ -15,6 +15,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using Android.App;
using Android.Content;
using KeePassLib;
using KeePassLib.Keys;
@@ -27,9 +28,9 @@ namespace keepass2android
private readonly String _keyfile;
private readonly IKp2aApp _app;
private readonly bool _dontSave;
private readonly Context _ctx;
private readonly Activity _ctx;
public SetPassword(Context ctx, IKp2aApp app, String password, String keyfile, OnFinish finish): base(finish) {
public SetPassword(Activity ctx, IKp2aApp app, String password, String keyfile, OnFinish finish): base(ctx, finish) {
_ctx = ctx;
_app = app;
_password = password;
@@ -37,8 +38,8 @@ namespace keepass2android
_dontSave = false;
}
public SetPassword(Context ctx, IKp2aApp app, String password, String keyfile, OnFinish finish, bool dontSave)
: base(finish)
public SetPassword(Activity ctx, IKp2aApp app, String password, String keyfile, OnFinish finish, bool dontSave)
: base(ctx, finish)
{
_ctx = ctx;
_app = app;
@@ -72,7 +73,7 @@ namespace keepass2android
pm.MasterKey = newKey;
// Save Database
_onFinishToRun = new AfterSave(previousKey, previousMasterKeyChanged, pm, OnFinishToRun);
_onFinishToRun = new AfterSave(ActiveActivity, previousKey, previousMasterKeyChanged, pm, OnFinishToRun);
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun, _dontSave);
save.SetStatusLogger(StatusLogger);
save.Run();
@@ -83,7 +84,7 @@ namespace keepass2android
private readonly DateTime _previousKeyChanged;
private readonly PwDatabase _db;
public AfterSave(CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(finish) {
public AfterSave(Activity activity, CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(activity, finish) {
_previousKeyChanged = previousKeyChanged;
_backup = backup;
_db = db;

View File

@@ -15,6 +15,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/
using Android.App;
using Android.Content;
using KeePassLib;
@@ -23,13 +24,13 @@ namespace keepass2android
public class UpdateEntry : RunnableOnFinish {
private readonly IKp2aApp _app;
private readonly Context _ctx;
private readonly Activity _ctx;
public UpdateEntry(Context ctx, IKp2aApp app, PwEntry oldE, PwEntry newE, OnFinish finish):base(finish) {
public UpdateEntry(Activity ctx, IKp2aApp app, PwEntry oldE, PwEntry newE, OnFinish finish):base(ctx, finish) {
_ctx = ctx;
_app = app;
_onFinishToRun = new AfterUpdate(oldE, newE, app, finish);
_onFinishToRun = new AfterUpdate(ctx, oldE, newE, app, finish);
}
@@ -45,7 +46,7 @@ namespace keepass2android
private readonly PwEntry _updatedEntry;
private readonly IKp2aApp _app;
public AfterUpdate(PwEntry backup, PwEntry updatedEntry, IKp2aApp app, OnFinish finish):base(finish) {
public AfterUpdate(Activity activity, PwEntry backup, PwEntry updatedEntry, IKp2aApp app, OnFinish finish):base(activity, finish) {
_backup = backup;
_updatedEntry = updatedEntry;
_app = app;

View File

@@ -63,8 +63,6 @@
<TransformFile Include="Transforms\EnumMethods.xml" />
<TransformFile Include="Transforms\Metadata.xml" />
</ItemGroup>
<ItemGroup>
<Folder Include="libs\" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildExtensionsPath)\Novell\Xamarin.Android.Bindings.targets" />
</Project>

View File

@@ -6,11 +6,11 @@ if exist "DropboxFileStorageKeys.cs" (
)
cd ..\..\keepass2android
call UseManifestDebug.bat
call UseManifestNoNet.bat
cd ..
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
msbuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Debug" /p:Platform="Any CPU"
msbuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Release" /p:Platform="Any CPU"
cd build-scripts

View File

@@ -312,6 +312,8 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase {
String driveId = path.getGDriveId();
logDebug("id"+driveId);
File file = driveService.files().get(driveId).execute();
if (file.getLabels().getTrashed())
throw new FileNotFoundException(path.getDisplayName() + " is trashed!");
logDebug("...done.");
return file;
}

View File

@@ -322,6 +322,9 @@ public class SftpStorage extends JavaFileStorageBase {
UserInfo ui = new SftpUserInfo(ci.password);
session.setUserInfo(ui);
session.setConfig("PreferredAuthentications",
"password,publickey");
session.connect();
Channel channel = session.openChannel("sftp");

View File

@@ -46,7 +46,8 @@
android:inputType="textPassword"
android:singleLine="true"
android:text=""
android:hint="@string/hint_pass" />
android:hint="@string/hint_pass"
android:importantForAccessibility="no" />
<TextView android:id="@+id/initial_dir"
android:layout_width="wrap_content"

View File

@@ -33,6 +33,7 @@
android:inputType="textPassword"
android:singleLine="true"
android:text="$T3st17$"
android:hint="@string/hint_pass" />
android:hint="@string/hint_pass"
android:importantForAccessibility="no" />
</LinearLayout>

View File

@@ -18,5 +18,9 @@
android:name="android.accessibilityservice"
android:resource="@xml/accserviceconfig" />
</service-->
<activity android:excludeFromRecents="true"
android:taskAffinity=""
android:theme="@android:style/Theme.Dialog"
android:name=".Kp2aDialog"></activity>
</application>
</manifest>

View File

@@ -10,20 +10,18 @@ public class KeyboardData
public static List<StringForTyping> availableFields = new ArrayList<StringForTyping>();
public static String entryName;
public static String entryId;
public static int kp2aFieldIndex = 0;
public static boolean hasData()
{
return !TextUtils.isEmpty(entryId);
}
public static boolean bla2()
{
return !TextUtils.isEmpty(entryId);
}
public static void clear()
{
availableFields.clear();
entryName = entryId = "";
kp2aFieldIndex = 0;
}
}

View File

@@ -1,6 +1,10 @@
package keepass2android.kbbridge;
import java.util.ArrayList;
import java.util.HashMap;
import keepass2android.softkeyboard.IKeyboardService;
import keepass2android.softkeyboard.KP2AKeyboard;
public class KeyboardDataBuilder {
private ArrayList<StringForTyping> availableFields = new ArrayList<StringForTyping>();
@@ -16,5 +20,8 @@ public class KeyboardDataBuilder {
public void commit()
{
KeyboardData.availableFields = this.availableFields;
KeyboardData.kp2aFieldIndex = 0;
if (KP2AKeyboard.CurrentlyRunningService != null)
KP2AKeyboard.CurrentlyRunningService.onNewData();
}
}

View File

@@ -0,0 +1,9 @@
package keepass2android.softkeyboard;
import keepass2android.kbbridge.StringForTyping;
public interface IKeyboardService
{
void commitStringForTyping(StringForTyping stringForTyping);
void onNewData();
}

View File

@@ -17,6 +17,7 @@
package keepass2android.softkeyboard;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
@@ -27,21 +28,26 @@ import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.BitmapDrawable;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.Keyboard;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Debug;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.text.ClipboardManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.View;
@@ -54,7 +60,9 @@ import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import keepass2android.kbbridge.KeyboardData;
import keepass2android.kbbridge.StringForTyping;
import keepass2android.softkeyboard.LatinIMEUtil.RingCharBuffer;
@@ -64,18 +72,24 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
/**
* Input method implementation for Qwerty'ish keyboard.
*/
public class KP2AKeyboard extends InputMethodService
implements LatinKeyboardBaseView.OnKeyboardActionListener,
IKeyboardService,
SharedPreferences.OnSharedPreferenceChangeListener {
public static IKeyboardService CurrentlyRunningService;
private static String get_KEEPASS2ANDROID_KEYBOARD_CLEARED(Context ctx)
{
return ctx.getPackageName()+".keyboard_cleared";
@@ -311,6 +325,7 @@ public class KP2AKeyboard extends InputMethodService
@Override
public void onCreate() {
CurrentlyRunningService = this;
LatinImeLogger.init(this);
KeyboardSwitcher.init(this);
super.onCreate();
@@ -330,6 +345,8 @@ public class KP2AKeyboard extends InputMethodService
}
mReCorrectionEnabled = prefs.getBoolean(PREF_RECORRECTION_ENABLED,
getResources().getBoolean(R.bool.default_recorrection_enabled));
Log.d("KP2AK","finding plugin dicts...");
PluginManager.getPluginDictionaries(getApplicationContext());
@@ -358,7 +375,7 @@ public class KP2AKeyboard extends InputMethodService
// register to receive ringer mode changes for silent mode
IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
registerReceiver(mReceiver, filter);
registerReceiver(mSilentModeReceiver, filter);
prefs.registerOnSharedPreferenceChangeListener(this);
@@ -467,12 +484,14 @@ public class KP2AKeyboard extends InputMethodService
if (mContactsDictionary != null) {
mContactsDictionary.close();
}*/
unregisterReceiver(mReceiver);
unregisterReceiver(mSilentModeReceiver);
unregisterReceiver(mPluginManager);
unregisterReceiver(mClearKeyboardReceiver);
LatinImeLogger.commit();
LatinImeLogger.onDestroy();
CurrentlyRunningService = null;
super.onDestroy();
}
@@ -502,6 +521,7 @@ public class KP2AKeyboard extends InputMethodService
mOrientation = conf.orientation;
reloadKeyboards();
}
updateKp2aKeyLabels();
mConfigurationChanging = true;
super.onConfigurationChanged(conf);
mConfigurationChanging = false;
@@ -526,6 +546,7 @@ public class KP2AKeyboard extends InputMethodService
mKeyboardSwitcher.setKeyboardMode(
KeyboardSwitcher.MODE_TEXT, 0);
}
updateKp2aKeyLabels();
return mKeyboardSwitcher.getInputView();
}
@@ -687,6 +708,7 @@ public class KP2AKeyboard extends InputMethodService
attribute.imeOptions);
}
}
updateKp2aKeyLabels();
}
private void updateShowKp2aMode() {
@@ -1065,6 +1087,7 @@ public class KP2AKeyboard extends InputMethodService
private void reloadKeyboards() {
mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher);
mKeyboardSwitcher.makeKeyboards(true);
updateKp2aKeyLabels();
}
private void commitTyped(InputConnection inputConnection) {
@@ -1254,6 +1277,9 @@ public class KP2AKeyboard extends InputMethodService
case LatinKeyboardView.KEYCODE_OPTIONS:
onOptionKeyPressed();
break;
case LatinKeyboardView.KEYCODE_KP2A_NEXTFIELDS:
onKp2aNextFieldsPressed();
break;
case LatinKeyboardView.KEYCODE_KP2A:
onKp2aKeyPressed();
break;
@@ -1342,28 +1368,95 @@ public class KP2AKeyboard extends InputMethodService
}
private void onKp2aPasswordKeyPressed() {
commitStringForTyping(findStringForTyping("Password"));
commitStringForTyping(KeyboardData.availableFields.get(KeyboardData.kp2aFieldIndex+1));
}
private StringForTyping findStringForTyping(String key) {
for (StringForTyping s: keepass2android.kbbridge.KeyboardData.availableFields)
{
if (key.equals(s.key))
{
return s;
}
}
//found nothing: return empty struct:
return new StringForTyping();
}
private void onKp2aUserKeyPressed() {
commitStringForTyping(findStringForTyping("UserName"));
commitStringForTyping(KeyboardData.availableFields.get(KeyboardData.kp2aFieldIndex));
}
private void onKp2aKeyPressed() {
private void onKp2aNextFieldsPressed()
{
List<StringForTyping> availableFields = keepass2android.kbbridge.KeyboardData.availableFields;
if (KeyboardData.kp2aFieldIndex >= availableFields.size()-2)
{
KeyboardData.kp2aFieldIndex = 0;
}
else if (KeyboardData.kp2aFieldIndex == availableFields.size()-3)
{
KeyboardData.kp2aFieldIndex++;
}
else
KeyboardData.kp2aFieldIndex += 2;
updateKp2aKeyLabels();
}
String makeShort(String input, int lineLength)
{
String result = input;
if (input.length() > lineLength)
{
result = input.substring(0,lineLength-1)+"";
}
return result;
}
private void updateKp2aKeyLabels() {
if ((mKeyboardSwitcher.getInputView() != null)
&& (mKeyboardSwitcher.getInputView().getKeyboard() != null))
{
for (Keyboard.Key key : mKeyboardSwitcher.getInputView().getKeyboard().getKeys()) {
boolean isFirstKey = false;
boolean isSecondKey = false;
for (int code : key.codes) {
if (code == -201)
isFirstKey = true;
if (code == -202)
isSecondKey = true;
}
int fieldIndex = -1;
if (isFirstKey) {
fieldIndex = KeyboardData.kp2aFieldIndex;
}
if (isSecondKey) {
fieldIndex = KeyboardData.kp2aFieldIndex + 1;
}
if (fieldIndex >= 0) {
key.label = "";
if (fieldIndex < KeyboardData.availableFields.size()) {
String displayName = "";
StringForTyping fieldData = KeyboardData.availableFields.get(fieldIndex);
if (fieldData != null) {
displayName = makeShort(fieldData.displayName, 10);
if ("Password".equals(fieldData.key))
displayName = getString(R.string.kp2a_password); //might be a shorter variant
if ("UserName".equals(fieldData.key))
displayName = getString(R.string.kp2a_user); //might be a shorter variant
}
key.label = displayName;
}
}
}
mKeyboardSwitcher.getInputView().invalidateAllKeys();
}
}
private void onKp2aKeyPressed() {
if ((mKeyboardSwitcher.getKeyboardMode() == KeyboardSwitcher.MODE_KP2A)
|| (!mKp2aEnableSimpleKeyboard)
|| (!keepass2android.kbbridge.KeyboardData.hasData()))
@@ -1376,132 +1469,149 @@ public class KP2AKeyboard extends InputMethodService
setCandidatesViewShown(false);
}
private void showKp2aDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String title = "Keepass2Android";
List<StringForTyping> availableFields = keepass2android.kbbridge.KeyboardData.availableFields;
final EditorInfo attribute = getCurrentInputEditorInfo();
Log.d("KP2AK", "hint: "+attribute.hintText);
Log.d("KP2AK", "field name: "+attribute.fieldName);
Log.d("KP2AK", "label: "+attribute.label);
attribute.dump(new Printer() {
@Override
public void println(String x) {
Log.d("KP2AK", x);
}
},"");
final ArrayList<StringForTyping> items = new ArrayList<StringForTyping>();
for (StringForTyping entry : availableFields)
{
Log.d("KP2AK", entry.displayName);
items.add(entry.clone());
}
StringForTyping openOrChangeEntry = new StringForTyping();
if (keepass2android.kbbridge.KeyboardData.entryName == null)
{
openOrChangeEntry.displayName = openOrChangeEntry.key = getString(R.string.open_entry);
}
else
{
openOrChangeEntry.displayName = openOrChangeEntry.key = getString(R.string.change_entry);
}
openOrChangeEntry.value = "KP2ASPECIAL_SelectEntryTask";
items.add(openOrChangeEntry);
final String clientPackageName = attribute.packageName;
if ((clientPackageName != null) && (clientPackageName != ""))
{
StringForTyping searchEntry = new StringForTyping();
try
{
searchEntry.key = searchEntry.displayName
= getString(R.string.open_entry_for_app, clientPackageName);
}
catch (java.util.FormatFlagsConversionMismatchException e) //buggy crowdin support for Arabic?
{
android.util.Log.e("KP2A", "Please report this error to crocoapps@gmail.com");
android.util.Log.e("KP2A", e.toString());
private void openOverlaySettings() {
final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.e(TAG, e.getMessage());
}
}
searchEntry.key = searchEntry.displayName
= "Search entry for app";
}
searchEntry.value = "KP2ASPECIAL_SearchUrlTask";
items.add(searchEntry);
}
builder.setTitle(title);
private void showKp2aDialog()
{
boolean androidP = android.os.Build.VERSION.SDK_INT >= 28;
//due to a change in Android P, showing the dialog as dialog does not work (only visible
// above the keyboard, not above the target application). Use an activity here.
// However, this is not perfect as it has another behavior regarding which task is
// in foreground, e.g. Chrome closes the IME when the activity is brought up which causes
// trouble entering data. So we still use the dialog in previous android versions.
if (androidP)
{
final EditorInfo attribute = getCurrentInputEditorInfo();
final String clientPackageName = attribute.packageName;
CharSequence[] itemNames = new CharSequence[items.size()];
int i=0;
for (StringForTyping sft: items)
itemNames[i++] = sft.displayName;
builder.setItems(itemNames,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Intent i = new Intent(this, Kp2aDialog.class);
i.putExtra("clientPackageName", clientPackageName);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
else
{
Log.d("KP2AK", "clicked item: " + items.get(item).key);
if (items.get(item).value.startsWith("KP2ASPECIAL")) {
//change entry
Log.d("KP2AK", "clicked item: " + items.get(item).value);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String title = "Keepass2Android";
List<StringForTyping> availableFields = keepass2android.kbbridge.KeyboardData.availableFields;
String packageName = getApplicationContext().getPackageName();
Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (startKp2aIntent != null)
{
startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER);
startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
String value = items.get(item).value;
String taskName = value.substring("KP2ASPECIAL_".length());
startKp2aIntent.putExtra("KP2A_APPTASK", taskName);
if (taskName.equals("SearchUrlTask"))
{
startKp2aIntent.putExtra("UrlToSearch", "androidapp://"+clientPackageName);
}
startActivity(startKp2aIntent);
} else Log.w("KP2AK", "didn't find intent for "+packageName);
} else {
StringForTyping theItem = items.get(item);
commitStringForTyping(theItem);
}
}
final EditorInfo attribute = getCurrentInputEditorInfo();
attribute.dump(new Printer() {
});
@Override
public void println(String x) {
Log.d("KP2AK", x);
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
}
}, "");
final ArrayList<StringForTyping> items = new ArrayList<StringForTyping>();
for (StringForTyping entry : availableFields) {
items.add(entry.clone());
}
// Create the AlertDialog
AlertDialog dialog = builder.create();
Window window = dialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
lp.token = inputView.getWindowToken();
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.show();
StringForTyping openOrChangeEntry = new StringForTyping();
if (keepass2android.kbbridge.KeyboardData.entryName == null) {
openOrChangeEntry.displayName = openOrChangeEntry.key = getString(R.string.open_entry);
} else {
openOrChangeEntry.displayName = openOrChangeEntry.key = getString(R.string.change_entry);
}
openOrChangeEntry.value = "KP2ASPECIAL_SelectEntryTask";
items.add(openOrChangeEntry);
final String clientPackageName = attribute.packageName;
if ((clientPackageName != null) && (clientPackageName != "")) {
StringForTyping searchEntry = new StringForTyping();
try {
searchEntry.key = searchEntry.displayName
= getString(R.string.open_entry_for_app, new Object[]{clientPackageName});
} catch (java.util.FormatFlagsConversionMismatchException e) //buggy crowdin support for Arabic?
{
android.util.Log.e("KP2A", "Please report this error to crocoapps@gmail.com");
android.util.Log.e("KP2A", e.toString());
searchEntry.key = searchEntry.displayName
= "Search entry for app";
}
searchEntry.value = "KP2ASPECIAL_SearchUrlTask";
items.add(searchEntry);
}
builder.setTitle(title);
CharSequence[] itemNames = new CharSequence[items.size()];
int i = 0;
for (StringForTyping sft : items)
itemNames[i++] = sft.displayName;
builder.setItems(itemNames,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (items.get(item).value.startsWith("KP2ASPECIAL")) {
//change entry
String packageName = getApplicationContext().getPackageName();
Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (startKp2aIntent != null) {
startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER);
startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
String value = items.get(item).value;
String taskName = value.substring("KP2ASPECIAL_".length());
startKp2aIntent.putExtra("KP2A_APPTASK", taskName);
if (taskName.equals("SearchUrlTask")) {
startKp2aIntent.putExtra("UrlToSearch", "androidapp://" + clientPackageName);
}
startActivity(startKp2aIntent);
} else Log.w("KP2AK", "didn't find intent for " + packageName);
} else {
StringForTyping theItem = items.get(item);
commitStringForTyping(theItem);
}
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog
AlertDialog dialog = builder.create();
Window window = dialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
lp.token = inputView.getWindowToken();
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.show();
}
}
private void commitStringForTyping(StringForTyping theItem) {
public void commitStringForTyping(StringForTyping theItem) {
if ((mKp2aRememberAutoFill) && (!TextUtils.isEmpty(getCurrentInputEditorInfo().hintText)))
{
@@ -1517,12 +1627,17 @@ public class KP2AKeyboard extends InputMethodService
Log.d("KP2AK", "committing text for " + theItem.key);
commitKp2aString(theItem.value, getCurrentInputEditorInfo());
}
public void onText(CharSequence text) {
@Override
public void onNewData() {
updateKp2aKeyLabels();
}
public void onText(CharSequence text) {
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
if (text == null)
@@ -1821,6 +1936,7 @@ public class KP2AKeyboard extends InputMethodService
}
setCandidatesViewShown(true);
updateInputViewShown();
updateKp2aKeyLabels();
postUpdateSuggestions();
}
});
@@ -2358,13 +2474,26 @@ public class KP2AKeyboard extends InputMethodService
// receive ringer mode changes to detect silent mode
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
private BroadcastReceiver mSilentModeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateRingerMode();
}
};
private BroadcastReceiver mCommitForTypingReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
StringForTyping stringForTyping = new StringForTyping();
stringForTyping.key = intent.getStringExtra("key");
stringForTyping.value = intent.getStringExtra("value");
KP2AKeyboard.this.commitStringForTyping(stringForTyping);
}
};
// update flags for silent mode
private void updateRingerMode() {
if (mAudioManager == null) {

View File

@@ -0,0 +1,129 @@
package keepass2android.softkeyboard;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.util.Printer;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
import keepass2android.kbbridge.StringForTyping;
public class Kp2aDialog extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
setContentView(R.layout.activity_kp2a_dialog);
ListView listview = ((ListView)findViewById(R.id.mylist));
final String clientPackageName = getIntent().getStringExtra("clientPackageName");
final ArrayList<StringForTyping> items = new ArrayList<StringForTyping>();
StringForTyping openOrChangeEntry = new StringForTyping();
if (keepass2android.kbbridge.KeyboardData.entryName == null)
{
openOrChangeEntry.displayName = openOrChangeEntry.key = getString(R.string.open_entry);
}
else
{
openOrChangeEntry.displayName = openOrChangeEntry.key = getString(R.string.change_entry);
}
openOrChangeEntry.value = "KP2ASPECIAL_SelectEntryTask";
items.add(openOrChangeEntry);
if ((clientPackageName != null) && (clientPackageName != ""))
{
StringForTyping searchEntry = new StringForTyping();
try
{
searchEntry.key = searchEntry.displayName
= getString(R.string.open_entry_for_app, new Object[]{clientPackageName});
}
catch (java.util.FormatFlagsConversionMismatchException e) //buggy crowdin support for Arabic?
{
android.util.Log.e("KP2A", "Please report this error to crocoapps@gmail.com");
android.util.Log.e("KP2A", e.toString());
searchEntry.key = searchEntry.displayName
= "Search entry for app";
}
searchEntry.value = "KP2ASPECIAL_SearchUrlTask";
items.add(searchEntry);
}
String[] itemNames = new String[items.size()];
int i=0;
for (StringForTyping sft: items)
itemNames[i++] = sft.displayName;
listview.setAdapter(new ArrayAdapter<String>(this,
R.layout.kp2a_textview,
itemNames));
listview.setClickable(true);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int item, long l) {
Log.d("KP2AK", "clicked item: " + items.get(item).key);
if (items.get(item).value.startsWith("KP2ASPECIAL")) {
//change entry
Log.d("KP2AK", "clicked item: " + items.get(item).value);
String packageName = getApplicationContext().getPackageName();
Intent startKp2aIntent = getPackageManager().getLaunchIntentForPackage(packageName);
if (startKp2aIntent != null)
{
startKp2aIntent.addCategory(Intent.CATEGORY_LAUNCHER);
startKp2aIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
String value = items.get(item).value;
String taskName = value.substring("KP2ASPECIAL_".length());
startKp2aIntent.putExtra("KP2A_APPTASK", taskName);
if (taskName.equals("SearchUrlTask"))
{
startKp2aIntent.putExtra("UrlToSearch", "androidapp://"+clientPackageName);
}
startActivity(startKp2aIntent);
} else Log.w("KP2AK", "didn't find intent for "+packageName);
} else {
StringForTyping theItem = items.get(item);
KP2AKeyboard.CurrentlyRunningService.commitStringForTyping(theItem);
}
Kp2aDialog.this.finish();
}
});
findViewById(R.id.button_cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Kp2aDialog.this.finish();
}
});
}
}

View File

@@ -43,6 +43,7 @@ public class LatinKeyboardView extends LatinKeyboardBaseView {
static final int KEYCODE_KP2A_ALPHA = -203;
static final int KEYCODE_KP2A_SWITCH = -204;
static final int KEYCODE_KP2A_LOCK = -205;
static final int KEYCODE_KP2A_NEXTFIELDS = -206;
private Keyboard mPhoneKeyboard;

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="12dp">
<Button
android:id="@+id/button_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginTop="19dp"
android:text="@string/cancel" />
<ListView
android:id="@+id/mylist"
android:layout_above="@id/button_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
tools:context="keepass2android.softkeyboard.Kp2aDialog">
</ListView>
</RelativeLayout>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:paddingTop="6dip"
android:paddingBottom="6dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />

View File

@@ -8,7 +8,7 @@
<string name="kp2a_password">密码</string>
<string name="kp2a_prefs">输入凭据设置</string>
<string name="kp2a_auto_fill">自动填充已启用</string>
<string name="kp2a_auto_fill_summary">进入一个空白字段时自动填充文字,如果 Keepass2Android 是激活键盘,且有一个相匹配字段的提示文本</string>
<string name="kp2a_auto_fill_summary">填充区域为空白、键盘有待输入条目、且有字段匹配填充区域的提示文本时,自动将其填入</string>
<string name="kp2a_remember_auto_fill">记忆字段提示文本</string>
<string name="kp2a_remember_auto_fill_summary">如果通过手动选择 Keepass2Android 填充字段,请记住哪个字段在对应字段中输入。该字段是后来由其提示文本重新检测到。</string>
<string name="kp2a_simple_keyboard">简易键盘</string>

View File

@@ -35,6 +35,7 @@
<integer name="key_kp2a_alpha">-203</integer>
<integer name="key_kp2a_switch">-204</integer>
<integer name="key_kp2a_lock">-205</integer>
<integer name="key_kp2a_nextfields">-206</integer>
</resources>

View File

@@ -376,6 +376,7 @@
<!-- Title for Latin keyboard debug settings activity / dialog -->
<string name="english_ime_debug_settings" translatable="false">Android keyboard Debug settings</string>
<string name="prefs_debug_mode" translatable="false">Debug Mode</string>
<string name="kp2a_nextfields"><![CDATA[>]]></string>
</resources>

View File

@@ -12,32 +12,37 @@
<Key
android:codes="@integer/key_kp2a_alpha"
android:keyLabel="@string/label_alpha_key"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isModifier="true"
android:keyEdgeFlags="left" />
<Key
android:codes="@integer/key_kp2a_user"
android:keyLabel="@string/kp2a_user"
android:keyWidth="25%p"
android:keyWidth="22%p"
/>
<Key
android:codes="@integer/key_kp2a_pass"
android:keyLabel="@string/kp2a_password"
android:keyWidth="15%p"
android:keyWidth="12%p"
/>
<Key
android:codes="@integer/key_kp2a_nextfields"
android:keyLabel="@string/kp2a_nextfields"
android:keyWidth="8%p"
/>
<Key
android:codes="@integer/key_kp2a"
android:keyIcon="@drawable/sym_keyboard_kp2a"
android:iconPreview="@drawable/sym_keyboard_feedback_kp2a"
android:popupKeyboard="@xml/popup_kp2a"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isModifier="true" />
<Key
android:codes="@integer/key_delete"
android:keyIcon="@drawable/sym_keyboard_delete"
android:iconPreview="@drawable/sym_keyboard_feedback_delete"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isModifier="true"
android:isRepeatable="true"
/>

View File

@@ -12,32 +12,37 @@
<Key
android:codes="@integer/key_kp2a_alpha"
android:keyLabel="@string/label_alpha_key"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isModifier="true"
android:keyEdgeFlags="left" />
<Key
android:codes="@integer/key_kp2a_user"
android:keyLabel="@string/kp2a_user"
android:keyWidth="20%p"
android:keyWidth="19%p"
/>
<Key
android:codes="@integer/key_kp2a_pass"
android:keyLabel="@string/kp2a_password"
android:keyWidth="20%p"
android:keyWidth="19%p"
/>
<Key
android:codes="@integer/key_kp2a_nextfields"
android:keyLabel="@string/kp2a_nextfields"
android:keyWidth="8%p"
/>
<Key
android:codes="@integer/key_kp2a"
android:keyIcon="@drawable/sym_keyboard_kp2a"
android:iconPreview="@drawable/sym_keyboard_feedback_kp2a"
android:popupKeyboard="@xml/popup_kp2a"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isModifier="true" />
<Key
android:codes="@integer/key_delete"
android:keyIcon="@drawable/sym_keyboard_delete"
android:iconPreview="@drawable/sym_keyboard_feedback_delete"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isModifier="true"
android:isRepeatable="true"
/>

View File

@@ -12,32 +12,37 @@
<Key
android:codes="@integer/key_kp2a_alpha"
android:keyLabel="@string/label_alpha_key"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isModifier="true"
android:keyEdgeFlags="left" />
<Key
android:codes="@integer/key_kp2a_user"
android:keyLabel="@string/kp2a_user"
android:keyWidth="20%p"
/>
android:keyWidth="19%p"
/>
<Key
android:codes="@integer/key_kp2a_pass"
android:keyLabel="@string/kp2a_password"
android:keyWidth="20%p"
/>
android:keyWidth="19%p"
/>
<Key
android:codes="@integer/key_kp2a_nextfields"
android:keyLabel="@string/kp2a_nextfields"
android:keyWidth="8%p"
/>
<Key
android:codes="@integer/key_kp2a"
android:keyIcon="@drawable/sym_bkeyboard_kp2a"
android:iconPreview="@drawable/sym_keyboard_feedback_kp2a"
android:popupKeyboard="@xml/popup_kp2a"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isModifier="true" />
<Key
android:codes="@integer/key_delete"
android:keyIcon="@drawable/sym_bkeyboard_delete"
android:iconPreview="@drawable/sym_keyboard_feedback_delete"
android:keyWidth="12%p"
android:keyWidth="10%p"
android:isRepeatable="true"
/>
<Key

View File

@@ -13,7 +13,7 @@
<string name="afc_cmd_grid_view">Ruudukkonäkymä</string>
<string name="afc_cmd_home">Etusivu</string>
<string name="afc_cmd_list_view">Luettelonäkymä</string>
<string name="afc_cmd_new_folder">Uusi kansio&#8230;</string>
<string name="afc_cmd_new_folder">Uusi kansio</string>
<string name="afc_cmd_select_all_files">Valitse kaikki tiedostot</string>
<string name="afc_cmd_select_all_folders">Valitse kaikki kansiot</string>
<string name="afc_cmd_sort">Lajittele&#8230;</string>
@@ -23,8 +23,8 @@
<string name="afc_hint_folder_name">kansion nimi</string>
<string name="afc_hint_save_as_filename">tiedostonimi</string>
<string name="afc_hint_search">haku</string>
<string name="afc_msg_app_doesnot_have_permission_to_create_files">Sovelluksella ei ole oikeutta luoda tiedostoja/kansioita</string>
<string name="afc_msg_app_doesnot_have_permission_to_delete_files">Sovelluksella ei ole oikeutta poistaa tiedostoja/kansioita</string>
<string name="afc_msg_app_doesnot_have_permission_to_create_files">Sovelluksella ei ole oikeutta luoda tiedostoja / kansioita</string>
<string name="afc_msg_app_doesnot_have_permission_to_delete_files">Sovelluksella ei ole oikeutta poistaa tiedostoja / kansioita</string>
<string name="afc_msg_cancelled">Peruutettu</string>
<string name="afc_msg_cannot_connect_to_file_provider_service">Ei voida yhdistää tiedoston tarjoavaan palveluun</string>
<string name="afc_msg_cannot_create_new_folder_here">Uutta kansiota ei voi luoda tänne</string>
@@ -46,7 +46,7 @@
<string name="afc_pmsg_max_file_count_allowed">...liikaa tiedostoja, maksimimäärä on %1$,d</string>
<string name="afc_pmsg_unknown_error">Tuntematon virhe: %1$s</string>
<string name="afc_root">Juuri</string>
<string name="afc_title_advanced_selection">Valitse...</string>
<string name="afc_title_advanced_selection">Valitse</string>
<string name="afc_title_confirmation">Vahvista</string>
<string name="afc_title_date">Pvm.</string>
<string name="afc_title_error">Virhe</string>

View File

@@ -22,8 +22,12 @@ namespace keepass2android
{
public class CancelDialog : Dialog {
public CancelDialog(Context context): base(context) {
}
protected readonly Activity _activity;
public CancelDialog(Activity activity): base(activity)
{
_activity = activity;
}
public bool Canceled { get; private set; }

View File

@@ -36,14 +36,13 @@ namespace keepass2android
var chalIntent = Activity.TryGetYubichallengeIntentOrPrompt(challenge64, true);
if (chalIntent == null)
throw new Exception("YubiChallenge not installed.");
Activity.StartActivityForResult(chalIntent, _requestCode);
{
Error = Activity.GetString(Resource.String.NoChallengeApp);
}
else
{
Activity.StartActivityForResult(chalIntent, _requestCode);
}
});
while ((Response == null) && (Error == null))

View File

@@ -26,8 +26,9 @@ namespace keepass2android
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(ctx, Android.Resource.Style.ThemeHoloLightDialog));
builder.SetTitle(ctx.GetString(Resource.String.ChangeLog_title));
List<string> changeLog = new List<string>{
ctx.GetString(Resource.String.ChangeLog_1_05),
ctx.GetString(Resource.String.ChangeLog_1_06),
ctx.GetString(Resource.String.ChangeLog_1_05),
ctx.GetString(Resource.String.ChangeLog_1_04b),
ctx.GetString(Resource.String.ChangeLog_1_04),
ctx.GetString(Resource.String.ChangeLog_1_03),

View File

@@ -411,15 +411,15 @@ namespace keepass2android
}
else
{
var task = new CreateNewFilename(new ActionOnFinish((success, messageOrFilename) =>
var task = new CreateNewFilename(this, new ActionOnFinish(this, (success, messageOrFilename, activity) =>
{
if (!success)
{
Toast.MakeText(this, messageOrFilename, ToastLength.Long).Show();
Toast.MakeText(activity, messageOrFilename, ToastLength.Long).Show();
return;
}
_ioc = new IOConnectionInfo { Path = ConvertFilenameToIocPath(messageOrFilename) };
UpdateIocView();
((CreateDatabaseActivity)activity)?.UpdateIocView();
}), filename);
@@ -471,7 +471,7 @@ namespace keepass2android
private readonly IOConnectionInfo _ioc;
public LaunchGroupActivity(IOConnectionInfo ioc, CreateDatabaseActivity activity)
: base(null)
: base(activity, null)
{
_activity = activity;
_ioc = ioc;

View File

@@ -1,4 +1,5 @@
using System;
using Android.App;
using KeePassLib.Serialization;
namespace keepass2android
@@ -7,8 +8,8 @@ namespace keepass2android
{
private readonly string _filename;
public CreateNewFilename(OnFinish finish, string filename)
: base(finish)
public CreateNewFilename(Activity activity, OnFinish finish, string filename)
: base(activity,finish)
{
_filename = filename;
}

View File

@@ -218,14 +218,18 @@ namespace keepass2android
}
//update the Entry output in the App database and notify the CopyToClipboard service
App.Kp2a.GetDb().LastOpenedEntry.OutputStrings.Set(key, new ProtectedString(isProtected, value));
Intent updateKeyboardIntent = new Intent(this, typeof(CopyToClipboardService));
updateKeyboardIntent.SetAction(Intents.UpdateKeyboard);
updateKeyboardIntent.PutExtra(KeyEntry, Entry.Uuid.ToHexString());
StartService(updateKeyboardIntent);
//notify plugins
NotifyPluginsOnModification(Strings.PrefixString+key);
if (App.Kp2a.GetDb()?.LastOpenedEntry != null)
{
App.Kp2a.GetDb().LastOpenedEntry.OutputStrings.Set(key, new ProtectedString(isProtected, value));
Intent updateKeyboardIntent = new Intent(this, typeof(CopyToClipboardService));
updateKeyboardIntent.SetAction(Intents.UpdateKeyboard);
updateKeyboardIntent.PutExtra(KeyEntry, Entry.Uuid.ToHexString());
StartService(updateKeyboardIntent);
//notify plugins
NotifyPluginsOnModification(Strings.PrefixString + key);
}
}
private void AddPluginAction(string pluginPackage, string fieldId, string popupItemId, string displayText, int iconId, Bundle bundleExtra)
@@ -1052,7 +1056,7 @@ namespace keepass2android
internal void AddUrlToEntry(string url, Action finishAction)
internal void AddUrlToEntry(string url, Action<EntryActivity> finishAction)
{
PwEntry initialEntry = Entry.CloneDeep();
@@ -1080,10 +1084,10 @@ namespace keepass2android
//save the entry:
ActionOnFinish closeOrShowError = new ActionOnFinish((success, message) =>
ActionOnFinish closeOrShowError = new ActionOnFinish(this, (success, message, activity) =>
{
OnFinish.DisplayMessage(this, message);
finishAction();
finishAction((EntryActivity)activity);
});

View File

@@ -413,20 +413,20 @@ namespace keepass2android
RunnableOnFinish runnable;
ActionOnFinish closeOrShowError = new ActionOnFinish((success, message) => {
ActionOnFinish closeOrShowError = new ActionOnFinish(this, (success, message, activity) => {
if (success)
{
Finish();
activity.Finish();
} else
{
OnFinish.DisplayMessage(this, message);
OnFinish.DisplayMessage(activity, message);
}
});
ActionOnFinish afterAddEntry = new ActionOnFinish((success, message) =>
ActionOnFinish afterAddEntry = new ActionOnFinish(this, (success, message, activity) =>
{
if (success)
_appTask.AfterAddNewEntry(this, newEntry);
_appTask.AfterAddNewEntry((EntryEditActivity)activity, newEntry);
},closeOrShowError);
if ( State.IsNew ) {
@@ -713,6 +713,7 @@ namespace keepass2android
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
switch (resultCode)
{
case (Result)ResultOkIconPicker:

View File

@@ -119,11 +119,11 @@ namespace keepass2android
}
else
{
var task = new CreateNewFilename(new ActionOnFinish((success, messageOrFilename) =>
var task = new CreateNewFilename(this, new ActionOnFinish(this, (success, messageOrFilename, activity) =>
{
if (!success)
{
Toast.MakeText(this, messageOrFilename, ToastLength.Long).Show();
Toast.MakeText(activity, messageOrFilename, ToastLength.Long).Show();
return;
}
ExportTo(new IOConnectionInfo { Path = ConvertFilenameToIocPath(messageOrFilename) });
@@ -162,15 +162,15 @@ namespace keepass2android
private void ExportTo(IOConnectionInfo ioc)
{
var exportDb = new ExportDb(App.Kp2a, new ActionOnFinish(delegate(bool success, string message)
{
if (!success)
Toast.MakeText(this, message, ToastLength.Long).Show();
else
Toast.MakeText(this, GetString(Resource.String.export_database_successful), ToastLength.Long).Show();
Finish();
}
), _ffp[_fileFormatIndex], ioc);
var exportDb = new ExportDb(this, App.Kp2a, new ActionOnFinish(this, (success, message, activity) =>
{
if (!success)
Toast.MakeText(activity, message, ToastLength.Long).Show();
else
Toast.MakeText(activity, GetString(Resource.String.export_database_successful), ToastLength.Long).Show();
activity.Finish();
}
), _ffp[_fileFormatIndex], ioc);
ProgressTask pt = new ProgressTask(App.Kp2a, this, exportDb);
pt.Run();
}
@@ -196,7 +196,7 @@ namespace keepass2android
private readonly FileFormatProvider _fileFormat;
private IOConnectionInfo _targetIoc;
public ExportDb(IKp2aApp app, OnFinish onFinish, FileFormatProvider fileFormat, IOConnectionInfo targetIoc) : base(onFinish)
public ExportDb(Activity activity, IKp2aApp app, OnFinish onFinish, FileFormatProvider fileFormat, IOConnectionInfo targetIoc) : base(activity, onFinish)
{
_app = app;
this._fileFormat = fileFormat;

View File

@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Linq;
#if !NoNet
using System.Net.FtpClient;
using Keepass2android.Javafilestorage;
#endif
using System.Text;
@@ -14,7 +16,6 @@ using Android.Views;
using Android.Widget;
using Java.IO;
using keepass2android.Io;
using Keepass2android.Javafilestorage;
using KeePassLib.Serialization;
using KeePassLib.Utility;
@@ -65,7 +66,9 @@ namespace keepass2android
string user = dlgContents.FindViewById<EditText>(Resource.Id.sftp_user).Text;
string password = dlgContents.FindViewById<EditText>(Resource.Id.sftp_password).Text;
string initialPath = dlgContents.FindViewById<EditText>(Resource.Id.sftp_initial_dir).Text;
string sftpPath = new Keepass2android.Javafilestorage.SftpStorage().BuildFullPath(host, port, initialPath, user,
if (string.IsNullOrEmpty(initialPath))
initialPath = "/";
string sftpPath = new Keepass2android.Javafilestorage.SftpStorage().BuildFullPath(host, port, initialPath, user,
password);
onStartBrowse(sftpPath);
});

View File

@@ -34,7 +34,7 @@ namespace keepass2android
public FingerprintManager FingerprintManager
{
get { return (FingerprintManager) Context.GetSystemService(Context.FingerprintService); }
get { return Context.GetSystemService(Context.FingerprintService) as FingerprintManager; }
}
public KeyguardManager KeyguardManager
@@ -265,6 +265,11 @@ namespace keepass2android
_iv = Base64.Decode(PreferenceManager.GetDefaultSharedPreferences(context).GetString(GetIvPrefKey(prefKey), null), 0);
}
public static bool IsSetUp(Context context, string prefKey)
{
return PreferenceManager.GetDefaultSharedPreferences(context).GetString(GetIvPrefKey(prefKey), null) != null;
}
public override bool Init()
{
Kp2aLog.Log("FP: Init for Dec");

View File

@@ -223,7 +223,7 @@ namespace keepass2android
if (requestCode == FingerprintPermissionRequestCode && grantResults[0] == Permission.Granted)
{
FingerprintModule fpModule = new FingerprintModule(this);
if (!fpModule.FingerprintManager.IsHardwareDetected)
if (fpModule.FingerprintManager == null || (!fpModule.FingerprintManager.IsHardwareDetected))
{
//seems like not all Samsung Devices (e.g. Note 4) don't support the Android 6 fingerprint API
if (!TrySetupSamsung())

View File

@@ -230,11 +230,8 @@ namespace keepass2android
{
//yes
ProgressTask pt = new ProgressTask(App.Kp2a, this,
new AddTemplateEntries(this, App.Kp2a, new ActionOnFinish(
delegate
{
StartAddEntry();
})));
new AddTemplateEntries(this, App.Kp2a, new ActionOnFinish(this,
(success, message, activity) => ((GroupActivity)activity)?.StartAddEntry())));
pt.Run();
},
(o, args) =>

View File

@@ -53,6 +53,7 @@ namespace keepass2android
{ Resource.Id.cancel_insert_element, 20 },
{ Resource.Id.insert_element, 20 },
//only use the same id if elements can be shown simultaneously!
{ Resource.Id.fingerprint_infotext, 12 },
{ Resource.Id.autofill_infotext, 11 },
{ Resource.Id.notification_info_android8_infotext, 10 },
{ Resource.Id.infotext, 9 },
@@ -239,6 +240,7 @@ namespace keepass2android
AppTask.StartInGroupActivity(this);
AppTask.SetupGroupBaseActivityButtons(this);
UpdateFingerprintInfo();
UpdateAutofillInfo();
UpdateAndroid8NotificationInfo();
UpdateInfotexts();
@@ -441,7 +443,33 @@ namespace keepass2android
}
};
}
if (FindViewById(Resource.Id.info_dont_show_fingerprint_again) != null)
{
FindViewById(Resource.Id.info_dont_show_fingerprint_again).Click += (sender, args) =>
{
_prefs.Edit().PutBoolean(fingerprintinfohidden_prefskey, true).Commit();
UpdateFingerprintInfo();
};
}
if (FindViewById(Resource.Id.hide_fingerprint_info) != null)
{
FindViewById(Resource.Id.hide_fingerprint_info).Click += (sender, args) =>
{
_prefs.Edit().PutBoolean(fingerprintinfohidden_prefskey + App.Kp2a.GetDb().CurrentFingerprintPrefKey, true).Commit();
UpdateFingerprintInfo();
};
}
if (FindViewById(Resource.Id.enable_fingerprint) != null)
{
FindViewById(Resource.Id.enable_fingerprint).Click += (sender, args) =>
{
StartActivity(typeof(FingerprintSetupActivity));
};
}
if (FindViewById(Resource.Id.info_dont_show_autofill_again) != null)
{
@@ -565,6 +593,7 @@ namespace keepass2android
}
const string autofillservicewasenabled_prefskey = "AutofillServiceWasEnabled";
const string fingerprintinfohidden_prefskey = "fingerprintinfohidden_prefskey";
private void UpdateAutofillInfo()
{
@@ -594,6 +623,33 @@ namespace keepass2android
UpdateBottomBarElementVisibility(Resource.Id.autofill_infotext, canShowAutofillInfo);
}
private void UpdateFingerprintInfo()
{
bool canShowFingerprintInfo = false;
bool disabledForDatabase = _prefs.GetBoolean(fingerprintinfohidden_prefskey + App.Kp2a.GetDb().CurrentFingerprintPrefKey, false);
bool disabledForAll = _prefs.GetBoolean(fingerprintinfohidden_prefskey, false);
if (!disabledForAll && !disabledForDatabase)
{
FingerprintModule fpModule = new FingerprintModule(this);
if (fpModule.FingerprintManager != null && fpModule.FingerprintManager.IsHardwareDetected)
{
FingerprintUnlockMode um;
Enum.TryParse(_prefs.GetString(Database.GetFingerprintModePrefKey(App.Kp2a.GetDb().Ioc), ""), out um);
canShowFingerprintInfo = um == FingerprintUnlockMode.Disabled;
}
}
if (canShowFingerprintInfo)
{
RegisterInfoTextDisplay("FingerprintSuggestion"); //this ensures that we don't show the general info texts too soon
}
UpdateBottomBarElementVisibility(Resource.Id.fingerprint_infotext, canShowFingerprintInfo);
}
protected void UpdateBottomBarElementVisibility(int resourceId, bool canShow)
{
if (canShow)
@@ -616,7 +672,13 @@ namespace keepass2android
var moveElement = new MoveElements(elementsToMove.ToList(), Group, this, App.Kp2a, new ActionOnFinish((success, message) => { StopMovingElements(); if (!String.IsNullOrEmpty(message)) Toast.MakeText(this, message, ToastLength.Long).Show(); }));
var moveElement = new MoveElements(elementsToMove.ToList(), Group, this, App.Kp2a, new ActionOnFinish(this,
(success, message, activity) =>
{
((GroupBaseActivity)activity)?.StopMovingElements();
if (!String.IsNullOrEmpty(message))
Toast.MakeText(activity, message, ToastLength.Long).Show();
}));
var progressTask = new ProgressTask(App.Kp2a, this, moveElement);
progressTask.Run();
@@ -867,8 +929,8 @@ namespace keepass2android
{
private readonly IOConnectionInfo _ioc;
public SyncOtpAuxFile(IOConnectionInfo ioc)
: base(null)
public SyncOtpAuxFile(Activity activity, IOConnectionInfo ioc)
: base(activity,null)
{
_ioc = ioc;
}
@@ -900,19 +962,19 @@ namespace keepass2android
{
var filestorage = App.Kp2a.GetFileStorage(App.Kp2a.GetDb().Ioc);
RunnableOnFinish task;
OnFinish onFinish = new ActionOnFinish((success, message) =>
OnFinish onFinish = new ActionOnFinish(this, (success, message, activity) =>
{
if (!String.IsNullOrEmpty(message))
Toast.MakeText(this, message, ToastLength.Long).Show();
Toast.MakeText(activity, message, ToastLength.Long).Show();
// Tell the adapter to refresh it's list
BaseAdapter adapter = (BaseAdapter)ListAdapter;
adapter.NotifyDataSetChanged();
BaseAdapter adapter = (BaseAdapter)((GroupBaseActivity)activity)?.ListAdapter;
adapter?.NotifyDataSetChanged();
if (App.Kp2a.GetDb().OtpAuxFileIoc != null)
{
var task2 = new SyncOtpAuxFile(App.Kp2a.GetDb().OtpAuxFileIoc);
new ProgressTask(App.Kp2a, this, task2).Run();
var task2 = new SyncOtpAuxFile(this, App.Kp2a.GetDb().OtpAuxFileIoc);
new ProgressTask(App.Kp2a, activity, task2).Run(true);
}
});
@@ -982,33 +1044,28 @@ namespace keepass2android
public class RefreshTask : OnFinish
{
readonly GroupBaseActivity _act;
public RefreshTask(Handler handler, GroupBaseActivity act)
: base(handler)
: base(act, handler)
{
_act = act;
}
public override void Run()
{
if (Success)
{
_act.RefreshIfDirty();
((GroupBaseActivity)ActiveActivity)?.RefreshIfDirty();
}
else
{
DisplayMessage(_act);
DisplayMessage(ActiveActivity);
}
}
}
public class AfterDeleteGroup : OnFinish
{
readonly GroupBaseActivity _act;
public AfterDeleteGroup(Handler handler, GroupBaseActivity act)
: base(handler)
: base(act, handler)
{
_act = act;
}
@@ -1016,13 +1073,13 @@ namespace keepass2android
{
if (Success)
{
_act.RefreshIfDirty();
((GroupBaseActivity)ActiveActivity)?.RefreshIfDirty();
}
else
{
Handler.Post(() =>
{
Toast.MakeText(_act, "Unrecoverable error: " + Message, ToastLength.Long).Show();
Toast.MakeText(ActiveActivity, "Unrecoverable error: " + Message, ToastLength.Long).Show();
});
App.Kp2a.LockDatabase(false);

View File

@@ -27,7 +27,7 @@ using KeePassLib.Utility;
namespace keepass2android
{
[Activity(Label = "@string/app_name", Theme = "@style/Dialog")]
public class GroupEditActivity : LifecycleDebugActivity
public class GroupEditActivity : LifecycleAwareActivity
{
public const String KeyParent = "parent";
public const String KeyName = "name";
@@ -73,7 +73,7 @@ namespace keepass2android
i.PutExtra(KeyParent, parent.Uuid.ToHexString());
i.PutExtra(KeyGroupUuid, groupToEdit.Uuid.ToHexString());
act.StartActivityForResult(i, 0);
act.StartActivityForResult(i, GroupEditActivity.RequestCodeGroupEdit);
}
protected override void OnCreate (Bundle savedInstanceState)
@@ -144,7 +144,8 @@ namespace keepass2android
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
switch ((int)resultCode)
base.OnActivityResult(requestCode, resultCode, data);
switch ((int)resultCode)
{
case EntryEditActivity.ResultOkIconPicker:
_selectedIconId = data.Extras.GetInt(IconPickerActivity.KeyIconId, (int) PwIcon.Key);

View File

@@ -74,7 +74,7 @@ namespace keepass2android
/// </summary>
[Activity(Label = AppNames.AppName, MainLauncher = false, Theme = "@style/MyTheme_Blue")]
[IntentFilter(new[] { Intent.ActionMain }, Categories = new[] { "android.intent.category.LAUNCHER", "android.intent.category.MULTIWINDOW_LAUNCHER" })]
public class KeePass : LifecycleDebugActivity, IDialogInterfaceOnDismissListener
public class KeePass : LifecycleAwareActivity, IDialogInterfaceOnDismissListener
{
public const Result ExitNormal = Result.FirstUser;
public const Result ExitLock = Result.FirstUser+1;

View File

@@ -24,15 +24,15 @@ using Android.Support.V7.App;
namespace keepass2android
{
public abstract class LifecycleDebugActivity : AppCompatActivity
public abstract class LifecycleAwareActivity : AppCompatActivity
{
protected LifecycleDebugActivity (IntPtr javaReference, JniHandleOwnership transfer)
protected LifecycleAwareActivity (IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
protected LifecycleDebugActivity()
protected LifecycleAwareActivity()
{
}
@@ -63,6 +63,7 @@ namespace keepass2android
protected override void OnStart()
{
ProgressTask.SetNewActiveActivity(this);
base.OnStart();
Kp2aLog.Log(ClassName+".OnStart");
}
@@ -90,7 +91,8 @@ namespace keepass2android
{
base.OnStop();
Kp2aLog.Log(ClassName+".OnStop");
}
ProgressTask.RemoveActiveActivity(this);
}
}
}

View File

@@ -27,7 +27,7 @@ namespace keepass2android
/// <summary>
/// Base class for activities. Notifies the TimeoutHelper whether the app is active or not.
/// </summary>
public class LockingActivity : LifecycleDebugActivity {
public class LockingActivity : LifecycleAwareActivity {
public LockingActivity (IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
@@ -123,12 +123,13 @@ namespace keepass2android
}
public Intent TryGetYubichallengeIntentOrPrompt(byte[] challenge, bool promptToInstall)
{
Intent chalIntent = new Intent("com.yubichallenge.NFCActivity.CHALLENGE");
Intent chalIntent = new Intent("net.pp3345.ykdroid.intent.action.CHALLENGE_RESPONSE");
chalIntent.PutExtra("challenge", challenge);
chalIntent.PutExtra("slot", 2);
IList<ResolveInfo> activities = PackageManager.QueryIntentActivities(chalIntent, 0);
IList<ResolveInfo> activities = PackageManager.QueryIntentActivities(chalIntent, 0);
bool isIntentSafe = activities.Count > 0;
if (isIntentSafe)
{
@@ -137,14 +138,22 @@ namespace keepass2android
if (promptToInstall)
{
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.SetMessage(Resource.String.YubiChallengeNotInstalled);
string message = GetString(Resource.String.NoChallengeApp) + " " + GetString(Resource.String.PleaseInstallApp, new Java.Lang.Object[]{"ykDroid"});
Intent yubichalIntent = new Intent("com.yubichallenge.NFCActivity.CHALLENGE");
IList<ResolveInfo> yubichallengeactivities = PackageManager.QueryIntentActivities(yubichalIntent, 0);
bool hasYubichallenge = yubichallengeactivities.Count > 0;
if (hasYubichallenge)
message += " " + GetString(Resource.String.AppOutdated, new Java.Lang.Object[] {"YubiChallenge"});
b.SetMessage(message);
b.SetPositiveButton(Android.Resource.String.Ok,
delegate { Util.GotoUrl(this, GetString(Resource.String.MarketURL) + "com.yubichallenge"); });
delegate { Util.GotoUrl(this, GetString(Resource.String.MarketURL) + "net.pp3345.ykdroid"); });
b.SetNegativeButton(Resource.String.cancel, delegate { });
b.Create().Show();
}
return null;
}
}
}
}

View File

@@ -310,7 +310,7 @@ namespace keepass2android
Handler handler = new Handler();
OnFinish onFinish = new AfterLoad(handler, this, _ioConnection);
_performingLoad = true;
LoadDb task = new LoadDb(App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, _keyFileOrProvider, onFinish);
LoadDb task = new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, _keyFileOrProvider, onFinish);
_loadDbFileTask = null; // prevent accidental re-use
new ProgressTask(App.Kp2a, this, task).Run();
}
@@ -1453,7 +1453,7 @@ namespace keepass2android
LoadDb task = (KeyProviderType == KeyProviders.Otp)
? new SaveOtpAuxFileAndLoadDb(App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, _keyFileOrProvider,
onFinish, this)
: new LoadDb(App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, _keyFileOrProvider, onFinish);
: new LoadDb(this, App.Kp2a, _ioConnection, _loadDbFileTask, compositeKey, _keyFileOrProvider, onFinish);
_loadDbFileTask = null; // prevent accidental re-use
SetNewDefaultFile();
@@ -2028,7 +2028,7 @@ namespace keepass2android
readonly PasswordActivity _act;
private readonly IOConnectionInfo _ioConnection;
public AfterLoad(Handler handler, PasswordActivity act, IOConnectionInfo ioConnection):base(handler)
public AfterLoad(Handler handler, PasswordActivity act, IOConnectionInfo ioConnection):base(act, handler)
{
_act = act;
_ioConnection = ioConnection;
@@ -2172,7 +2172,7 @@ namespace keepass2android
private readonly PasswordActivity _act;
public SaveOtpAuxFileAndLoadDb(IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, string keyfileOrProvider, OnFinish finish, PasswordActivity act) : base(app, ioc, databaseData, compositeKey, keyfileOrProvider, finish)
public SaveOtpAuxFileAndLoadDb(IKp2aApp app, IOConnectionInfo ioc, Task<MemoryStream> databaseData, CompositeKey compositeKey, string keyfileOrProvider, OnFinish finish, PasswordActivity act) : base(act, app, ioc, databaseData, compositeKey, keyfileOrProvider, finish)
{
_act = act;
}

View File

@@ -58,7 +58,7 @@
</intent-filter>
</activity>
<activity android:configChanges="orientation" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<activity android:configChanges="orientation|keyboard|keyboardHidden" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />

View File

@@ -11,7 +11,7 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/MyTheme" android:name="keepass2android.PasswordActivity">
<activity android:configChanges="orientation|keyboard|keyboardHidden" android:label="@string/app_name" android:theme="@style/MyTheme" android:name="keepass2android.PasswordActivity">
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />

View File

@@ -1,14 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="119"
android:versionName="1.05e"
android:versionCode="127"
android:versionName="1.06f"
package="keepass2android.keepass2android"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="26" />
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher" android:label="KP2A entry search" android:name="keepass2android.keepass2android.permission.KP2aInternalSearch" android:protectionLevel="signature" />
<permission android:description="@string/permission_desc3" android:icon="@drawable/ic_launcher" android:label="KP2A choose autofill dataset" android:name="keepass2android.keepass2android.permission.Kp2aChooseAutofill" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@mipmap/ic_launcher_online">
<application android:label="keepass2android"
android:icon="@mipmap/ic_launcher_online"
android:roundIcon="@mipmap/ic_launcher_online_round"
>
<activity android:name="com.dropbox.core.android.AuthActivity" android:launchMode="singleTask" android:configChanges="orientation|keyboard">
<intent-filter>
<data android:scheme="db-i8shu7v1hgh7ynt" />
@@ -59,7 +62,7 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:configChanges="orientation" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<activity android:configChanges="orientation|keyboard|keyboardHidden" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="93"
android:versionName="1.01-g"
android:versionCode="127"
android:versionName="1.06f"
package="keepass2android.keepass2android_nonet"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher" android:label="KP2A entry search" android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalSearch" android:protectionLevel="signature" />
<permission android:description="@string/permission_desc3" android:icon="@drawable/ic_launcher" android:label="KP2A choose autofill dataset" android:name="keepass2android.keepass2android_nonet.permission.Kp2aChooseAutofill" android:protectionLevel="signature" />
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="26" />
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher_offline" android:label="KP2A entry search" android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalSearch" android:protectionLevel="signature" />
<permission android:description="@string/permission_desc3" android:icon="@drawable/ic_launcher_offline" android:label="KP2A choose autofill dataset" android:name="keepass2android.keepass2android_nonet.permission.Kp2aChooseAutofill" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@mipmap/ic_launcher_offline">
<provider android:name="group.pals.android.lib.ui.filechooser.providers.localfile.LocalFileProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.localfile" android:exported="false" />
<provider android:name="group.pals.android.lib.ui.filechooser.providers.history.HistoryProvider" android:authorities="keepass2android.keepass2android_nonet.android-filechooser.history" android:exported="false" />
@@ -42,8 +42,7 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:configChanges="orientation" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<activity android:configChanges="orientation|keyboard|keyboardHidden" android:label="@string/app_name" android:theme="@style/MyTheme_Blue" android:name="keepass2android.PasswordActivity" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@@ -52,12 +51,13 @@
<data android:mimeType="application/octet-stream" />
<data android:host="*" />
</intent-filter>
<intent-filter>
<action android:name="kp2a.action.PasswordActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
@@ -126,8 +126,8 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" />
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalSearch" />
<uses-permission android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalFileBrowsing" />
<uses-permission android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalSearch" />
<!-- Samsung Pass permission -->
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
</manifest>

View File

@@ -37,7 +37,7 @@ namespace keepass2android
WindowSoftInputMode = SoftInput.AdjustResize,
MainLauncher = false,
Theme = "@style/MyTheme_Blue")]
public class QuickUnlock : LifecycleDebugActivity, IFingerprintAuthCallback
public class QuickUnlock : LifecycleAwareActivity, IFingerprintAuthCallback
{
private IOConnectionInfo _ioc;
private QuickUnlockBroadcastReceiver _intentReceiver;
@@ -261,7 +261,7 @@ namespace keepass2android
_fingerprintIdentifier = new FingerprintDecryption(fpModule, App.Kp2a.GetDb().CurrentFingerprintPrefKey, this,
App.Kp2a.GetDb().CurrentFingerprintPrefKey);
}
if (_fingerprintIdentifier == null)
if ((_fingerprintIdentifier == null) && (!FingerprintDecryption.IsSetUp(this, App.Kp2a.GetDb().CurrentFingerprintPrefKey)))
{
try
{
@@ -277,12 +277,15 @@ namespace keepass2android
catch (Exception)
{
Kp2aLog.Log("trying Samsung Fingerprint API...failed.");
FindViewById<ImageButton>(Resource.Id.fingerprintbtn).Visibility = ViewStates.Gone;
_fingerprintIdentifier = null;
return false;
}
}
btn.Tag = GetString(Resource.String.fingerprint_unlock_hint);
if (_fingerprintIdentifier == null)
{
FindViewById<ImageButton>(Resource.Id.fingerprintbtn).Visibility = ViewStates.Gone;
return false;
}
btn.Tag = GetString(Resource.String.fingerprint_unlock_hint);
if (_fingerprintIdentifier.Init())
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -139,7 +139,8 @@ android:paddingRight="16dp"
android:fontFamily="sans-serif"
android:textSize="20sp"
android:focusable="true"
android:focusableInTouchMode="true" />
android:focusableInTouchMode="true"
android:importantForAccessibility="no"/>
<ImageButton
android:id="@+id/fingerprintbtn"

View File

@@ -108,7 +108,8 @@ android:layout_height="wrap_content">
android:hint="@string/hint_pass"
android:inputType="textPassword"
android:singleLine="true"
android:typeface="monospace" />
android:typeface="monospace"
android:importantForAccessibility="no" />
<!-- Confirm Password -->
<EditText
android:id="@+id/entry_confpassword"
@@ -119,7 +120,8 @@ android:layout_height="wrap_content">
android:hint="@string/hint_conf_pass"
android:inputType="textPassword"
android:singleLine="true"
android:typeface="monospace" />
android:typeface="monospace"
android:importantForAccessibility="no"/>
</RelativeLayout>

View File

@@ -74,7 +74,8 @@
android:paddingTop="0dp"
android:singleLine="true"
android:inputType="textPassword"
android:hint="password" />
android:hint="password"
android:importantForAccessibility="no"/>
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="wrap_content"
@@ -110,7 +111,8 @@
android:paddingTop="0dp"
android:singleLine="true"
android:inputType="textPassword"
android:hint="confirm password" />
android:hint="confirm password"
android:importantForAccessibility="no"/>
</LinearLayout>
</LinearLayout>
<!-- URL -->

View File

@@ -27,7 +27,7 @@
android:id="@+id/group_name_vdots"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:src="@drawable/vdots"
android:src="@drawable/vdots_bright"
android:gravity="right|bottom"
android:layout_alignParentRight="true"
android:paddingTop="4sp"/>

View File

@@ -56,7 +56,8 @@
android:inputType="textPassword"
android:text=""
android:singleLine="true"
android:hint="@string/hint_pass" />
android:hint="@string/hint_pass"
android:importantForAccessibility="no"/>
<TextView android:id="@+id/initial_dir"
android:layout_width="wrap_content"

View File

@@ -85,6 +85,57 @@
android:text="@string/dont_show_again"
style="@style/BottomBarButton" />
</LinearLayout>
<LinearLayout
android:id="@+id/fingerprint_infotext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical">
<TextView android:id="@+id/myinfotext" android:text="@string/enable_fingerprint_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_margin="6dp"
android:layout_marginBottom="2dp"
/>
<RelativeLayout
android:id="@+id/fingerprint_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false">
<Button
android:id="@+id/enable_fingerprint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:paddingTop="4dp"
android:text="@string/yes"
style="@style/BottomBarButton" />
<Button
android:id="@+id/hide_fingerprint_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:paddingTop="4dp"
android:text="@string/no"
style="@style/BottomBarButton" />
</RelativeLayout>
<Button
android:id="@+id/info_dont_show_fingerprint_again"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:text="@string/dont_show_again"
style="@style/BottomBarButton" />
</LinearLayout>
<LinearLayout
android:id="@+id/notification_info_android8_infotext"
android:layout_width="match_parent"

View File

@@ -36,7 +36,8 @@
android:inputType="textPassword"
android:singleLine="true"
android:text=""
android:hint="@string/hint_pass" />
android:hint="@string/hint_pass"
android:importantForAccessibility="no"/>

View File

@@ -37,7 +37,8 @@
android:inputType="textPassword"
android:singleLine="true"
android:text=""
android:hint="@string/hint_pass" />
android:hint="@string/hint_pass"
android:importantForAccessibility="no"/>

View File

@@ -153,7 +153,8 @@
android:singleLine="true"
android:inputType="textPassword"
android:fontFamily="sans-serif"
android:hint="@string/hint_login_pass" />
android:hint="@string/hint_login_pass"
android:importantForAccessibility="no"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -22,4 +22,13 @@
android:paddingRight="0dp"
android:paddingLeft="0dp" />
<Switch
android:id="@+id/local_backups_switch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/show_local_backups"
android:checked="false"
android:textColor="#fff"
android:gravity="left"/>
</LinearLayout>

View File

@@ -46,7 +46,8 @@
android:layout_height="wrap_content"
android:inputType="textPassword"
android:singleLine="true"
android:hint="@string/hint_pass" />
android:hint="@string/hint_pass"
android:importantForAccessibility="no"/>
<TextView android:id="@+id/initial_dir"
android:layout_width="wrap_content"

View File

@@ -66,7 +66,7 @@
<string name="entry_is_available">متوفر</string>
<string name="not_possible_im_picker">لا يمكن فتح صندوق الحوار لتحديد طريقة الإدخال. يرجى تفعيل لوحة المفاتيح يدويًا.</string>
<string name="please_activate_keyboard">يرجى تفعيل لوحة مفاتيح Keepass2Android في إعدادات النظام.</string>
<string name="creating_db_key">إنشاء مفتاح قاعدة البيانات&#8230;</string>
<string name="creating_db_key">إنشاء مفتاح قاعدة البيانات</string>
<string name="current_group">المجموعة الحالية</string>
<string name="current_group_root">المجموعة الحالية: الأساس</string>
<string name="database">قاعدة البيانات</string>
@@ -104,7 +104,7 @@
<string name="entry_expires">انتهاء الصلاحية</string>
<string name="entry_group_name">اسم المجموعة</string>
<string name="entry_keyfile">ملف المفتاح (اختياري)</string>
<string name="keyfile_heading">ملف مفتاح</string>
<string name="keyfile_heading">ملف المفتاح</string>
<string name="entry_modified">معدل</string>
<string name="entry_password">كلمة السر</string>
<string name="entry_save">حفظ</string>
@@ -157,7 +157,7 @@
<string name="length">الطول</string>
<string name="list_size_title">حجم قائمة المجموعات</string>
<string name="list_size_summary">حجم النص في قائمة المجموعات</string>
<string name="loading_database">جاري تحميل قاعدة البيانات&#8230;</string>
<string name="loading_database">جاري تحميل قاعدة البيانات</string>
<string name="lowercase">حروف صغيرة</string>
<string name="MaskedPassword">*****</string>
<string name="maskpass_title">حجب كلمة السر</string>
@@ -201,10 +201,11 @@
<string name="master_key_type">اختر نوع المفتاح الرئيسي:</string>
<string name="progress_create">إنشاء قاعدة بيانات جديدة...</string>
<string name="create_database">إنشاء قاعدة بيانات</string>
<string name="progress_title">جاري العمل&#8230;</string>
<string name="progress_title">جاري العمل</string>
<string name="remember_keyfile_summary">تذكر موقع ملف المفتاح</string>
<string name="remember_keyfile_title">حفظ ملف المفتاح</string>
<string name="remove_from_filelist">حذف</string>
<string name="edit">تعديل</string>
<string name="rijndael">Rijndael (AES)</string>
<string name="root">البداية</string>
<string name="KeyDerivFunc">طريقة اشتقاق المفتاح</string>
@@ -215,8 +216,8 @@
<string name="argon2parallelism">التوازي لـ Argon2</string>
<string name="database_name">اسم قاعدة البيانات</string>
<string name="default_username">اسم المستخدم الافتراضي للقيود الجديدة</string>
<string name="saving_database">جاري حفظ قاعدة البيانات&#8230;</string>
<string name="exporting_database">جاري تصدير قاعدة البيانات&#8230;</string>
<string name="saving_database">جاري حفظ قاعدة البيانات</string>
<string name="exporting_database">جاري تصدير قاعدة البيانات</string>
<string name="export_database_successful">تم تصدير قاعدة البيانات بنجاح!</string>
<string name="space">فراغ</string>
<string name="search_label">بحث</string>
@@ -230,7 +231,7 @@
<string name="search_hint">البحث عن ماذا</string>
<string name="search_results">نتائج البحث</string>
<string name="search_in">البحث في</string>
<string name="select_other_entry">حدد قيدًا آخر</string>
<string name="select_other_entry">اختر مُدخل آخر</string>
<string name="select_group_then_add">افتح المجموعة المطلوبة، ثم اضغط على \"%1$s\"!</string>
<string name="insert_element_here">أدخل هنا</string>
<string name="twofish">تشفير Twofish</string>
@@ -317,11 +318,9 @@
<string name="NoDonationReminder_title">لا تطلب التبرع مطلقاً</string>
<string name="NoDonationReminder_summary">لن أعطيك قرشاً أو أني تبرعت مسبقاُ. لا تطلب التبرع، ولا حتى في عيد ميلاد المطور.</string>
<string name="UseOfflineCache_title">التخزين المؤقت لقاعدة بيانات</string>
<string name="UseOfflineCache_summary">الاحتفاظ بنسخة ملفات قاعدة البيانات البعيدة في مجلد ذاكرة التخزين المؤقت للتطبيق. هذا يسمح باستخدام قواعد البيانات البعيد حتى عندما تكون غير متصل.</string>
<string name="AcceptAllServerCertificates_title">شهادات SSL</string>
<string name="AcceptAllServerCertificates_summary">حدد السلوك عند فشل التحقق من صحة الشهادة. ملاحظة: يمكنك تثبيت شهادات على الجهاز الخاص بك إذا فشل التحقق من صحة الشهادة!</string>
<string name="ClearOfflineCache_title">مسح ذاكرة التخزين المؤقت؟</string>
<string name="ClearOfflineCache_question">سيؤدي هذا إلى حذف كافة ملفات قاعدة البيانات المخزنة مؤقتاً. سيتم فقدان أية تغييرات قمت بها بدون اتصال ولم يتم مزامنتها بعد! هل تريد المتابعة؟</string>
<string name="CheckForFileChangesOnSave_title">التحقق من التعديلات</string>
<string name="CheckForFileChangesOnSave_summary">التحقق مما إذا تم تعديل الملف خارجيًا قبل حفظ التغييرات.</string>
<string name="CheckForDuplicateUuids_title">التحقق من وجود معرفات (UUIDs) مكررة</string>
@@ -361,49 +360,34 @@
<string name="suggest_improvements">اقترح أو صوت على التحسينات</string>
<string name="rate_app">قيّم هذا التطبيق</string>
<string name="translate_app">ترجم KP2A</string>
<string name="AddingEntry">جاري إضافة قيد&#8230;</string>
<string name="AddingGroup">جاري إضافة مجموعة&#8230;</string>
<string name="DeletingEntry">جاري حذف القيد&#8230;</string>
<string name="DeletingGroup">جاري حذف المجموعة&#8230;</string>
<string name="DeletingItems">جاري حذف العناصر&#8230;</string>
<string name="SettingPassword">جاري تعيين كلمة مرور&#8230;</string>
<string name="UndoingChanges">جاري التراجع عن التغييرات&#8230;</string>
<string name="TransformingKey">جاري تحويل المفتاح الرئيسي&#8230;</string>
<string name="DecodingDatabase">جاري فك تشفير قاعدة البيانات&#8230;</string>
<string name="ParsingDatabase">جاري تحليل قاعدة البيانات&#8230;</string>
<string name="CheckingTargetFileForChanges">جاري التحقق من وجود تغييرات في الملف الهدف&#8230;</string>
<string name="AddingEntry">جاري إضافة قيد</string>
<string name="AddingGroup">جاري إضافة مجموعة</string>
<string name="DeletingEntry">جاري حذف القيد</string>
<string name="DeletingGroup">جاري حذف المجموعة</string>
<string name="DeletingItems">جاري حذف العناصر</string>
<string name="SettingPassword">جاري تعيين كلمة مرور</string>
<string name="UndoingChanges">جاري التراجع عن التغييرات</string>
<string name="TransformingKey">جاري تحويل المفتاح الرئيسي</string>
<string name="DecodingDatabase">جاري فك تشفير قاعدة البيانات</string>
<string name="ParsingDatabase">جاري تحليل قاعدة البيانات</string>
<string name="CheckingTargetFileForChanges">جاري التحقق من وجود تغييرات في الملف الهدف</string>
<string name="TitleSyncQuestion">دمج التغييرات؟</string>
<string name="MessageSyncQuestion">تم تعديل ملف قاعدة البيانات خارجياً. هل تريد تحميل ودمج التغييرات قبل الحفظ؟ حدد \"لا\" إذا كنت ترغب في الكتابة فوق التغييرات الخارجية.</string>
<string name="SynchronizingDatabase">جاري دمج التغييرات&#8230;</string>
<string name="SynchronizingDatabase">جاري دمج التغييرات</string>
<string name="YesSynchronize">نعم، ادمج التغييرات</string>
<string name="NoOverwrite">لا، اكتب فوق التغييرات</string>
<string name="UseOfflineMode">العمل دون اتصال</string>
<string name="UseOnlineMode">العمل على الإنترنت</string>
<string name="UseOfflineMode_Info">تجنب أي تعامل مع شبكة الاتصال باستخدام نسخة من الملف في ذاكرة التخزين المؤقت المحلية. التغييرات يتم تخزينها في ذاكرة التخزين المؤقت المحلية فقط، وسيتم رفعها فقط عند التبديل إلى وضع الاتصال بالانترنت.</string>
<string name="InOfflineMode">العمل دون اتصال.</string>
<string name="SynchronizingCachedDatabase">جاري مزامنة قاعدة البيانات المخزنة مؤقتاً&#8230;</string>
<string name="DownloadingRemoteFile">جاري تحميل الملف البعيد&#8230;</string>
<string name="UploadingFile">جاري رفع الملف&#8230;</string>
<string name="RestoringRemoteFile">جاري استعادة الملف البعيد&#8230;</string>
<string name="SynchronizingCachedDatabase">جاري مزامنة قاعدة البيانات المخزنة مؤقتاً…</string>
<string name="FilesInSync">الملفات في تزامن.</string>
<string name="SynchronizedDatabaseSuccessfully">تمت مزامنة قاعدة البيانات بنجاح!</string>
<string name="CheckingDatabaseForChanges">جاري التحقق من التغييرات في قاعدة البيانات&#8230;</string>
<string name="CouldNotSaveToRemote">تعذر الحفظ إلى الملف البعيد: %1$s. حاول مرة أخرى أو استخدم قائمة المزامنة عند توفر الاتصال مرة أخرى.</string>
<string name="CouldNotLoadFromRemote">تعذر فتح الملف البعيد: %1$s. تم تحميل الملف من ذاكرة التخزين المؤقت المحلية. لا يزال بإمكانك إجراء تغييرات في قاعدة البيانات ومزامنتها في وقت لاحق.</string>
<string name="UpdatedRemoteFileOnLoad">تم تحديث الملف البعيد.</string>
<string name="NotifyOpenFromLocalDueToConflict">تم فتح الملف المحلي بسبب تعارض مع التغييرات في الملف البعيد. استخدام قائمة المزامنة للدمج.</string>
<string name="LoadedFromRemoteInSync">تمت مزامنة الملف البعيد وذاكرة التخزين المؤقت.</string>
<string name="UpdatedCachedFileOnLoad">تم تحديث نسخة ذاكرة التخزين المؤقت المحلية من %1$s.</string>
<string name="CheckingDatabaseForChanges">جاري التحقق من التغييرات في قاعدة البيانات</string>
<string name="RemoteDatabaseUnchanged">لم يتم اكتشاف أية تغييرات.</string>
<string name="ResolvedCacheConflictByUsingRemoteOtpAux">تم تحديث ملف \"كلمة السر أحادية الاستخدام\" المخزن مؤقتاً: العداد البعيد كان أعلى.</string>
<string name="ResolvedCacheConflictByUsingLocalOtpAux">تم تحديث ملف \"كلمة السر أحادية الاستخدام\" المخزن بعيدًا: العداد المحلي كان أعلى.</string>
<string name="SynchronizingOtpAuxFile">جاري مزامنة ملف \"كلمة السر أحادية الاستخدام\"&#8230;</string>
<string name="SynchronizingOtpAuxFile">جاري مزامنة ملف \"كلمة السر أحادية الاستخدام\"</string>
<string name="database_file">ملف قاعدة البيانات</string>
<string name="otp_aux_file">ملف \"كلمة السر أحادية الاستخدام\"</string>
<string name="ErrorOcurred">حدث خطأ:</string>
<string name="DuplicateUuidsError">قاعدة البيانات معطوبة: تم العثور على معرفات مكررة. (هل قمت بالحفظ بواسطة Minikeepass؟) يرجى إعادة الاستيراد إلى قاعدة بيانات جديدة مع برنامج Keepass2 الخاص بأجهزة سطح المكتب وحدد \'إنشاء معرفات جديدة\'.</string>
<string name="DuplicateUuidsErrorAdditional">يمكنك تعطيل رسالة الخطأ هذه في الإعدادات/إعدادات التطبيق/التعامل مع الملفات/التحقق من المعرفات (UUIDs) المكررة. الرجاء ملاحظة أنه قد يواجهك سلوك غير متوقع. من المستحسن إصلاح قاعدة البيانات.</string>
<string name="synchronize_database_menu">جاري مزامنة قاعدة البيانات&#8230;</string>
<string name="synchronize_database_menu">جاري مزامنة قاعدة البيانات</string>
<string name="CannotMoveGroupHere">لا يمكن نقل المجموعة إلى هذه المجموعة.</string>
<string name="donate_question">اليوم هو مهرجان أكتوبر! إذا أعجبك Keepass2Android ألن يكون اليوم مناسبا لتشتري لي بيرة؟</string>
<string name="donate_bday_question">10 مايو؟ إنه عيد ميلادي! إذا أعجبك هذا التطبيق، لما لا ترسل لي بعض التحايا إلى جانب هدية عيد ميلاد صغيرة؟ هذا سيسعدني كثيرًا! :-)</string>
@@ -450,10 +434,9 @@
<string name="hint_key_file">اختر إذا كنت تريد استخدام ملف المفتاح بالإضافة إلى كلمة المرور الرئيسية:</string>
<string name="use_key_file">استخدم ملف المفتاح</string>
<string name="error_adding_keyfile">حدث خطأ أثناء إضافة ملف المفتاح!</string>
<string name="init_otp">تحميل الملف الخارجي الخاص بكلمة المرور لمرة واحدة OTP&#8230;</string>
<string name="init_otp">تحميل الملف الخارجي الخاص بكلمة المرور لمرة واحدة OTP</string>
<string name="otp_explanation">(12345) emad.</string>
<string name="otp_hint">كلمة مرور مؤقتة %1$d</string>
<string name="YubiChallengeNotInstalled">تعذر العثور على تطبيق يمكنه التعامل مع هذا التحدي. يرجى تثبيت تطبيق يوبيتشالينج Yubichallenge من متجر Google Play.</string>
<string name="CouldntLoadOtpAuxFile">تعذر تحميل الملف الخارجي الخاص ب \"كلمة المرور لمرة واحدة\" OTP!</string>
<string name="CouldntLoadOtpAuxFile_Hint">الرجاء استخدام ألأضافة \"أوتبكييبروف\" OtpKeyProv في KeePass 2.x (نسخة PC) لتمكين قاعدة بياناتك مناستخدام \"كلمة المرور لمرة واحدة\" OTP !</string>
<string name="otp_discarded_because_no_db">الرجاء تحديد قاعدة البيانات أولاً. سيتم تجاهل كلمة المرور لمرة واحدة لدواعي ألأمان.</string>
@@ -464,7 +447,7 @@
<string name="CouldntParseOtpSecret">حدث خطأ أثناء تحليل سر كلمة المرور المؤقتة!</string>
<string name="OtpKeyError">فشل إنشاء مفتاح كلمة المرور المؤقتة! تأكد من إدخالك كلمات المرور الصحيحة.</string>
<string name="ErrorUpdatingOtpAuxFile">خطأ أثناء تحديث الملف الخارجي الخاص بكلمة المرور أحادية الاستخدام!</string>
<string name="SavingOtpAuxFile">جاري حفظ الملف الخارجي الخاص بكلمة المرور أحادية الاستخدام&#8230;</string>
<string name="SavingOtpAuxFile">جاري حفظ الملف الخارجي الخاص بكلمة المرور أحادية الاستخدام</string>
<string name="bad_resp">إجابة السؤال غير صحيحة.</string>
<string name="CouldntLoadChalAuxFile">تعذر تحميل الملف الخارجي الخاص بالسؤال!</string>
<string name="CouldntLoadChalAuxFile_Hint">من فضلك استعمل ملحق KeeChallenge فالنّسخة 2.0 من KeePass للحاسوب، وذلك لإعداد قاعدة البيانات من أجل استعمال نظام تحدّي/استجابة (Challenge-response)!</string>
@@ -474,7 +457,7 @@
<string name="TrayTotp_SettingsField_title">اسم الحقل \"إعدادات TOTP\"</string>
<string name="TrayTotp_SettingsField_summary">أدخل اسمًا لحقل \"إعدادات TrayTotp\" هنا.</string>
<string name="TrayTotp_prefs">TrayTotp</string>
<string name="loading">جاري التحميل&#8230;</string>
<string name="loading">جاري التحميل</string>
<string name="plugins">الإضافات</string>
<string name="plugin_packagename">اسم الحزمة:</string>
<string name="plugin_description">الوصف (لم يتم التأكيد):</string>
@@ -546,6 +529,7 @@
<string name="CorruptDatabaseHelp">
الملف معطوب.\n
هنا هي بعض التلميحات التي قد تساعد على تشخيص المسألة: \n إن قمت بنسخ الملف عبر USB (وضع الخطة المتوسطة الأجل)، الرجاء المحاولة مرة أخرى باستخدام أدوات مثل MyPhoneExplorer. الخطة المتوسطة الأجل تقتطع الملفات في بعض الحالات. \n • إذا تعذر عليك فتح الملف من نفس الموقع على جهاز الكمبيوتر الخاص بك، فمن المحتمل جداً أن الملف معطوب فعلا. الرجاء استخدام نسخة احتياطية من قاعدة البيانات. إذا كنت تفترض أن Keepass2Android قد أتلف الملف، الرجاء الاتصال بالمساعدة. \n • إذا تمكنت من فتح الملف على جهاز الكمبيوتر الخاص بك، الرجاء الاتصال بالمساعدة. يمكنك محاولة حفظه باستخدام إعدادات مختلفة (مثلا، غير مضغوط) على جهاز الكمبيوتر وإعادة محاولة فتحه في Keepass2Android. </string>
<string name="DbQuicklockedChannel_name">QuickUnlock</string>
<string name="ErrorReportTitle">Keepass2Android : حدث خطأ.</string>
<string name="ErrorReportText">حدث خطأ غير متوقع أثناء تشغيل Keepass2Android. الرجاء مساعدتنا في حل هذه المشكلة بالسماح للتطبيق بإرسال التقارير عن الأخطاء.</string>
<string name="ErrorReportPromise">لا تحتوي تقارير الأخطاء أبدا على أي محتويات من قاعدة البيانات الخاصة بك ولا على كلمة السر الرئيسية. يمكنك تعطيلها في إعدادات التطبيق.</string>
@@ -673,6 +657,7 @@
<item>كلمة السر + سر \"كلمة السر أحادية الاستخدام\" (وضع الاسترجاع)</item>
<item>كلمة السر + إجابة السؤال الشخصي</item>
<item>كلمة السر + سر إجابة السؤال الشخصي (وضع الاسترجاع)</item>
<item>Password + Challenge-Response for Keepass XC</item>
</string-array>
<string-array name="AcceptAllServerCertificates_options">
<item>تجاهل فشل التحقق من صحة الشهادة</item>

View File

@@ -307,11 +307,9 @@
<string name="NoDonateOption_summary">Тази настройка е за дарители. Тя е достъпна след използване на Keepass2Android за известно време.</string>
<string name="NoDonateOption_question">Без дарения това приложение не може да съществува и няма да се подобрява непрекъснато! Ако сте все още не сте дарили, моля обмислете да го направите сега.</string>
<string name="UseOfflineCache_title">Кеширане на базатаданни</string>
<string name="UseOfflineCache_summary">Запази копие на отдалечената база данни в кеф папката. Това позволява да се използва отдалечена база данни когато сте офлайн.</string>
<string name="AcceptAllServerCertificates_title">SSL сертификати</string>
<string name="AcceptAllServerCertificates_summary">Дефинирайте поведението когато сертифицирането пропадне. Бел.: вие можете да инсталирате сертификати ако валидирането пропадне!</string>
<string name="ClearOfflineCache_title">Изчисване на кеша?</string>
<string name="ClearOfflineCache_question">Това ще изтрие всички кефирани бази данни. Всички промени докато сте били офлайн които не са синхронизиране ще бъдат изгубени! Продължаване?</string>
<string name="CheckForFileChangesOnSave_title">Провери за промени</string>
<string name="CheckForFileChangesOnSave_summary">Проверява дали файлът е променен външно преди записване на промените.</string>
<string name="CheckForDuplicateUuids_title">Проверка за дублирани UUID</string>
@@ -352,8 +350,6 @@
<string name="MessageSyncQuestion">Файлът на базата данни беше променен външно. Искате ли да заредите и да обедините промените преди записване? Изберете \"не\" ако искате да замените външните промени.</string>
<string name="SynchronizingDatabase">Добавя промените&#8230;</string>
<string name="NoOverwrite">Не, презапиши</string>
<string name="UseOfflineMode">Работа офлайн</string>
<string name="UseOnlineMode">Работа онлайн</string>
<string name="SynchronizedDatabaseSuccessfully">Базата данни е синхронизирана успешно!</string>
<string name="DuplicateUuidsError">Базата данни е повредена: дубликат идентификатори намерени. (Знаете запишете с Minikeepass?) Моля да импортирате отново в нова база данни с Keepass 2 за PC и изберете \"Създай нов ИД\".</string>
<string name="DuplicateUuidsErrorAdditional">Можете да забраните това съобщение за грешка в приложението настройки/настройки/файл обработка/проверка за дублирани UUID. Моля, обърнете внимание, че е възможно да имате неочаквано поведение. Препоръчително е да се определи на базата данни.</string>

View File

@@ -0,0 +1,399 @@
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.com-->
<!--Generated by crowdin.net-->
<resources>
<string name="about_feedback">Отзив</string>
<string name="about_homepage">Уеб страница</string>
<string name="AboutText">Keepass2Android е мениджър за пароли който осигурява достъп четене/записване до KeePass 2.x база данни на Android.</string>
<string name="CreditsText">Потребителският интерфейс е базиран на KeepassDroid създаден от Brian Pellin. Кода действие на базите данни е базиран на KeePass на Dominik Reichl. Робота Android е репродукция или модифициран от разработения и споделен от Google и се използва в съответствие с лиценза Creative Commons 3.0 Attribution License.</string>
<string name="CreditsTextSFTP">SFTP поддръжка се осъществява чрез използване на библиотеката на JSch под BSD лиценз, създаден от JCraft, Inc.</string>
<string name="accept">Приемам</string>
<string name="deny">Отказано</string>
<string name="add_entry">Добавям запис</string>
<string name="edit_entry">Редактиране на запис</string>
<string name="add_url_entry">Създавам запис от страница</string>
<string name="add_group">Добавям група</string>
<string name="add_group_title">Добавям Група</string>
<string name="edit_group_title">Редактирам Група</string>
<string name="algorithm">Алгоритъм</string>
<string name="algorithm_colon">Алгоритъм</string>
<string name="app_name">Keepass2Android</string>
<string name="short_app_name">KP2A</string>
<string name="app_name_nonet">Keepass2Android Офлайн</string>
<string name="short_app_name_nonet">KP2A Офлайн</string>
<string name="app_timeout">Времето за изчакване на приложението изтече</string>
<string name="app_timeout_summary">Време за заключване на базата данни, когато приложение е неактивно.</string>
<string name="kill_app_label">Спиране на процеса на приложението</string>
<string name="show_kill_app">Бутон-Затваряне</string>
<string name="show_kill_app_summary">Покажи бутон за спиране на приложението в екрана за парола (за параноични потребители)</string>
<string name="application">Приложение</string>
<string name="application_settings">Настройки на приложението</string>
<string name="ShowGroupnameInSearchResult_title">Показване на името на групата в резултата от търсенето</string>
<string name="ShowGroupnameInSearchResult_resume">Показване на името на групата под заглавието в резултатите от търсенето. Полезно е, ако няколко записа имат едно и също име.</string>
<string name="NavigationToGroupCompleted_message">Групата за показване е: %1$s</string>
<string name="ShowGroupInEntry_title">Покажи името на групата във вид на запис</string>
<string name="unknown_uri_scheme">Съжалявам! Keepass2Android не може да обработи върнатите URI %1$s. Свържете се с разработчика!</string>
<string name="Entry_singular">Един запис</string>
<string name="Entry_plural">%1$d записи</string>
<string name="IconSet_title">Набор икони</string>
<string name="IconSet_install">Търси още... </string>
<string name="security_prefs">Сигурност</string>
<string name="display_prefs">Покажи</string>
<string name="password_access_prefs">Достъп до въведените пароло</string>
<string name="QuickUnlock_prefs">Бързо отключване</string>
<string name="FileHandling_prefs">Работа с файлове</string>
<string name="keyboard_prefs">Клавиатура</string>
<string name="export_prefs">Експортиране на база данни...</string>
<string name="fingerprint_prefs">Отключване с отпечатък</string>
<string name="import_db_prefs">Импортиране на БД във вътрешна папка</string>
<string name="import_keyfile_prefs">Импортирай ключ от вътрешна папка</string>
<string name="keyboardswitch_prefs">Превключване на клавиатурата</string>
<string name="OnlyAvailableForLocalFiles">Достъпно само за локални файлове.</string>
<string name="FileIsInInternalDirectory">Файлът се съхранява във вътрешна папка</string>
<string name="DatabaseFileMoved">База данни файлът е копиран във вътрешна папка. Натиснете Ok, за да отворите ново местоположение. Забележка: Не забравяйте редовно да експортирате базата данни на безопасно място</string>
<string name="KeyfileMoved">Keyfile е копиран във вътрешна папка. Уверете се, че имате бекъп преди да го изтриете от текущото му място!</string>
<string name="KeyfileMoveRequiresRememberKeyfile">Не можете да използвате вътрешна папка ако key файла не е запомнен. Променете настройките на сигурността.</string>
<string name="unlock_database_button">Отключване</string>
<string name="unlock_database_title">Отключи базата данни</string>
<string name="brackets">Скоби</string>
<string name="cancel">Прекъсни</string>
<string name="ClearClipboard">Клиброда е изчистен.</string>
<string name="clipboard_timeout">Времето за изчакване на клипборда изтече</string>
<string name="clipboard_timeout_summary">Време за изчистване на клипборда преди копиране на потребителско име или парола</string>
<string name="copy_username">Изберете за да копиране потребителското име в клипборда</string>
<string name="copy_password">Изберете за да копирате парола в клипборда</string>
<string name="available_through_keyboard">Въвеждането е възможно чрез KP2A клавиатурата</string>
<string name="entry_is_available">е наличен</string>
<string name="not_possible_im_picker">Невъзможно отваряне на диалог за избиране на метод за въвеждане. Моля активирайте клавиатурата ръчно.</string>
<string name="please_activate_keyboard">Моля активирайте клавиатурата на Keepass2Android във вашата системни настройки.</string>
<string name="creating_db_key">Създаване на ключ на базата данни…</string>
<string name="current_group">Настояща Група</string>
<string name="current_group_root">Настояща Група: Главна</string>
<string name="database">Базаданни</string>
<string name="digits">Цифри</string>
<string name="disclaimer_formal">Keepass2Android е с АБСОЛЮТНО НИКАКВИ ГАРАНЦИИ. Това е свободен софтуер и вие сте свободни да го разпространявате при условията на GPL врсия 2 и по-късни.</string>
<string name="ellipsis">\u2026</string>
<string name="copy_to_clipboard">Копиране в клипборда</string>
<string name="fingerprint_hint">Сензор за докосване</string>
<string name="fingerprint_description">Потвърди отпечатъка за продължение</string>
<string name="fingerprint_fatal">Не може да настрои отключването с отпечатък:</string>
<string name="fingerprint_not_recognized">Не разпознат. Опитайте пак</string>
<string name="fingerprint_success">Разпознат</string>
<string name="fingerprint_os_error">Отпечатъка изисква Android 6.0 или по нов. </string>
<string name="fingerprint_hardware_error">Нямате устройство за отпечатък. </string>
<string name="fingerprint_no_enrolled">Нямате запазени пръстови отпечатъци на това устройство. Моля посетете състемните настройки.</string>
<string name="disable_fingerprint_unlock">Изключи отключването с отпечатък</string>
<string name="enable_fingerprint_unlock">Разреши отключването с отпечатък</string>
<string name="enable_fingerprint_quickunlock">Включи Отключване с Пръстов Отпечатък при Бързо Отключване</string>
<string name="fingerprint_unlock_hint">Докоснете сензора за отключване на базата данни</string>
<string name="fingerprint_reenable">Моля активирайте повторно отключването с пръстов отпечатък за новата главна парола.</string>
<string name="enable_fingerprint_unlock_Info">
Това ще запише вашата главна парола криптирана с Android Keystore и защитена с пръстовия ви отпечатък. Можете да отключите само с вашия отпечатък. </string>
<string name="enable_fingerprint_quickunlock_Info">Позволява да използвате пръстов отпечатък вместо QuickUnlock код. Не изисква да запазва каквато и да е информация свързана с вашата главна парола.</string>
<string name="enter_filename">Въведете име на файла на базаданни</string>
<string name="entry_accessed">Достъп до</string>
<string name="entry_cancel">Прекъсни</string>
<string name="entry_comment">Бележки</string>
<string name="entry_tags">Тагове</string>
<string name="entry_override_url">Замени URL</string>
<string name="entry_confpassword">Потвърди паролата</string>
<string name="entry_created">Създаден</string>
<string name="entry_expires">Изтича</string>
<string name="entry_group_name">Име на група</string>
<string name="entry_keyfile">Ключов файл (незадължителен)</string>
<string name="entry_modified">Модифициран</string>
<string name="entry_password">Парола</string>
<string name="entry_save">Запази</string>
<string name="entry_title">Име</string>
<string name="entry_url">URL</string>
<string name="entry_user_name">Потребителско име</string>
<string name="entry_extra_strings">Допълнителни низ полета</string>
<string name="entry_binaries">Прикачени файлове</string>
<string name="error_can_not_handle_uri">Keepass2Android не може да обработи този uri.</string>
<string name="error_could_not_create_group">Грешка при създаване на група.</string>
<string name="error_could_not_create_parent">Не може да се създаде директория.</string>
<string name="error_database_exists">Този файл вече съществува.</string>
<string name="error_database_settinoverrgs">Не можа да определи настройките на базата данни.</string>
<string name="error_failed_to_launch_link">Неуспешно отваряне на линк.</string>
<string name="error_filename_required">Изисква се име на файл.</string>
<string name="error_file_not_create">Не можа да създаде файл</string>
<string name="error_invalid_db">Невалидна база данни.</string>
<string name="error_invalid_path">Невалиден път.</string>
<string name="error_no_name">Името е задължително.</string>
<string name="error_nopass">Изисква се парола или ключов файл.</string>
<string name="error_pass_gen_type">Трябва да бъде избран поне един вид генератор за парола</string>
<string name="error_pass_match">Паролите не съвпадат.</string>
<string name="error_rounds_not_number">Кръга трябва да бъде число.</string>
<string name="error_param_not_number">Въведения параметър трябва да бъде число.</string>
<string name="error_title_required">Изисква се заглавие.</string>
<string name="error_wrong_length">Въведете положително число в полето \"дължина\"</string>
<string name="FileNotFound">Файлът не е намерен.</string>
<string name="file_browser">Файл браузър</string>
<string name="generate_password">Генериране на парола</string>
<string name="group">Група</string>
<string name="hint_comment">бележки</string>
<string name="hint_conf_pass">Потвърди паролата</string>
<string name="hint_generated_password">генерира парола</string>
<string name="hint_group_name">Име на група</string>
<string name="hint_keyfile">Ключов файл</string>
<string name="hint_length">Дължина</string>
<string name="hint_pass">парола</string>
<string name="hint_login_pass">Парола</string>
<string name="hint_title">Име</string>
<string name="hint_url">url</string>
<string name="hint_override_url">замени url</string>
<string name="hint_tags">таг1, таг2</string>
<string name="hint_username">потребителско име</string>
<string name="InvalidPassword">Невалидна парола или ключов файл.</string>
<string name="invalid_algorithm">Невалиден алгоритъм.</string>
<string name="invalid_db_sig">Формат на базата данни не се разпознава.</string>
<string name="keyfile_does_not_exist">Файла на ключа не съществува.</string>
<string name="no_keyfile_selected">Няма избран ключов файл.</string>
<string name="keyfile_is_empty">Файла с ключа е празен.</string>
<string name="length">Дължина</string>
<string name="list_size_title">Размер на груповия списък</string>
<string name="list_size_summary">Размер на текстра в груповия списък</string>
<string name="loading_database">Зареждане на базата данни…</string>
<string name="lowercase">Малки букви</string>
<string name="MaskedPassword">*****</string>
<string name="maskpass_title">Маска за паролата</string>
<string name="maskpass_summary">Скрий паролите по подразбиране</string>
<string name="menu_about">За</string>
<string name="menu_change_key">Смяна на главния ключ</string>
<string name="menu_copy_pass">Копирай парола</string>
<string name="menu_copy_user">Копирай потребителско име</string>
<string name="menu_create">Създай</string>
<string name="menu_app_settings">Настройки</string>
<string name="menu_db_settings">Настройка на базата данни</string>
<string name="menu_delete">Изтриване</string>
<string name="menu_copy">Създаване на дубликат</string>
<string name="menu_move">Премести в друга група</string>
<string name="menu_move_light">Премести</string>
<string name="menu_navigate">Отиди в родителската група</string>
<string name="menu_donate">Дарете бира...</string>
<string name="menu_edit">Редактиране</string>
<string name="menu_hide_password">Скрий парола</string>
<string name="menu_lock">Заключи базата данни</string>
<string name="menu_open">Отвори</string>
<string name="menu_close">Затвори</string>
<string name="menu_rename">Преименувай</string>
<string name="menu_search">Търсене</string>
<string name="menu_search_advanced">Сложно търсене</string>
<string name="menu_url">Отиди на страницата</string>
<string name="menu_change_db">Смени базата данни…</string>
<string name="menu_show_all">Покажи всички полета</string>
<string name="minus">Минус</string>
<string name="never">Никога</string>
<string name="yes">Да</string>
<string name="no">Не</string>
<string name="no_keys">Няма въведени записи в базата данни или групата.</string>
<string name="no_results">Търсенето не даде резултати</string>
<string name="no_url_handler">Няма доставчик за тази страница.</string>
<string name="open_recent">Отвори последната база данни (кликни за да се отвори)</string>
<string name="omitbackup_title">Не търси в бекъпа и кошчето</string>
<string name="omitbackup_summary">Пропусни \'Backup\' и Recycle Bin групите от търсенето</string>
<string name="pass_filename">Име на KeePass файл за базата данни</string>
<string name="password_title">Въведете паролата на базата данни</string>
<string name="master_key_type">Изберете вид на главния ключ:</string>
<string name="progress_create">Създаване на нова база данни…</string>
<string name="create_database">Създаване на база данни</string>
<string name="progress_title">В процес на работа…</string>
<string name="remember_keyfile_summary">Запомни пътя до ключовия файл</string>
<string name="remember_keyfile_title">Запази ключов файл</string>
<string name="remove_from_filelist">Премахване</string>
<string name="edit">Редактиране</string>
<string name="rijndael">Rijndael (AES)</string>
<string name="root">Главен</string>
<string name="rounds">Шифрован кръг</string>
<string name="rounds_explaination">По-високо криптиране на кръга осигурява допълнителна защита срещу атаки с груба сила, но може да забави зареждането и записването.</string>
<string name="database_name">Име на базата данни</string>
<string name="default_username"> Потребителско име по подразбиране за нови записи</string>
<string name="saving_database">Записване на база данни...</string>
<string name="exporting_database">Експортиране на база данни...</string>
<string name="export_database_successful">Базата данни е експортирана!</string>
<string name="space">Пространство</string>
<string name="search_label">Търсене</string>
<string name="show_password">Покажи паролата</string>
<string name="sort_menu">Сортирай по...</string>
<string name="sort_name">Сортиране по име</string>
<string name="sort_db">Сортирай по дата на създаване</string>
<string name="sort_moddate">Сортирай по дата на модификация</string>
<string name="sort_default">Запази ред по подразбиране</string>
<string name="special">Специални</string>
<string name="search_hint">Търси</string>
<string name="search_results">Резултати от търсенето</string>
<string name="search_in">Търсене в</string>
<string name="select_other_entry">Изберете друг запис</string>
<string name="select_group_then_add">Отворете желаната група, след което натиснете \"%1$s\"!</string>
<string name="insert_element_here">Вмъкни тук</string>
<string name="twofish">Twofish</string>
<string name="underline">Подчертаване</string>
<string name="unsupported_db_version">Неподдържана версия на базата данни.</string>
<string name="uppercase">Главни букви</string>
<string name="warning_read_only">Sd картата е само за четене. Може да не успеете да запазите промените във вашата база данни.</string>
<string name="warning_unmounted">Sd картата не е монтирана в момента на вашето устройство. Вие няма да можете да заредите или да създадете вашата база данни.</string>
<string name="version_label">Версия</string>
<string name="version_history">Хронология на версиите</string>
<string name="author">Keepass2Android е разработена от Philipp Crocoll.</string>
<string name="further_authors">Благодарение на девелопера %1$s.</string>
<string name="designers">Благодарение на иконата и оформлението дизайн вноски от %1$s.</string>
<string name="credit_plugin1">Twofish шифър плъгина за Keepass е разработен от Скот Грийнбърг и е включен в KP2A.</string>
<string name="credit_android_filechooser">Android-filechooser е разработена от Хай бизони</string>
<string name="credit_keyboard">KP2A клавиатурата се основава на Gingerbread клавиатурата от андроида отворен източник на проект и използва плъгин мениджър кода от клавиатурата на хакер от Клаус Weidner.</string>
<string name="please_note">Моля, обърнете внимание</string>
<string name="contributors">Сътрудници</string>
<string name="regular_expression">Регулярен израз</string>
<string name="TanExpiresOnUse_title">Тан изтича на използване</string>
<string name="TanExpiresOnUse_summary">Отбележи TAN записите с изтекъл срок при използването им</string>
<string name="ShowUsernameInList_title">Показвано име в списъка</string>
<string name="ShowUsernameInList_summary">Показване на потребителските имена под заглавията. Полезно за няколко сметки или TAN-а</string>
<string name="RememberRecentFiles_title">Запомни базите данни</string>
<string name="RememberRecentFiles_summary">Запомни последно отваряните бази данни ги показвай в екрана на отворената база данни.</string>
<string name="kp2a_findUrl">Keepass2Android: Намери парола</string>
<string name="excludeExpiredEntries">Изключи изтеклите записи</string>
<string name="search_options">Опции</string>
<string name="caseSensitive">Има разлика за голям-малък шрифт</string>
<string name="start_open_file">Отваряне на файл...</string>
<string name="start_create">Създаване на нова база данни...</string>
<string name="start_open_url">Отваряне на URL...</string>
<string name="start_create_import">Импортира файл в нова база данни</string>
<string name="enter_filename_details_url">Пълен URL адрес трябва да се зададе, включително протокол като http://.</string>
<string name="enter_filename_details_create_import">Файла за импортиране ще бъде избран в следващата стъпка.</string>
<string name="enable_quickunlock">Включете опцията \"Бързо отключване\"</string>
<string name="QuickUnlock_label">Въведете последните %1$d символа от вашата парола:</string>
<string name="QuickUnlock_button">Бързо отключване!</string>
<string name="QuickUnlock_lockButton">Затвори базата данни</string>
<string name="QuickUnlockDefaultEnabled_title">Включи Бързо отключване по подразбиране</string>
<string name="QuickUnlockDefaultEnabled_summary">Определя дали Бързо отключване е включено по подразбиране или не.</string>
<string name="ViewDatabaseSecure_title">Защити показването на базата данни</string>
<string name="ViewDatabaseSecure_summary">Ако е включено, снимките на екрана са блокирани и превюто на програмата не се показва в текущите работещи приложения</string>
<string name="QuickUnlockIconHidden_title">Скрий иконата за Бързо отключване</string>
<string name="QuickUnlockIconHidden_summary">Бързо отключване за съжаление не работи без да се показва нотификационна икона. Изберете тази опция за да използвате прозрачна икона.</string>
<string name="QuickUnlockIconHidden16_title">Скрий иконата за Бързо отключване</string>
<string name="QuickUnlockIconHidden16_summary">QuickUnlock изисква уведомяване за да работи правилно. Изберете тази опция за показване на уведомление без икона.</string>
<string name="QuickUnlockLength_title">Дължина на ключа за Бързо отключване</string>
<string name="QuickUnlockLength_summary">Максимален брой знаци използвани като парола за Бързо отключване.</string>
<string name="QuickUnlock_fail">Бързо отключване НЕУСПЕШНО: невярна парола!</string>
<string name="BinaryDirectory_title">Папка с приложени файлове</string>
<string name="BinaryDirectory_summary">Папка където се записват приложените файлове.</string>
<string name="SaveAttachmentDialog_title">Запази приложен файл</string>
<string name="SaveAttachmentDialog_text">Моля изберете къде да се запише приложения файл.</string>
<string name="SaveAttachmentDialog_save">Запази в SD картата</string>
<string name="SaveAttachmentDialog_open">Запази в кеша и отвори</string>
<string name="SaveAttachment_doneMessage">Файла е запазен в %1$s.</string>
<string name="SaveAttachment_Failed">Не може да запази приложения файл в %1$s.</string>
<string name="AddUrlToEntryDialog_title">Запомни текста за търсене?</string>
<string name="AddUrlToEntryDialog_text">Искате ли да съхраните търсения текст \"%1$s\" в избрания запис, за да го намерите автоматично следващия път?</string>
<string name="error_invalid_expiry_date">Невалиден формат за дата/време за изтекла дата!</string>
<string name="error_string_key">Име на полето е задължително за всеки стринг.</string>
<string name="field_name">Име на полето</string>
<string name="field_value">Съдържание на полето</string>
<string name="protection">Защитено поле</string>
<string name="add_binary">Добави приложен файл...</string>
<string name="add_extra_string">Въведи допълнителен стринг</string>
<string name="delete_extra_string">Изтрий допълнителен стринг</string>
<string name="database_loaded_quickunlock_enabled">%1$s: Заключена. Бързо отключване е включено.</string>
<string name="database_loaded_unlocked">%1$s: Отключена.</string>
<string name="credentials_dialog_title">Въведете потребителско име и парола за връзка със сървъра</string>
<string name="UseFileTransactions_title">Транзакция на файлове</string>
<string name="UseFileTransactions_summary">Използвай тракзакция на файлове за записване на бази данни</string>
<string name="LockWhenScreenOff_title">Заключи когато изкл.екрана</string>
<string name="LockWhenScreenOff_summary">Заключи базата данни когато се изкл.екрана.</string>
<string name="ClearPasswordOnLeave_title">Изчиства въведената главна парола</string>
<string name="ClearPasswordOnLeave_summary">Изчиства въведената главна парола ако напуснете екрана без отключване на базата данни</string>
<string name="LockWhenNavigateBack_title">Заключване при излизане от приложението</string>
<string name="LockWhenNavigateBack_summary">Заключване на базата данни при излизане от приложението чрез натискане на бутона за връщане назад.</string>
<string name="NoDonateOption_title">Скрий опцията за дарения</string>
<string name="NoDonateOption_summary">Тази настройка е за дарители. Тя е достъпна след използване на Keepass2Android за известно време.</string>
<string name="NoDonateOption_question">Без дарения това приложение не може да съществува и няма да се подобрява непрекъснато! Ако сте все още не сте дарили, моля обмислете да го направите сега.</string>
<string name="UseOfflineCache_title">Кеширане на базатаданни</string>
<string name="AcceptAllServerCertificates_title">SSL сертификати</string>
<string name="AcceptAllServerCertificates_summary">Дефинирайте поведението когато сертифицирането пропадне. Бел.: вие можете да инсталирате сертификати ако валидирането пропадне!</string>
<string name="ClearOfflineCache_title">Изчисване на кеша?</string>
<string name="CheckForFileChangesOnSave_title">Провери за промени</string>
<string name="CheckForFileChangesOnSave_summary">Проверява дали файлът е променен външно преди записване на промените.</string>
<string name="CheckForDuplicateUuids_title">Проверка за дублирани UUID</string>
<string name="CheckForDuplicateUuids_summary">Проверете дали файлът на базата данни е повреден от наличието на множество записи със същия ИД. Това може да доведе до неочаквано поведение.</string>
<string name="ShowCopyToClipboardNotification_title">Уведомления от клипборда</string>
<string name="ShowCopyToClipboardNotification_summary">Направи достъпни чрез лентата за уведомление и клипборда потребителското име и парола. Пазете се прехващачи на пароли!</string>
<string name="ShowSeparateNotifications_title">Отделни уведомления</string>
<string name="ShowSeparateNotifications_summary">Показвай отделни съобщения за копиране на потребителско име и парола към clipboard и активиране от клавиатурата.</string>
<string name="OpenKp2aKeyboardAutomatically_title">Превключване на клавиатурата</string>
<string name="OpenKp2aKeyboardAutomatically_summary">Отвори диалог за избор на клавиатура когато стойност е налична през KP2A клавиатура след търсене от браузъра.</string>
<string name="OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_title">Автоматично превключване само след търсене</string>
<string name="ShowUnlockedNotification_summary">Показвай иконка за уведомяване когато базата данни е отключена.</string>
<string name="PreloadDatabaseEnabled_title">Презарежда файла с базата данни</string>
<string name="AskOverwriteBinary_yes">Презаписване</string>
<string name="AskOverwriteBinary_no">Преименувай</string>
<string name="AttachFailed">Неуспешно добавяне на прикачен файл.</string>
<string name="RecycleBin">Кошче</string>
<string name="AskDeletePermanentlyEntry">Искате ли да изтриете този елемент окончателно? Натиснете не за рециклиране.</string>
<string name="AskDeletePermanentlyGroup">Искате ли да изтриете този елемент окончателно? Натиснете не за рециклиране.</string>
<string name="AskDeletePermanentlyItems">Искате ли да изтриете избрания елемент завинаги? Натиснете Не за възстановяване.</string>
<string name="AskDeletePermanentlyEntryNoRecycle">Искате ли да изтриете избрания елемент завинаги?</string>
<string name="AskDeletePermanentlyGroupNoRecycle">Искате ли да изтриете тази група завинаги?</string>
<string name="AskDeletePermanently_title">Изтриване завинаги?</string>
<string name="AskReloadFile_title">Презареди файла?</string>
<string name="AskReloadFile">Файла който е отворен в момента е променен от друга програма. Искате ли да го презареди?</string>
<string name="AskDiscardChanges_title">Отхвърляне на промените?</string>
<string name="rate_app">Оценете това приложение</string>
<string name="translate_app">Превод на KP2A</string>
<string name="AddingEntry">Добавяне на запис…</string>
<string name="AddingGroup">Добавяне на група…</string>
<string name="DeletingEntry">Изтриване на запис…</string>
<string name="DeletingGroup">Изтриване на група…</string>
<string name="DeletingItems">Изтриване на елементи…</string>
<string name="SettingPassword">Задаване на парола…</string>
<string name="UndoingChanges">Отмяна на промените…</string>
<string name="DecodingDatabase">Декодиране на базата данни…</string>
<string name="TitleSyncQuestion">Обедини и съхрани промените?</string>
<string name="MessageSyncQuestion">Файлът на базата данни беше променен външно. Искате ли да заредите и да обедините промените преди записване? Изберете \"не\" ако искате да замените външните промени.</string>
<string name="SynchronizingDatabase">Добавя промените…</string>
<string name="NoOverwrite">Не, презапиши</string>
<string name="SynchronizedDatabaseSuccessfully">Базата данни е синхронизирана успешно!</string>
<string name="DuplicateUuidsError">Базата данни е повредена: дубликат идентификатори намерени. (Знаете запишете с Minikeepass?) Моля да импортирате отново в нова база данни с Keepass 2 за PC и изберете \"Създай нов ИД\".</string>
<string name="DuplicateUuidsErrorAdditional">Можете да забраните това съобщение за грешка в приложението настройки/настройки/файл обработка/проверка за дублирани UUID. Моля, обърнете внимание, че е възможно да имате неочаквано поведение. Препоръчително е да се определи на базата данни.</string>
<string name="synchronize_database_menu">Синхронизиране на базата данни...</string>
<string name="CannotMoveGroupHere">Може да преместите група към тази група.</string>
<string name="donate_question">Днес тя е Октоберфест! Ако ви харесва Keepass2Android: днес няма да бъде един добър ден да ми купи една бира?</string>
<string name="donate_bday_question">10 май? Това е моят рожден ден! Ако ви харесва този ап, защо не ми изпратите някои рожден ден Поздрави заедно с малък подарък за рождения ден? Това наистина ще ме направи щастлив! :-)</string>
<string name="donate_missedbday_question">О ти пропусна моя рожден ден на 10 май! Ако ви харесва този ап, защо не да ми изпратите някои рожден ден поздравления и малко подарък? Все още не е твърде късно, за да ме направи щастлив! :-)</string>
<string name="ok_donate">Кажи ми повече!</string>
<string name="no_thanks">Не, не ми харесва толкова много</string>
<string name="hint_sftp_host">host (ex: 192.168.0.1)</string>
<string name="hint_sftp_port">порт</string>
<string name="initial_directory">Начална директория (по избор):</string>
<string name="enter_sftp_login_title">Въведете SFTP входните данни:</string>
<string name="select_storage_type">Изберете типа на съхранение:</string>
<string name="filestoragename_file">Локален файл</string>
<string name="filestoragename_androidget">Получи от трети партия app</string>
<string name="filestoragename_androidsend">Изпрати на трети партия app</string>
<string name="filestoragename_ftp">FTP</string>
<string name="filestoragename_http">HTTP (WebDav)</string>
<string name="filestoragename_https">HTTPS (WebDav)</string>
<string name="filestoragename_dropbox">Dropbox</string>
<string name="filestoragename_dropboxKP2A">Dropbox (KP2A папка)</string>
<string name="filestoragehelp_dropboxKP2A">Ако не искате да дадете KP2A достъп до пълен живея, можете да изберете тази опция. Тя ще поиска достъп само до папката приложения/Keepass2Android. Това е особено подходящ, когато създавате нова база данни. Ако вече имате база данни, щракнете върху тази опция, за да създаде папката, след което поставете вашия файл в папката (от вашия компютър) и след това изберете тази опция отново за отваряне на файла.</string>
<string name="filestoragename_gdrive">Google Drive</string>
<string name="filestoragename_sftp">SFTP (SSH прехвърляне на файлове)</string>
<string name="filestorage_setup_title">Файла достъп инициализация</string>
<string name="database_location">Database местоположение</string>
<string name="help_database_location">Можете да съхранявате вашата база данни локално на вашето устройство Android или в облака (не офлайн версия само). Keepass2Android предоставя базата данни, дори ако сте офлайн. Тъй като базата данни е сигурно криптирани с AES 256 bit криптиране, никой няма да може да получите достъп до паролите ви освен вас. Препоръчваме да изберете Dropbox: тя е достъпна на всичките ви устройства и дори дава гръб на предишни версии на файлове.</string>
<string name="hint_database_location">Изберете къде искате да съхранявате в базата данни:</string>
<string name="button_change_location">Промяна на местоположението</string>
<string name="master_password">Главна парола</string>
<string name="help_master_password">Вашата база данни е шифрована с парола, въведете тук. Изберете сигурна парола за да се запази базата данни безопасно! Съвет: Съставляват едно изречение или две и въведете първите букви на думите като парола. Включете препинателни знаци.</string>
<string name="loading">Зареждане…</string>
<string name="TemplateField_IdCard_Name">Име</string>
<string name="DbQuicklockedChannel_name">Бързо отключване</string>
<string-array name="clipboard_timeout_options">
<item>30 seconds</item>
<item>1 minute</item>
<item>5 minutes</item>
<item>10 minutes</item>
<item>15 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>Никога</item>
</string-array>
</resources>

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