From 5c6ff45cc951dcff43b20ebf909564ed59b8d6e1 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Sat, 27 Aug 2016 14:36:32 -0400 Subject: [PATCH] Proper conditions for push reregistration. Added fix for app compat crash on resume from sleep while app was open. --- src/Android/MainActivity.cs | 15 +++--- src/Android/MainApplication.cs | 68 ++++++++++++++++++++++++-- src/Android/Services/AppInfoService.cs | 10 ++-- src/App/App.cs | 6 +++ src/App/Pages/LoginPage.cs | 1 - 5 files changed, 83 insertions(+), 17 deletions(-) diff --git a/src/Android/MainActivity.cs b/src/Android/MainActivity.cs index 28228df2a..6b54be372 100644 --- a/src/Android/MainActivity.cs +++ b/src/Android/MainActivity.cs @@ -1,5 +1,4 @@ using System; - using Android.App; using Android.Content.PM; using Android.Views; @@ -10,28 +9,33 @@ using Plugin.Fingerprint.Abstractions; using Plugin.Settings.Abstractions; using Plugin.Connectivity.Abstractions; using Acr.UserDialogs; -using PushNotification.Plugin.Abstractions; using Android.Content; using System.Reflection; using Xamarin.Forms.Platform.Android; using Xamarin.Forms; +using System.Threading.Tasks; namespace Bit.Android { [Activity(Label = "bitwarden", - Icon = "@drawable/icon", + Icon = "@drawable/icon", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, WindowSoftInputMode = SoftInput.StateHidden)] public class MainActivity : FormsAppCompatActivity { private const string HockeyAppId = "d3834185b4a643479047b86c65293d42"; - protected override void OnCreate(Bundle bundle) + protected async override void OnCreate(Bundle bundle) { ToolbarResource = Resource.Layout.toolbar; TabLayoutResource = Resource.Layout.tabs; base.OnCreate(bundle); + + // workaround for app compat bug + // ref https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity + await Task.Delay(10); + Console.WriteLine("A OnCreate"); Window.SetSoftInputMode(SoftInput.StateHidden); Window.AddFlags(WindowManagerFlags.Secure); @@ -59,8 +63,7 @@ namespace Bit.Android Resolver.Resolve(), Resolver.Resolve())); - Xamarin.Forms.MessagingCenter.Subscribe( - Xamarin.Forms.Application.Current, "RateApp", (sender) => + MessagingCenter.Subscribe(Xamarin.Forms.Application.Current, "RateApp", (sender) => { RateApp(); }); diff --git a/src/Android/MainApplication.cs b/src/Android/MainApplication.cs index 38d8eb879..774edae84 100644 --- a/src/Android/MainApplication.cs +++ b/src/Android/MainApplication.cs @@ -17,16 +17,21 @@ using PushNotification.Plugin; using PushNotification.Plugin.Abstractions; using XLabs.Ioc; using XLabs.Ioc.Unity; +using System.Threading.Tasks; +using Plugin.Settings.Abstractions; namespace Bit.Android { #if DEBUG [Application(Debuggable = true)] #else - [Application(Debuggable=false)] + [Application(Debuggable = false)] #endif public class MainApplication : Application, Application.IActivityLifecycleCallbacks { + private const string FirstLaunchKey = "firstLaunch"; + private const string LastVersionCodeKey = "lastVersionCode"; + public static Context AppContext; public MainApplication(IntPtr handle, JniHandleOwnership transer) @@ -38,23 +43,76 @@ namespace Bit.Android } } - public override void OnCreate() + public async override void OnCreate() { base.OnCreate(); + + // workaround for app compat bug + // ref https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity + await Task.Delay(10); + RegisterActivityLifecycleCallbacks(this); AppContext = ApplicationContext; StartPushService(); + HandlePushReregistration(); + } + private void HandlePushReregistration() + { var pushNotification = Resolver.Resolve(); - // Must unregister the previous instance first or else things wont work + var settings = Resolver.Resolve(); + + // Reregister for push token based on certain conditions // ref https://github.com/rdelrosario/xamarin-plugins/issues/65 - if(Resolver.Resolve().IsAuthenticated) + + var reregister = false; + + // 1. First time starting the app after a new install + if(settings.GetValueOrDefault(FirstLaunchKey, true)) + { + settings.AddOrUpdateValue(FirstLaunchKey, false); + reregister = true; + } + + // 2. App version changed (installed update) + var versionCode = Context.ApplicationContext.PackageManager.GetPackageInfo(Context.PackageName, 0).VersionCode; + if(settings.GetValueOrDefault(LastVersionCodeKey, -1) != versionCode) + { + settings.AddOrUpdateValue(LastVersionCodeKey, versionCode); + reregister = true; + } + + // 3. In debug mode + if(InDebugMode()) + { + reregister = true; + } + + // 4. Doesn't have a push token currently + if(string.IsNullOrWhiteSpace(pushNotification.Token)) + { + reregister = true; + } + + if(reregister) { pushNotification.Unregister(); - pushNotification.Register(); + if(Resolver.Resolve().IsAuthenticated) + { + pushNotification.Register(); + } } } + private bool InDebugMode() + { +#if DEBUG + return true; +#else + return false; +#endif + } + public override void OnTerminate() { base.OnTerminate(); diff --git a/src/Android/Services/AppInfoService.cs b/src/Android/Services/AppInfoService.cs index 342236dde..c6737da5c 100644 --- a/src/Android/Services/AppInfoService.cs +++ b/src/Android/Services/AppInfoService.cs @@ -1,14 +1,14 @@ using Bit.App.Abstractions; -using AndrodApp = Android.App.Application; +using AndroidApp = Android.App.Application; namespace Bit.Android.Services { public class AppInfoService : IAppInfoService { - public string Version => AndrodApp.Context.ApplicationContext.PackageManager - .GetPackageInfo(AndrodApp.Context.PackageName, 0).VersionName; + public string Version => AndroidApp.Context.ApplicationContext.PackageManager + .GetPackageInfo(AndroidApp.Context.PackageName, 0).VersionName; - public string Build => AndrodApp.Context.ApplicationContext.PackageManager - .GetPackageInfo(AndrodApp.Context.PackageName, 0).VersionCode.ToString(); + public string Build => AndroidApp.Context.ApplicationContext.PackageManager + .GetPackageInfo(AndroidApp.Context.PackageName, 0).VersionCode.ToString(); } } diff --git a/src/App/App.cs b/src/App/App.cs index 54140a2ed..1c7568500 100644 --- a/src/App/App.cs +++ b/src/App/App.cs @@ -102,6 +102,12 @@ namespace Bit.App protected async override void OnResume() { + base.OnResume(); + + // workaround for app compat bug + // ref https://forums.xamarin.com/discussion/62414/app-resuming-results-in-crash-with-formsappcompatactivity + await Task.Delay(10); + // Handle when your app resumes Debug.WriteLine("OnResume"); diff --git a/src/App/Pages/LoginPage.cs b/src/App/Pages/LoginPage.cs index 4005e941b..c1fdce5a2 100644 --- a/src/App/Pages/LoginPage.cs +++ b/src/App/Pages/LoginPage.cs @@ -205,7 +205,6 @@ namespace Bit.App.Pages if(Device.OS == TargetPlatform.Android) { - _pushNotification.Unregister(); _pushNotification.Register(); }