From f613206daba494b7857cc9fd8bc826afcff12528 Mon Sep 17 00:00:00 2001 From: Philipp Crocoll Date: Wed, 14 May 2014 07:23:31 +0200 Subject: [PATCH] Plugins: transferring list of protected fields CreateDatabaseActivity: Passing app task to next activity Keepass.cs: added documentation on Activities and AppTasks SearchActivity.cs: passing appTask to next activity, using ForwardResult to pass ActivityResult back to previous activity FileSelectActivity: pass AppTask to CreateDatabaseActivity, Recreate instead of Start+Finish (to have correct handling of ActivityResults) --- src/Kp2aUnitTests/Kp2aUnitTests.csproj | 2 + src/Kp2aUnitTests/MainActivity.cs | 3 +- src/PluginHostTest/PluginHost.cs | 5 + .../PluginActionBroadcastReceiver.java | 28 ++++++ .../keepass2android/pluginsdk/Strings.java | 6 ++ src/keepass2android/CreateDatabaseActivity.cs | 7 +- src/keepass2android/GroupBaseActivity.cs | 62 ++++++------ src/keepass2android/KeePass.cs | 33 +++++++ src/keepass2android/LockCloseActivity.cs | 8 +- src/keepass2android/LockCloseListActivity.cs | 8 +- .../Resources/Resource.designer.cs | 5 +- src/keepass2android/ShareUrlResults.cs | 26 +---- src/keepass2android/Utils/Util.cs | 8 +- src/keepass2android/app/App.cs | 8 +- src/keepass2android/app/AppTask.cs | 95 +++++++++++++++++-- .../fileselect/FileSelectActivity.cs | 16 ++-- src/keepass2android/keepass2android.csproj | 3 + src/keepass2android/search/SearchActivity.cs | 10 +- .../services/CopyToClipboardService.cs | 2 +- 19 files changed, 246 insertions(+), 89 deletions(-) diff --git a/src/Kp2aUnitTests/Kp2aUnitTests.csproj b/src/Kp2aUnitTests/Kp2aUnitTests.csproj index 8b55a936..90ff6b5d 100644 --- a/src/Kp2aUnitTests/Kp2aUnitTests.csproj +++ b/src/Kp2aUnitTests/Kp2aUnitTests.csproj @@ -67,6 +67,7 @@ + @@ -85,6 +86,7 @@ + diff --git a/src/Kp2aUnitTests/MainActivity.cs b/src/Kp2aUnitTests/MainActivity.cs index 5636946b..71c1c621 100644 --- a/src/Kp2aUnitTests/MainActivity.cs +++ b/src/Kp2aUnitTests/MainActivity.cs @@ -18,7 +18,8 @@ namespace Kp2aUnitTests { TestRunner runner = new TestRunner(); // Run all tests from this assembly - runner.AddTests(Assembly.GetExecutingAssembly()); + //runner.AddTests(Assembly.GetExecutingAssembly()); + runner.AddTests(new List { typeof(TestIntentsAndBundles) }); //runner.AddTests(new List { typeof(TestSynchronizeCachedDatabase)}); //runner.AddTests(typeof(TestLoadDb).GetMethod("LoadErrorWithCertificateTrustFailure")); //runner.AddTests(typeof(TestLoadDb).GetMethod("LoadWithAcceptedCertificateTrustFailure")); diff --git a/src/PluginHostTest/PluginHost.cs b/src/PluginHostTest/PluginHost.cs index db072fb2..99a749f4 100644 --- a/src/PluginHostTest/PluginHost.cs +++ b/src/PluginHostTest/PluginHost.cs @@ -152,10 +152,15 @@ namespace keepass2android //add the output string array (placeholders replaced taking into account the db context) Dictionary outputFields = entry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key), pair => pair.Value.ReadString()); + //add field values as JSON ({ "key":"value", ... } form) JSONObject json = new JSONObject(outputFields); var jsonStr = json.ToString(); intent.PutExtra(Strings.ExtraEntryOutputData, jsonStr); + //add list of which fields are protected (StringArrayExtra) + string[] protectedFieldsList = entry.OutputStrings.Where(s=>s.Value.IsProtected).Select(s => s.Key).ToArray(); + intent.PutExtra(Strings.ExtraProtectedFieldsList, protectedFieldsList); + intent.PutExtra(Strings.ExtraEntryId, entry.Uuid.ToHexString()); } diff --git a/src/java/Keepass2AndroidPluginSDK/src/keepass2android/pluginsdk/PluginActionBroadcastReceiver.java b/src/java/Keepass2AndroidPluginSDK/src/keepass2android/pluginsdk/PluginActionBroadcastReceiver.java index 47dd3d6b..8631ad97 100644 --- a/src/java/Keepass2AndroidPluginSDK/src/keepass2android/pluginsdk/PluginActionBroadcastReceiver.java +++ b/src/java/Keepass2AndroidPluginSDK/src/keepass2android/pluginsdk/PluginActionBroadcastReceiver.java @@ -52,6 +52,12 @@ public abstract class PluginActionBroadcastReceiver extends BroadcastReceiver { } return res; } + + protected String[] getProtectedFieldsListFromIntent() + { + return _intent.getStringArrayExtra(Strings.EXTRA_PROTECTED_FIELDS_LIST); + } + } protected class ActionSelected extends PluginActionBase @@ -89,10 +95,23 @@ public abstract class PluginActionBroadcastReceiver extends BroadcastReceiver { return getFieldId() == null; } + /** + * + * @return a hashmap containing the entry fields in key/value form + */ public HashMap getEntryFields() { return getEntryFieldsFromIntent(); } + + /** + * + * @return an array with the keys of all protected fields in the entry + */ + public String[] getProtectedFieldsList() + { + return getProtectedFieldsListFromIntent(); + } } protected class CloseEntryView extends PluginActionBase @@ -125,6 +144,15 @@ public abstract class PluginActionBroadcastReceiver extends BroadcastReceiver { return getEntryFieldsFromIntent(); } + /** + * + * @return an array with the keys of all protected fields in the entry + */ + public String[] getProtectedFieldsList() + { + return getProtectedFieldsListFromIntent(); + } + public void addEntryAction(String actionDisplayText, int actionIconResourceId, Bundle actionData) throws PluginAccessException { addEntryFieldAction(null, null, actionDisplayText, actionIconResourceId, actionData); diff --git a/src/java/Keepass2AndroidPluginSDK/src/keepass2android/pluginsdk/Strings.java b/src/java/Keepass2AndroidPluginSDK/src/keepass2android/pluginsdk/Strings.java index 0392b438..ffacf590 100644 --- a/src/java/Keepass2AndroidPluginSDK/src/keepass2android/pluginsdk/Strings.java +++ b/src/java/Keepass2AndroidPluginSDK/src/keepass2android/pluginsdk/Strings.java @@ -88,6 +88,12 @@ public class Strings { */ public static final String EXTRA_ENTRY_OUTPUT_DATA = "keepass2android.EXTRA_ENTRY_OUTPUT_DATA"; + /** + * Json serialized lisf of field keys, specifying which field of the EXTRA_ENTRY_OUTPUT_DATA is protected. + */ + public static final String EXTRA_PROTECTED_FIELDS_LIST = "keepass2android.EXTRA_PROTECTED_FIELDS_LIST"; + + /** * Extra key for passing the access token (both ways) */ diff --git a/src/keepass2android/CreateDatabaseActivity.cs b/src/keepass2android/CreateDatabaseActivity.cs index 90525979..8383d044 100644 --- a/src/keepass2android/CreateDatabaseActivity.cs +++ b/src/keepass2android/CreateDatabaseActivity.cs @@ -27,7 +27,8 @@ namespace keepass2android private bool _restoringInstanceState; private bool _showPassword; - private ActivityDesign _design; + private readonly ActivityDesign _design; + private AppTask _appTask; public CreateDatabaseActivity() { @@ -57,7 +58,7 @@ namespace keepass2android _design.ApplyTheme(); SetContentView(Resource.Layout.create_database); - + _appTask = AppTask.GetTaskInOnCreate(bundle, Intent); SetDefaultIoc(); @@ -527,7 +528,7 @@ namespace keepass2android dbHelper.CreateFile(_ioc, Filename); } - GroupActivity.Launch(_activity, new NullTask()); + GroupActivity.Launch(_activity, _activity._appTask); _activity.Finish(); } diff --git a/src/keepass2android/GroupBaseActivity.cs b/src/keepass2android/GroupBaseActivity.cs index 9721e1d8..6e514659 100644 --- a/src/keepass2android/GroupBaseActivity.cs +++ b/src/keepass2android/GroupBaseActivity.cs @@ -127,7 +127,9 @@ namespace keepass2android public override bool OnSearchRequested() { - StartActivityForResult(typeof(SearchActivity), 0); + Intent i = new Intent(this, typeof(SearchActivity)); + AppTask.ToIntent(i); + StartActivityForResult(i, 0); return true; } @@ -214,35 +216,9 @@ namespace keepass2android titleText = GetText(Resource.String.root); } - //see if the button for SDK Version < 11 is there - Button tv = (Button)FindViewById(Resource.Id.group_name); - if (tv != null) - { - if (Group != null) - { - tv.Text = titleText; - } - - if (clickable) - { - tv.Click += (sender, e) => - { - AppTask.SetActivityResult(this, KeePass.ExitNormal); - Finish(); - }; - } else - { - tv.SetCompoundDrawables(null, null, null, null); - tv.Clickable = false; - } - } - //ICS? - if (Util.HasActionBar(this)) - { - ActionBar.Title = titleText; - if (clickable) - ActionBar.SetDisplayHomeAsUpEnabled(true); - } + ActionBar.Title = titleText; + if (clickable) + ActionBar.SetDisplayHomeAsUpEnabled(true); } @@ -256,6 +232,29 @@ namespace keepass2android ActionBar.SetIcon(drawable); } } + + class SuggestionListener: Java.Lang.Object, SearchView.IOnSuggestionListener + { + private readonly CursorAdapter _suggestionsAdapter; + + public SuggestionListener(CursorAdapter suggestionsAdapter) + { + _suggestionsAdapter = suggestionsAdapter; + } + + public bool OnSuggestionClick(int position) + { + var cursor = _suggestionsAdapter.Cursor; + cursor.MoveToPosition(position); + var x = cursor.GetString(cursor.GetColumnIndexOrThrow(SearchManager.SuggestColumnIntentDataId)); + return true; + } + + public bool OnSuggestionSelect(int position) + { + return false; + } + } public override bool OnCreateOptionsMenu(IMenu menu) { base.OnCreateOptionsMenu(menu); @@ -266,8 +265,9 @@ namespace keepass2android { var searchManager = (SearchManager) GetSystemService(Context.SearchService); var searchView = (SearchView) menu.FindItem(Resource.Id.menu_search).ActionView; - + searchView.SetSearchableInfo(searchManager.GetSearchableInfo(ComponentName)); + searchView.SetOnSuggestionListener(new SuggestionListener(searchView.SuggestionsAdapter)); } var item = menu.FindItem(Resource.Id.menu_sync); if (item != null) diff --git a/src/keepass2android/KeePass.cs b/src/keepass2android/KeePass.cs index 50f26c12..dab2d040 100644 --- a/src/keepass2android/KeePass.cs +++ b/src/keepass2android/KeePass.cs @@ -28,6 +28,39 @@ using Java.Lang.Reflect; using KeePassLib.Serialization; using Exception = System.Exception; using String = System.String; +/** + * General documentation + * + * Activity stack and activity results + * =================================== + * + * Keepass2Android comprises quite a number of different activities and entry points: The app can be started + * using the launcher icon (-> Activity "Keepass"), or by sending a URL (-> FileSelect), opening a .kdb(x)-file (->Password), + * swiping a YubikeyNEO (NfcOtpActivity). + * While the database is closed, there is only one activity on the stack: Keepass -> FileSelect <-> Password. + * After opening an database (in Password), Password is always the root of the stack (exception: after creating a database, + * FileSelect is the root without Password being open). + * + * Some possible stacks: + * Password -> Group ( -> Group (subgroups) ... ) -> EntryView -> EntryEdit + * (AdvancedSearch Menu) -> Search -> SearchResults -> EntryView -> EntryEdit + * (SearchWidget) -> SearchResults -> EntryView -> EntryEdit + * Password -> ShareUrlResults -> EntryView + * + * + * In each of these activities, an AppTask may be present and must be passed to started activities and ActivityResults + * must be returned. Therefore, if any Activity calls { StartActivity(newActivity);Finish(); }, it must specify FLAG_ACTIVITY_FORWARD_RESULT. + * + * Further sub-activities may be opened (e.g. Settings -> ExportDb, ...), but these are not necesarrily + * part of the AppTask. Then, neither the task has to be passed nor must the sub-activity return an ActivityResult. + * + * Activities with AppTasks should check if they get a new AppTask in OnActivityResult. + * + * Note: Chrome fires the ActionSend (Share URL) intent with NEW_TASK (i.e. KP2A appears in a separate task, either a new one, + * or, if it was running before, in the KP2A task), whereas Firefox doesn't specify that flag and KP2A appears "inside" Firefox. + * This means that the AppTask must be cleared for use in Chrome after finding an entry or pressing back button in ShareUrlResults. + * This would not be necessary for Firefox where the (Android) Task of standalone KP2A is not affected by the search. + */ namespace keepass2android { diff --git a/src/keepass2android/LockCloseActivity.cs b/src/keepass2android/LockCloseActivity.cs index 86db2160..e716e472 100644 --- a/src/keepass2android/LockCloseActivity.cs +++ b/src/keepass2android/LockCloseActivity.cs @@ -115,10 +115,10 @@ namespace keepass2android private class LockCloseActivityBroadcastReceiver : BroadcastReceiver { - readonly LockCloseActivity _service; - public LockCloseActivityBroadcastReceiver(LockCloseActivity service) + readonly LockCloseActivity _activity; + public LockCloseActivityBroadcastReceiver(LockCloseActivity activity) { - _service = service; + _activity = activity; } public override void OnReceive(Context context, Intent intent) @@ -126,7 +126,7 @@ namespace keepass2android switch (intent.Action) { case Intents.DatabaseLocked: - _service.OnLockDatabase(); + _activity.OnLockDatabase(); break; case Intent.ActionScreenOff: App.Kp2a.OnScreenOff(); diff --git a/src/keepass2android/LockCloseListActivity.cs b/src/keepass2android/LockCloseListActivity.cs index 1cf3efa1..a1496a05 100644 --- a/src/keepass2android/LockCloseListActivity.cs +++ b/src/keepass2android/LockCloseListActivity.cs @@ -95,10 +95,10 @@ namespace keepass2android private class LockCloseListActivityBroadcastReceiver : BroadcastReceiver { - readonly LockCloseListActivity _service; - public LockCloseListActivityBroadcastReceiver(LockCloseListActivity service) + readonly LockCloseListActivity _activity; + public LockCloseListActivityBroadcastReceiver(LockCloseListActivity activity) { - _service = service; + _activity = activity; } public override void OnReceive(Context context, Intent intent) @@ -106,7 +106,7 @@ namespace keepass2android switch (intent.Action) { case Intents.DatabaseLocked: - _service.OnLockDatabase(); + _activity.OnLockDatabase(); break; case Intent.ActionScreenOff: App.Kp2a.OnScreenOff(); diff --git a/src/keepass2android/Resources/Resource.designer.cs b/src/keepass2android/Resources/Resource.designer.cs index 86bdbe5f..4d62eb2c 100644 --- a/src/keepass2android/Resources/Resource.designer.cs +++ b/src/keepass2android/Resources/Resource.designer.cs @@ -5831,7 +5831,10 @@ namespace keepass2android public const int searchable = 2131034140; // aapt resource value: 0x7f05001d - public const int searchable_offline = 2131034141; + public const int searchable_debug = 2131034141; + + // aapt resource value: 0x7f05001e + public const int searchable_offline = 2131034142; static Xml() { diff --git a/src/keepass2android/ShareUrlResults.cs b/src/keepass2android/ShareUrlResults.cs index 79dc1c5e..81974719 100644 --- a/src/keepass2android/ShareUrlResults.cs +++ b/src/keepass2android/ShareUrlResults.cs @@ -62,27 +62,12 @@ namespace keepass2android SetResult(KeePass.ExitCloseAfterTaskComplete); _db = App.Kp2a.GetDb(); - - String searchUrl = ((SearchUrlTask)AppTask).UrlToSearchFor; - - if (!_db.Loaded) + if (App.Kp2a.DatabaseIsUnlocked) { - Intent intent = new Intent(this, typeof(FileSelectActivity)); - AppTask.ToIntent(intent); - intent.AddFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask); - StartActivityForResult(intent, 0); - - Finish(); - } - else if (App.Kp2a.QuickLocked) - { - PasswordActivity.Launch(this,_db.Ioc, AppTask); - Finish(); - } - else - { - Query(searchUrl); + String searchUrl = ((SearchUrlTask)AppTask).UrlToSearchFor; + Query(searchUrl); } + // else: LockCloseListActivity.OnResume will trigger a broadcast (LockDatabase) which will cause the activity to be finished. } @@ -99,8 +84,7 @@ namespace keepass2android } private void Query(String url) - { - + { try { //first: search for exact url diff --git a/src/keepass2android/Utils/Util.cs b/src/keepass2android/Utils/Util.cs index 8e37af0a..71214d6f 100644 --- a/src/keepass2android/Utils/Util.cs +++ b/src/keepass2android/Utils/Util.cs @@ -322,7 +322,13 @@ namespace keepass2android ((Spinner)dialog.FindViewById(Resource.Id.cred_remember_mode)).SetSelection((int)ioc.CredSaveMode); } - + + public static void FinishAndForward(Activity activity, Intent i) + { + i.SetFlags(ActivityFlags.ForwardResult); + activity.StartActivity(i); + activity.Finish(); + } } } diff --git a/src/keepass2android/app/App.cs b/src/keepass2android/app/App.cs index f76f3610..1a9fa809 100644 --- a/src/keepass2android/app/App.cs +++ b/src/keepass2android/app/App.cs @@ -67,15 +67,17 @@ namespace keepass2android #endif public const int AppNameResource = Resource.String.app_name; - public const string AppNameShort = "@string/short_app_name"; - public const string AppLauncherTitle = "@string/app_name"; + public const string AppNameShort = "@string/short_app_name" + "DBG"; + public const string AppLauncherTitle = "@string/app_name" + " Debug"; #if DEBUG public const string PackagePart = "keepass2android_debug"; + public const string Searchable = "@xml/searchable_debug"; #else public const string PackagePart = "keepass2android"; + public const string Searchable = "@xml/searchable"; #endif public const int LauncherIcon = Resource.Drawable.ic_launcher; - public const string Searchable = "@xml/searchable"; + } #endif /// diff --git a/src/keepass2android/app/AppTask.cs b/src/keepass2android/app/AppTask.cs index 5e687b1e..b0a6db63 100644 --- a/src/keepass2android/app/AppTask.cs +++ b/src/keepass2android/app/AppTask.cs @@ -48,6 +48,29 @@ namespace keepass2android #endregion } + /// + /// represents data stored in an intent or bundle as extra string array + /// + public class StringArrayExtra : IExtra + { + public string Key { get; set; } + public string[] Value { get; set; } + + #region IExtra implementation + + public void ToBundle(Bundle b) + { + b.PutStringArray(Key, Value); + } + + public void ToIntent(Intent i) + { + i.PutExtra(Key, Value); + } + + #endregion + } + /// /// base class for "tasks": these are things the user wants to do and which require several activities /// @@ -271,8 +294,20 @@ namespace keepass2android public override void AfterUnlockDatabase(PasswordActivity act) { ShareUrlResults.Launch(act, this); - RemoveTaskFromIntent(act); - act.AppTask = new NullTask(); + + //removed. this causes an issue in the following workflow: + //When the user wants to find an entry for a URL but has the wrong database open he needs + //to switch to another database. But the Task is removed already the first time when going through PasswordActivity + // (with the wrong db). + //Then after switching to the right database, the task is gone. + + //A reason this code existed was the following workflow: + //Using Chrome browser (with NEW_TASK flag for ActionSend): Share URL -> KP2A. + //Now the AppTask was in PasswordActivity and didn't get out of it. + //This is now solved by returning new tasks in ActivityResult. + + //RemoveTaskFromIntent(act); + //act.AppTask = new NullTask(); } public override bool CloseEntryActivityAfterCreate @@ -393,30 +428,72 @@ namespace keepass2android /// public class CreateEntryThenCloseTask: AppTask { + /// + /// extra key if only a URL is passed. optional. + /// public const String UrlKey = "CreateEntry_Url"; + + /// + /// extra key if a json serialized key/value mapping is passed. optional. + /// + /// Uses the PluginSDKs keys because this is mainly used for communicating with plugins. + /// Of course the data might also contain "non-output-data" (e.g. placeholders), but usually won't. + public const String AllFieldsKey = Keepass2android.Pluginsdk.Strings.ExtraEntryOutputData; - public string Url - { - get; - set; - } + /// + /// extra key to specify a list of protected field keys in AllFieldsKey. Passed as StringArrayExtra. optional. + /// + public const String ProtectedFieldsListKey = Keepass2android.Pluginsdk.Strings.ExtraProtectedFieldsList; + + public string Url { get; set; } + + public string AllFields { get; set; } + + public string[] ProtectedFieldsList { get; set; } public override void Setup(Bundle b) { Url = b.GetString(UrlKey); + AllFields = b.GetString(AllFieldsKey); + ProtectedFieldsList = b.GetStringArray(ProtectedFieldsListKey); } public override IEnumerable Extras { get { - yield return new StringExtra { Key = UrlKey, Value = Url }; + if (Url != null) + yield return new StringExtra { Key = UrlKey, Value = Url }; + if (AllFields != null) + yield return new StringExtra { Key = AllFieldsKey, Value = AllFields }; + if (ProtectedFieldsList != null) + yield return new StringArrayExtra { Key = ProtectedFieldsListKey, Value = ProtectedFieldsList }; } } public override void PrepareNewEntry(PwEntry newEntry) { - newEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(false, Url)); + if (Url != null) + { + newEntry.Strings.Set(PwDefs.UrlField, new ProtectedString(false, Url)); + } + if (AllFields != null) + { + IList protectedFieldsKeys = new List(); + if (ProtectedFieldsList != null) + { + protectedFieldsKeys = new Org.Json.JSONArray(ProtectedFieldsList).ToArray(); + } + var allFields = new Org.Json.JSONObject(AllFields); + for (var iter = allFields.Keys(); iter.HasNext; ) + { + string key = iter.Next().ToString(); + string value = allFields.Get(key).ToString(); + bool isProtected = protectedFieldsKeys.Contains(key) || key == PwDefs.PasswordField; + newEntry.Strings.Set(key, new ProtectedString(isProtected, value)); + } + + } } diff --git a/src/keepass2android/fileselect/FileSelectActivity.cs b/src/keepass2android/fileselect/FileSelectActivity.cs index 88d0cf96..e55facaa 100644 --- a/src/keepass2android/fileselect/FileSelectActivity.cs +++ b/src/keepass2android/fileselect/FileSelectActivity.cs @@ -44,7 +44,7 @@ namespace keepass2android DataMimeType="text/plain")] public class FileSelectActivity : ListActivity { - private ActivityDesign _design; + private readonly ActivityDesign _design; public FileSelectActivity (IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { @@ -136,7 +136,9 @@ namespace keepass2android EventHandler createNewButtonClick = (sender, e) => { //ShowFilenameDialog(false, true, true, Android.OS.Environment.ExternalStorageDirectory + GetString(Resource.String.default_file_path), "", Intents.RequestCodeFileBrowseForCreate) - StartActivityForResult(typeof (CreateDatabaseActivity), 0); + Intent i = new Intent(this, typeof (CreateDatabaseActivity)); + this.AppTask.ToIntent(i); + StartActivityForResult(i, 0); }; createNewButton.Click += createNewButtonClick; @@ -193,11 +195,11 @@ namespace keepass2android class MyViewBinder: Java.Lang.Object, SimpleCursorAdapter.IViewBinder { - private Kp2aApp app; + private readonly Kp2aApp _app; public MyViewBinder(Kp2aApp app) { - this.app = app; + _app = app; } public bool SetViewValue(View view, ICursor cursor, int columnIndex) @@ -207,7 +209,7 @@ namespace keepass2android String path = cursor.GetString(columnIndex); TextView textView = (TextView)view; IOConnectionInfo ioc = new IOConnectionInfo {Path = path}; - textView.Text = app.GetFileStorage(ioc).GetDisplayName(ioc); + textView.Text = _app.GetFileStorage(ioc).GetDisplayName(ioc); textView.Tag = ioc.Path; return true; } @@ -421,9 +423,7 @@ namespace keepass2android if (ShowRecentFiles() != _recentMode) { // Restart the activity - Intent intent = Intent; - StartActivity(intent); - Finish(); + Recreate(); return; } diff --git a/src/keepass2android/keepass2android.csproj b/src/keepass2android/keepass2android.csproj index 2dc5dd5a..c48bae4a 100644 --- a/src/keepass2android/keepass2android.csproj +++ b/src/keepass2android/keepass2android.csproj @@ -966,4 +966,7 @@ + + + \ No newline at end of file diff --git a/src/keepass2android/search/SearchActivity.cs b/src/keepass2android/search/SearchActivity.cs index 0e0240b7..ae9e54cc 100644 --- a/src/keepass2android/search/SearchActivity.cs +++ b/src/keepass2android/search/SearchActivity.cs @@ -36,9 +36,12 @@ namespace keepass2android return ((CheckBox)FindViewById(resId)).Checked; } + private AppTask _appTask; + protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); + _appTask = AppTask.GetTaskInOnCreate(bundle, Intent); SetContentView(Resource.Layout.search); SearchParameters sp = new SearchParameters(); PopulateCheckBox(Resource.Id.cbSearchInTitle, sp.SearchInTitles); @@ -92,8 +95,11 @@ namespace keepass2android searchIntent.PutExtra("CaseSensitive", GetCheckBoxValue(Resource.Id.cbCaseSensitive)); searchIntent.PutExtra("ExcludeExpired", GetCheckBoxValue(Resource.Id.cbExcludeExpiredEntries)); searchIntent.PutExtra(SearchManager.Query, searchString); - StartActivityForResult(searchIntent, 0); - Finish(); + //forward appTask: + _appTask.ToIntent(searchIntent); + + Util.FinishAndForward(this, searchIntent); + } } } diff --git a/src/keepass2android/services/CopyToClipboardService.cs b/src/keepass2android/services/CopyToClipboardService.cs index 62d7c597..5e820760 100644 --- a/src/keepass2android/services/CopyToClipboardService.cs +++ b/src/keepass2android/services/CopyToClipboardService.cs @@ -255,7 +255,7 @@ namespace keepass2android // automatically bring up the Keyboard selection dialog if ((closeAfterCreate) && prefs.GetBoolean(GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default))) { - ActivateKp2aKeyboard(this); + ActivateKp2aKeyboard(this); } }