From 957db1ec1177689aed2b1b13478506a1611acf7b Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 8 Jun 2017 16:22:11 -0400 Subject: [PATCH] launch android app packages --- src/Android/MainActivity.cs | 31 ++++++++++++++++++- .../Models/Page/VaultViewLoginPageModel.cs | 13 +++++++- src/App/Pages/Vault/VaultViewLoginPage.cs | 12 ++++++- src/App/Resources/AppResources.Designer.cs | 9 ++++++ src/App/Resources/AppResources.resx | 4 +++ 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/Android/MainActivity.cs b/src/Android/MainActivity.cs index cfa25950a..643a7b7ef 100644 --- a/src/Android/MainActivity.cs +++ b/src/Android/MainActivity.cs @@ -14,6 +14,7 @@ using Xamarin.Forms.Platform.Android; using Xamarin.Forms; using System.Threading.Tasks; using Bit.App.Models.Page; +using Bit.App; namespace Bit.Android { @@ -24,6 +25,7 @@ namespace Bit.Android public class MainActivity : FormsAppCompatActivity { private const string HockeyAppId = "d3834185b4a643479047b86c65293d42"; + private DateTime? _lastAction; protected override void OnCreate(Bundle bundle) { @@ -94,6 +96,12 @@ namespace Bit.Android { MoveTaskToBack(true); }); + + MessagingCenter.Subscribe( + Xamarin.Forms.Application.Current, "LaunchApp", (sender, args) => + { + LaunchApp(args); + }); } private void ReturnCredentials(VaultListPageModel.Login login) @@ -118,7 +126,7 @@ namespace Bit.Android { Parent.SetResult(Result.Ok, data); } - + Finish(); } @@ -199,5 +207,26 @@ namespace Bit.Android var intent = new Intent(global::Android.Provider.Settings.ActionAccessibilitySettings); StartActivity(intent); } + + private void LaunchApp(string packageName) + { + if(_lastAction.LastActionWasRecent()) + { + return; + } + _lastAction = DateTime.UtcNow; + + packageName = packageName.Replace("androidapp://", string.Empty); + var launchIntent = PackageManager.GetLaunchIntentForPackage(packageName); + if(launchIntent == null) + { + var dialog = Resolver.Resolve(); + dialog.Alert(string.Format(App.Resources.AppResources.CannotOpenApp, packageName)); + } + else + { + StartActivity(launchIntent); + } + } } } diff --git a/src/App/Models/Page/VaultViewLoginPageModel.cs b/src/App/Models/Page/VaultViewLoginPageModel.cs index 930b6da9c..d8fcea766 100644 --- a/src/App/Models/Page/VaultViewLoginPageModel.cs +++ b/src/App/Models/Page/VaultViewLoginPageModel.cs @@ -114,7 +114,18 @@ namespace Bit.App.Models.Page { get { - if(!ShowUri || !Uri.StartsWith("http")) + if(!ShowUri) + { + return false; + } + + if(Device.RuntimePlatform == Device.Android && !Uri.StartsWith("http") && + !Uri.StartsWith("androidapp://")) + { + return false; + } + + if(Device.RuntimePlatform != Device.Android && !Uri.StartsWith("http")) { return false; } diff --git a/src/App/Pages/Vault/VaultViewLoginPage.cs b/src/App/Pages/Vault/VaultViewLoginPage.cs index 8a2af5e9e..c61582652 100644 --- a/src/App/Pages/Vault/VaultViewLoginPage.cs +++ b/src/App/Pages/Vault/VaultViewLoginPage.cs @@ -75,7 +75,17 @@ namespace Bit.App.Pages UriCell = new LabeledValueCell(AppResources.Website, button1Text: AppResources.Launch); UriCell.Value.SetBinding(Label.TextProperty, nameof(VaultViewLoginPageModel.UriHost)); UriCell.Button1.SetBinding(IsVisibleProperty, nameof(VaultViewLoginPageModel.ShowLaunch)); - UriCell.Button1.Command = new Command(() => Device.OpenUri(new Uri(Model.Uri))); + UriCell.Button1.Command = new Command(() => + { + if(Device.RuntimePlatform == Device.Android && Model.Uri.StartsWith("androidapp://")) + { + MessagingCenter.Send(Application.Current, "LaunchApp", Model.Uri); + } + else if(Model.Uri.StartsWith("http://") || Model.Uri.StartsWith("https://")) + { + Device.OpenUri(new Uri(Model.Uri)); + } + }); // Notes NotesCell = new LabeledValueCell(); diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs index 33bb32b4d..1deef147c 100644 --- a/src/App/Resources/AppResources.Designer.cs +++ b/src/App/Resources/AppResources.Designer.cs @@ -394,6 +394,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Cannot open the app "{0}".. + /// + public static string CannotOpenApp { + get { + return ResourceManager.GetString("CannotOpenApp", resourceCulture); + } + } + /// /// Looks up a localized string similar to Change Email. /// diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx index 7088c9b60..4fcdcb7ab 100644 --- a/src/App/Resources/AppResources.resx +++ b/src/App/Resources/AppResources.resx @@ -849,4 +849,8 @@ Always scan the screen for fields and only offer an auto-fill notification if password fields are found. This is the default setting. + + Cannot open the app "{0}". + Message shown when trying to launch an app that does not exist on the user's device. + \ No newline at end of file