How to call PCL service from background service?

revaldo666revaldo666 Member ✭✭

Hello,

I have a Xamarin Forms android application.
With with background service that checks every 10 seconds current time and user configs to notify the user that he should drink the medicine.

When I tried to send a message from PeriaodicBackgroundService to PCL

MessagingCenter.Send<string, string>("APP", "PROCESS_TIMING", DateTime.Now.ToString());

it does not get it in PCL.
Is it possible to call the PCL method from the Background Service?

Here is the code of Background Service

 [Service(Name = "com.xamarin.TimestampService",
         Process = ":timestampservice_process",
         Exported = true)]
    class PeriodicBackgroundService : Service
    {
        private const string Tag = "[PeriodicBackgroundService]";

        private bool _isRunning;
        private Context _context;
        private Task _task;

        #region overrides

        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public override void OnCreate()
        {
            _context = this;
            _isRunning = false;
            _task = new Task(DoWork);
        }

        public override void OnDestroy()
        {
            _isRunning = false;

            if (_task != null && _task.Status == TaskStatus.RanToCompletion)
            {
                _task.Dispose();
            }
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            if (!_isRunning)
            {
                _isRunning = true;
                _task.Start();
            }
            return StartCommandResult.Sticky;
        }

        #endregion

        private void DoWork()
        {
            try
            {
                MessagingCenter.Send<string, string>("APP", "PROCESS_TIMING", DateTime.Now.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                StopSelf();
            }
        }
    }

In MainActivity

 public static void SetAlarmForBackgroundServices(Context context)
        {
            var alarmIntent = new Intent(context.ApplicationContext, typeof(AlarmReceiver));
            var broadcast = PendingIntent.GetBroadcast(context.ApplicationContext, 0, alarmIntent, PendingIntentFlags.NoCreate);
            if (broadcast == null)
            {
                var pendingIntent = PendingIntent.GetBroadcast(context.ApplicationContext, 0, alarmIntent, 0);
                var alarmManager = (AlarmManager)context.GetSystemService(Context.AlarmService);
                alarmManager.SetRepeating(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime(), 10000, pendingIntent);
            }
        }

In App.cs (PCL)

protected override async void OnStart()
        {
       base.OnStart();

            ITranslationService translationService = ViewModelLocator.Resolve<ITranslationService>();
            translationService.LoadLocalizations();

            drugService = ViewModelLocator.Resolve<IDrugService>();
            dependencyService = ViewModelLocator.Resolve<IDependencyService>();

            MessagingCenter.Subscribe<string, string>("APP", "PROCESS_TIMING", async (sender, args) =>
            {
                DrugServiceResult processed = await this.drugService .ProceedTime();

                if (processed.NextDrunk >= DateTime.Now)
                {
                    this.notifiyed = false;
                }
            });

            await InitNavigation();

            base.OnResume();
        }

Answers

  • revaldo666revaldo666 Member ✭✭

    @AlessandroCaliaro said:
    The first parameter should be a class, non "string"

    I modified the PeriodicBackgroundService to send the message like this

    MessagingCenter.Send((App)Xamarin.Forms.Application.Current, "PROCESS_TIMING");

    In the PCL App.cs I have subscribed to this message, but I still can't receive it.

    MessagingCenter.Subscribe<App>(this, "PROCESS_TIMING", (sender) =>
                {
                    this.dependencyService.Get<IAudio>().PlayAndNotify();
                });
    
  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    where have you subscribed the message? post your class

  • revaldo666revaldo666 Member ✭✭
    edited July 15

    @AlessandroCaliaro said:
    where have you subscribed the message? post your class

    public partial class App : Application
            {
                ISettingsService _settingsService;
    
                public static Func<Task<bool?>> HardwareBackPressed
                {
                    private get;
                    set;
                }
    
                public static event EventHandler OnApplicationSleep;
                public static event EventHandler OnApplicationResumed;
    
                public static async Task<bool?> CallHardwareBackPressed()
                {
                    Func<Task<bool?>> backPressed = HardwareBackPressed;
                    if (backPressed != null)
                    {
                        return await backPressed();
                    }
    
                    return true;
                }
    
                public App()
                {
                    InitializeComponent();
    
                    InitApp();
                }
    
                private void InitApp()
                {
                    _settingsService = ViewModelLocator.Resolve<ISettingsService>();
                }
    
                private Task InitNavigation()
                {
                    var navigationService = ViewModelLocator.Resolve<INavigationService>();
                    return navigationService.InitializeAsync();
                }
    
                private IDependencyService dependencyService;
                private bool notifiyed = false;
                protected override async void OnStart()
                {
                    base.OnStart();
    
                    ITranslationService translationService = ViewModelLocator.Resolve<ITranslationService>();
                    translationService.LoadLocalizations();
    
                    dependencyService = ViewModelLocator.Resolve<IDependencyService>();
    
                    MessagingCenter.Subscribe<App>(this, "PROCESS_TIMING", (sender) =>
                    {
                        this.dependencyService.Get<IAudio>().PlayAndNotify();
                    });
    
                    await InitNavigation();
    
                    base.OnResume();
                }
    
                protected override void OnSleep()
                {
                    HardwareBackPressed = null;
    
                    if (OnApplicationSleep != null)
                    {
                        OnApplicationSleep(null, null);
                    }
                }
    
                protected override void OnResume()
                {
                    if (OnApplicationResumed != null)
                    {
                        OnApplicationResumed(null, null);
                    }
                }
            }
    

    This is PCL App.cs class

  • ColeXColeX Member, Xamarin Team Xamurai
    edited July 15

    The parameter should be corresponding when send and Subscribe.

    Send :

    MessagingCenter.Send<object, string>(this, "PROCESS_TIMING", DateTime.Now.ToString());
    

    Subscribe :

     MessagingCenter.Subscribe<object, string>(this, "PROCESS_TIMING", (obj, str) =>{ });
    
  • revaldo666revaldo666 Member ✭✭

    @ColeX said:
    The parameter should be corresponding when send and Subscribe.

    Send :

    MessagingCenter.Send<object, string>(this, "PROCESS_TIMING", DateTime.Now.ToString());
    

    Subscribe :

     MessagingCenter.Subscribe<object, string>(this, "PROCESS_TIMING", (obj, str) =>{ });
    

    Still can't receive :(
    I think the problem is that I'm trying to send a message from background service...I don't know... maybe something else.

  • revaldo666revaldo666 Member ✭✭

    Any Suggestions?

    Maybe another solution exists for calling the PCL class from periodic background service?

Sign In or Register to comment.