diff --git a/src/java/JavaFileStorage/app/src/main/AndroidManifest.xml b/src/java/JavaFileStorage/app/src/main/AndroidManifest.xml
index 048d89e2..d3e90d8a 100644
--- a/src/java/JavaFileStorage/app/src/main/AndroidManifest.xml
+++ b/src/java/JavaFileStorage/app/src/main/AndroidManifest.xml
@@ -6,7 +6,7 @@
android:versionName="1.0">
diff --git a/src/keepass2android/Resources/values/strings.xml b/src/keepass2android/Resources/values/strings.xml
index ee03fa6f..68c54d79 100644
--- a/src/keepass2android/Resources/values/strings.xml
+++ b/src/keepass2android/Resources/values/strings.xml
@@ -56,6 +56,7 @@
Biometric unlock
Import database to internal folder
Import key file to internal folder
+ Export key file from internal folder
Keyboard switching
Only available for local files.
File is stored in internal directory.
@@ -248,8 +249,10 @@
Saving database…
Exporting database…
Database exported successfully!
-
- Space
+ Key file exported successfully!
+
+
+ Space
Search
Show password
Sort by...
@@ -784,6 +787,7 @@
+ - Updated Jsch to version 0.1.55
- No longer storing package names of Android apps in the URL field
- Improve locking behavior - no longer displaying biometric prompt immediately after unlocking
- Update OkHttp to support HTTP/2
diff --git a/src/keepass2android/Resources/xml/preferences.xml b/src/keepass2android/Resources/xml/preferences.xml
index d37b08ca..7fd360c4 100644
--- a/src/keepass2android/Resources/xml/preferences.xml
+++ b/src/keepass2android/Resources/xml/preferences.xml
@@ -128,10 +128,16 @@
android:key="import_keyfile_prefs"
android:title="@string/import_keyfile_prefs"
/>
-
-
-
-
+
+
+
+
+
+
+
{ ExportKeyfileFromInternalFolder(); };
+ importKeyfile.Summary = GetString(Resource.String.FileIsInInternalDirectory);
}
else
{
- importDb.Enabled = true;
- importDb.PreferenceClick += (sender, args) => { MoveKeyfileToInternalFolder(); };
+ exportKeyfile.Enabled = false;
+ importKeyfile.Enabled = true;
+ importKeyfile.PreferenceClick += (sender, args) => { MoveKeyfileToInternalFolder(); };
}
}
else
{
- importDb.Enabled = false;
+ exportKeyfile.Enabled = false;
+ importKeyfile.Enabled = false;
}
}
+
+
+ private void ExportKeyfileFromInternalFolder()
+ {
+ StartActivity(new Intent(Activity.ApplicationContext, typeof(ExportKeyfileActivity)));
+
+ }
+
private void MoveKeyfileToInternalFolder()
{
Func copyAndReturnPostExecute = () =>
diff --git a/src/keepass2android/settings/ExportKeyfileActivity.cs b/src/keepass2android/settings/ExportKeyfileActivity.cs
new file mode 100644
index 00000000..e185d588
--- /dev/null
+++ b/src/keepass2android/settings/ExportKeyfileActivity.cs
@@ -0,0 +1,113 @@
+using System;
+using Android.App;
+using Android.Content;
+using Android.Widget;
+using keepass2android.Io;
+using KeePassLib.Keys;
+using KeePassLib.Serialization;
+
+namespace keepass2android
+{
+ [Activity]
+ public class ExportKeyfileActivity : LockCloseActivity
+ {
+
+ public class ExportKeyfile : RunnableOnFinish
+ {
+ private readonly IKp2aApp _app;
+ private IOConnectionInfo _targetIoc;
+
+ public ExportKeyfile(Activity activity, IKp2aApp app, OnFinish onFinish, IOConnectionInfo targetIoc) : base(
+ activity, onFinish)
+ {
+ _app = app;
+ _targetIoc = targetIoc;
+ }
+
+ public override void Run()
+ {
+ StatusLogger.UpdateMessage(UiStringKey.exporting_database);
+
+ try
+ {
+ var fileStorage = _app.GetFileStorage(_targetIoc);
+ if (fileStorage is IOfflineSwitchable)
+ {
+ ((IOfflineSwitchable) fileStorage).IsOffline = false;
+ }
+
+ CompositeKey masterKey = App.Kp2a.CurrentDb.KpDatabase.MasterKey;
+ var sourceIoc = ((KcpKeyFile) masterKey.GetUserKey(typeof(KcpKeyFile))).Ioc;
+
+ IoUtil.Copy(_targetIoc, sourceIoc, App.Kp2a);
+
+ if (fileStorage is IOfflineSwitchable)
+ {
+ ((IOfflineSwitchable) fileStorage).IsOffline = App.Kp2a.OfflineMode;
+ }
+
+ Finish(true);
+
+
+ }
+ catch (Exception ex)
+ {
+ Finish(false, ex.Message);
+ }
+
+
+ }
+ }
+
+
+ public class ExportKeyfileProcessManager : FileSaveProcessManager
+ {
+ public ExportKeyfileProcessManager(int requestCode, Activity activity) : base(requestCode, activity)
+ {
+
+ }
+
+ protected override void SaveFile(IOConnectionInfo ioc)
+ {
+ var exportKeyfile = new ExportKeyfile(_activity, App.Kp2a, new ActionOnFinish(_activity,
+ (success, message, activity) =>
+ {
+ if (!success)
+ Toast.MakeText(activity, message, ToastLength.Long).Show();
+ else
+ Toast.MakeText(activity, _activity.GetString(Resource.String.export_keyfile_successful),
+ ToastLength.Long).Show();
+ activity.Finish();
+ }
+ ), ioc);
+ ProgressTask pt = new ProgressTask(App.Kp2a, _activity, exportKeyfile);
+ pt.Run();
+
+ }
+ }
+
+ private ExportKeyfileProcessManager _exportKeyfileProcessManager;
+
+
+ protected override void OnCreate(Android.OS.Bundle savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+ _exportKeyfileProcessManager = new ExportKeyfileProcessManager(0, this);
+ _exportKeyfileProcessManager.StartProcess();
+
+ }
+
+ protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
+ {
+ base.OnActivityResult(requestCode, resultCode, data);
+
+ if (_exportKeyfileProcessManager?.OnActivityResult(requestCode, resultCode, data) == true)
+ return;
+
+ Finish();
+
+ }
+
+
+ }
+}
\ No newline at end of file