XamarinPlayCoreUpdater icon indicating copy to clipboard operation
XamarinPlayCoreUpdater copied to clipboard

InstallStateUpdatedListener.onStateUpdate method mapping

Open Alex1ch opened this issue 4 years ago • 6 comments

I've got an issue with implementing IInstallStateUpdatedListener interface. Java generated mappings for my class gave me an error that it didn't implement onStateUpdate(IstallState), because IInstallStateUpdatedListener maps osStateUpdate(Object).

So, to solve this problem I propose to remove IStateUpdatedListener from IInstallStateUpdatedListener and map onStateUpdate(IstallState) by hand.

Alex1ch avatar Oct 15 '21 11:10 Alex1ch

@Alex1ch how can I test this to see if it works with the new changes?

saamerm avatar Oct 15 '21 13:10 saamerm

@saamerm you can test sample from the issue https://github.com/PatGet/XamarinPlayCoreUpdater/issues/17, but you have to change parameter type:

public class AppUpdateInstallListener : Java.Lang.Object, IInstallStateUpdatedListener
{
    private readonly IAppUpdateManager _appUpdateManager;

    public AppUpdateInstallListener(IAppUpdateManager appUpdateManager)
    {
        _appUpdateManager = appUpdateManager;
    }

    public void OnStateUpdate(InstallState info)
    {
        if (info.InstallStatus() == InstallStatus.Downloaded)
        {
                _appUpdateManager.CompleteUpdate();
        }
    }
}

Or I can modify PlayCoreUpdateTest.Android later.

Alex1ch avatar Oct 15 '21 13:10 Alex1ch

Once these changes are made in your local environment, are you able to support flexible updates in your app? @Alex1ch

saamerm avatar May 08 '22 07:05 saamerm

I've tested the version from this PR and flexible updates seems to work fine.

Main activity example:

    [Activity(MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
    public class MainActivity : FormsAppCompatActivity
    {
        private ILogger<MainActivity> logger;
        private IMessageBoxService messageBoxService;
        private const int _Request_Update = 4711;


        protected override void OnCreate(Bundle savedInstanceState)
        {
            AppCompatDelegate.DefaultNightMode = AppCompatDelegate.ModeNightNo;

            base.OnCreate(savedInstanceState);

            Popup.Init(this);
            Platform.Init(this, savedInstanceState);
            Forms.Init(this, savedInstanceState);
            ZXing.Net.Mobile.Forms.Android.Platform.Init();
            CachedImageRenderer.Init(true);

            var application = new App.App();
            LoadApplication(application);

            var loggerFactory = application.DependencyInjectionService.Resolve<ILoggerFactory>();
            logger = loggerFactory.CreateLogger<MainActivity>();
            messageBoxService = application.DependencyInjectionService.Resolve<IMessageBoxService>();
#if !DEBUG
            var appUpdateManager = AppUpdateManagerFactory.Create(this);
            var appUpdateInfoTask = appUpdateManager.AppUpdateInfo;

            appUpdateInfoTask.AddOnSuccessListener(new AppUpdateSuccessListener(appUpdateManager, this, _Request_Update, Intent, loggerFactory, messageBoxService));
#endif
        }

        public override void OnUserInteraction()
        {
            UserActivityMonitor.ReportActivity();
            base.OnUserInteraction();
        }

        protected override void OnDestroy()
        {
            _ = BeforeApplicationExitActions.HandleThreatOfApplicationTerminationAsync();
            base.OnDestroy();
        }

        public override void OnBackPressed()
        {
            Popup.SendBackPressed(base.OnBackPressed);
        }

        //protected override void OnResume()
        //{
        //    var appUpdateManager = AppUpdateManagerFactory.Create(this);
        //    appUpdateManager.AppUpdateInfo.AddOnSuccessListener(new AppUpdateSuccessListener(appUpdateManager, this, _Request_Update, Intent));
        //    base.OnResume();
        //}

        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);
            if (_Request_Update.Equals(requestCode))
            {
                HandleFlexibleUpdateActivityResult(resultCode);
            }
        }

        private void HandleFlexibleUpdateActivityResult(Result resultCode)
        {
            switch (resultCode) // The switch block will be triggered only with flexible update since it returns the install result codes
            {
                case Result.Ok:
                    messageBoxService.ShowSuccessToast("Application update started");
                    break;
                case Result.Canceled:
                    messageBoxService.ShowToast("Application update cancelled");
                    break;
                case (Result) ActivityResult.ResultInAppUpdateFailed:
                    messageBoxService.ShowErrorToast("Application update failed");
                    break;
            }
        }
    }


    public class AppUpdateSuccessListener : Object, IOnSuccessListener
    {
        private readonly IAppUpdateManager appUpdateManager;
        private readonly Activity mainActivity;
        private readonly int updateRequest;
        private readonly Intent intent;
        private readonly ILoggerFactory loggerFactory;
        private readonly IMessageBoxService messageBoxService;
        private readonly ILogger<AppUpdateSuccessListener> logger;

        public AppUpdateSuccessListener(IAppUpdateManager appUpdateManager, Activity mainActivity, int updateRequest, Intent intent, ILoggerFactory loggerFactory, IMessageBoxService messageBoxService)
        {
            this.appUpdateManager = appUpdateManager;
            this.mainActivity = mainActivity;
            this.updateRequest = updateRequest;
            this.intent = intent;
            this.loggerFactory = loggerFactory;
            logger = loggerFactory.CreateLogger<AppUpdateSuccessListener>();
            this.messageBoxService = messageBoxService;
        }

        public void OnSuccess(Object p0)
        {
            try
            {
                if (p0 is not AppUpdateInfo info)
                {
                    return;
                }


                var availability = info.UpdateAvailability();

                if (availability.Equals(UpdateAvailability.UpdateAvailable) ||
                    availability.Equals(UpdateAvailability.DeveloperTriggeredUpdateInProgress))
                {
                    var availableVersionCode = info.AvailableVersionCode();
                    var currentVersionCode = int.Parse(AppInfo.BuildString);
                    var versionMismatchType = VersionLogic.GetVersionMismatchType(currentVersionCode, availableVersionCode);

                    if (versionMismatchType == VersionMismatchType.None)
                    {
                        return;
                    }

                    if (versionMismatchType == VersionMismatchType.Minor && info.IsUpdateTypeAllowed(AppUpdateType.Flexible))
                    {
                        appUpdateManager.RegisterListener(new InstallStateUpdatedListener(mainActivity, appUpdateManager, loggerFactory, messageBoxService));
                        appUpdateManager.StartUpdateFlowForResult(info, AppUpdateType.Flexible, mainActivity, updateRequest);
                        return;
                    }

                    if (versionMismatchType == VersionMismatchType.Minor && info.IsUpdateTypeAllowed(AppUpdateType.Immediate))
                    {
                        appUpdateManager.StartUpdateFlowForResult(info, AppUpdateType.Immediate, mainActivity, updateRequest);
                        return;
                    }

                    messageBoxService.ShowErrorToast($"In app update ({versionMismatchType}) is not allowed.");
                }
            }
            catch (Exception e)
            {
                logger.LogError(e, "Failed to perform in app update.");
            }
        }
    }

    public class InstallStateUpdatedListener : Object, IInstallStateUpdatedListener
    {
        private readonly Activity activity;
        private readonly IAppUpdateManager appUpdateManager;
        private readonly IMessageBoxService messageBoxService;
        private readonly ILogger<InstallStateUpdatedListener> logger;

        public InstallStateUpdatedListener(Activity activity, IAppUpdateManager appUpdateManager, ILoggerFactory loggerFactory, IMessageBoxService messageBoxService)
        {
            this.activity = activity;
            this.appUpdateManager = appUpdateManager;
            logger = loggerFactory.CreateLogger<InstallStateUpdatedListener>();
            this.messageBoxService = messageBoxService;
        }

        public void OnStateUpdate(InstallState installState)
        {
            try
            {
                var installStatus = installState.InstallStatus();
                if (installStatus == InstallStatus.Downloading)
                {
                    var completed = Math.Round((double) installState.BytesDownloaded() / installState.TotalBytesToDownload() * 100);
                    messageBoxService.ShowSuccessToast($"Downloaded {completed}%", TimeSpan.FromMilliseconds(500));
                }
                else if (installStatus == InstallStatus.Downloaded)
                {
                    var dialog = new AlertDialog.Builder(activity);
                    var alert = dialog.Create();

                    alert?.SetTitle("Download completed");
                    alert?.SetMessage("Update is ready to be installed.");
                    alert?.SetButton((int) DialogButtonType.Positive, "Perform update", (o, args) => { appUpdateManager.CompleteUpdate(); });
                    alert?.SetCancelable(false);
                    alert?.Show();
                }
                else if (installStatus == InstallStatus.Failed)
                {
                    messageBoxService.ShowErrorToast("Update download failed.");
                }
            }
            catch (Exception e)
            {
                logger.LogError(e, "Error occurred during in app update status change.");
            }
        }
    }

MichalTichy avatar Oct 10 '22 20:10 MichalTichy

Would be great to see this get merged!

kkppstudios avatar Oct 18 '22 01:10 kkppstudios

i just downloaded the NuGet and i'm still facing this issue

othmanTeffahi99 avatar Nov 23 '22 16:11 othmanTeffahi99