0
votes

I am using the following code for calling a function every 10 seconds.

var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromSeconds(10);

var timer = new System.Threading.Timer((e) =>
{
    MyFunction();
}, null, startTimeSpan, periodTimeSpan);

MyFunction() will execute every 10 seconds when the app is on the open state. When the app is in the background, that function is not invoking.

So how can I invoke a function when the app is in the background? Are there any NuGet packages for this or we need to do this using the dependency service?

UPDATE

When I running your demo I am getting the below exception:

enter image description here

I have integrated the codes on my sample. The code execution coming on Start() in the StartServiceDroid. But not hitting the OnStartCommand() function. Here is my sample, could you please have a look? I need to run the MyFunction() every x seconds in the background or foreground mode.

Update 10-07-2020

@Leon Lu - MSFT I found a new solution here. :)

var second = TimeSpan.FromSeconds(10);

Device.StartTimer(second, () => {
    Debug.WriteLine("Hiiiii");
    return true;
});

I create a sample application with this code and it is working fine on foreground and background mode. Every 10 seconds, the Hiii message is printing on the output box even the app is running on the background.

This is included with Xamarin Forms, so no need for any platform-specific logic.

Is there any problem with this approach?

Update 15/07/2020

Today I have tested it on a real device. :)

Case 1: Run the app on Visual Studio, Service is invoking in foreground mode. Move the app to the background (Still, the app is running in VS), the background service is invoking when the app is on the background every 10 seconds.

Case 2: Open the app installed app normally, (not running it in VS), service is invoking in foreground mode, Move the app to the background, the background service is not invoking even after 10minutes.

I am totally confused now, background service is invoking when the app is running on VS and not invoking when open the installed app normally. For the second case, I have waited for more than 10 minutes, but the service that I added is not invoking. Both cases are done on debug mode.

Is it the only behavior of xamarin forms platform? If we do it in the native ios platform, is it possible to trigger the background service on every x seconds? How skype is doing background service?

Tested device model: iPhone 7 Software version: 13.5.1

1

1 Answers

1
votes

In Android, you can use foreground service to keep your MyFunction() always running in background. If you used it in xamarin forms. you can use dependence service to invoke the foreground service, then execute your Timer with MyFunction in foreground service.

Here is simple code about use a DependentService to open a foreground service.

  [Service]
    public class DependentService : Service, IService
    {
        public void Start()
        {
            var intent = new Intent(Android.App.Application.Context,
     typeof(DependentService));


            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
            {
                Android.App.Application.Context.StartForegroundService(intent);
            }
            else
            {
                Android.App.Application.Context.StartService(intent);
            }
        }

        public override IBinder OnBind(Intent intent)
        {
            return null;
        }
        public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
        public override StartCommandResult OnStartCommand(Intent intent,StartCommandFlags flags, int startId)
        {
            // From shared code or in your PCL

            CreateNotificationChannel();
            string messageBody = "service starting";

            var notification = new Notification.Builder(this, "10111")
            .SetContentTitle("Foreground")
            .SetContentText(messageBody)
            .SetSmallIcon(Resource.Drawable.main)
            .SetOngoing(true)
            .Build();
            StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);

     //=======you can do you always running work here.=====
           var startTimeSpan = TimeSpan.Zero;
           var periodTimeSpan = TimeSpan.FromSeconds(10);

           var timer = new System.Threading.Timer((e) =>
          {
              MyFunction();
          }, null, startTimeSpan, periodTimeSpan);
          



           
            return StartCommandResult.Sticky;
        }


        void CreateNotificationChannel()
        {
            if (Build.VERSION.SdkInt < BuildVersionCodes.O)
            {
                // Notification channels are new in API 26 (and not a part of the
                // support library). There is no need to create a notification
                // channel on older versions of Android.
                return;
            }

            var channelName = Resources.GetString(Resource.String.channel_name);
            var channelDescription = GetString(Resource.String.channel_description);
            var channel = new NotificationChannel("10111", channelName, NotificationImportance.Default)
            {
                Description = channelDescription
            };

            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.CreateNotificationChannel(channel);
        }
    }

Here is my demo about how to use foreground service in xamarin form.

https://github.com/851265601/ForeGroundService

In iOS, it cannot be achieved that always running your application in the background, because iOS, just allow normal applications(:Audio, VoIP,External Accessories and Bluetooth Newsstand, Location, Fetch (iOS 7+), Remote Notifications (iOS 7+) application could be allowed allways running in background, you can see this thread) running in background with in 10 minutes. You can refer to this article.

https://docs.microsoft.com/en-us/xamarin/ios/app-fundamentals/backgrounding/ios-backgrounding-techniques/ios-backgrounding-with-tasks