Forum Xamarin.Forms

Xamarin Forms Android boot start service with new task

I want to run a task in the background after Android boot. The task would stay active for an infinite time, and. After the user launched the app, the task may be killed by the user and a new task will be launched from the UI.

I found the “LongRunningTaskService” sample in FormsBackgrounding fits my usage quite well as I need the background task with the ability to be killed under certain condition. The sample starts an Android service “LongRunningTaskService” when a message is received from the UI Form. The service then kicks off a background task with “Task.Run”.

The full sample is available at
http://arteksoftware.com/backgrounding-with-xamarin-forms/
https://github.com/RobGibbens/XamarinFormsBackgrounding

void WireUpLongRunningTask()
    {
        MessagingCenter.Subscribe<StartLongRunningTaskMessage> (this, "StartLongRunningTaskMessage", message =>  {
            var intent = new Intent(this, typeof(LongRunningTaskService));
            StartService(intent);
        });
….

public class LongRunningTaskService : Service
{
    CancellationTokenSource _cts;
    …
    public override StartCommandResult OnStartCommand (Intent intent, StartCommandFlags flags, int startId)
    {
        _cts = new CancellationTokenSource ();

        Task.Run (() => {
            try {
                //INVOKE THE SHARED CODE
                var counter = new TaskCounter();
                counter.RunCounter(_cts.Token).Wait();
            }
            catch (OperationCanceledException) {
…..

The sample works perfectly when the app is launched with a UI. To start the service at boot, I added a broadcast receiver as below:

    [BroadcastReceiver(Enabled = true)]
    [IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
    public class BootReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            if (intent.Action == Intent.ActionBootCompleted)
            {

                Intent intent1 = new Intent(context, typeof(LongRunningTaskService));
                context.StartService(intent1);

            }
        }
    }

I have 2 questions now:

Q1. The first one does not relate to coding but debugging. As the code run when the OS boot, it does not connect to the development environment. To trace what’s happening, I use “toast”, and occasionally have to run it on UI thread with Device.BeginInvokeOnMainThread(() to display variables and progress. To have a more consistent way for debugging, at the end I have to use app property to store the values and retrieve it later with the UI to confirm if the code was executed.

Is there any easier way I can log the activities, no matter the task is running in the foreground / background and with/without UI? I am using Viual Studio in Windows 10.

Q2. The real issue I am facing is about the long running task. With the broadcast, the service was started successfully. However, the code “TaskCounter” inside the “Task.Run” has never run.

I then tried to replace the “Task.Run(() =>” with “new Thread(() =>”. TaskCounter still doesn’t run after Android boot. Interesting, it run immediately when the app is launched. It looks like that the thread is at a pending status and it is released after the app is launched. Using thread() also have another issue that I won’t be able to use cancellation token anymore.

In short, the code inside “Task.Run()” can be executed if the service is started when the app is launched with an UI. It cannot be run if the service is started by a broadcast receiver at OS boot.

Is there something I can do to fix the code using “Task.Run()”?

What would be the best way to start a long running task in the background when Android boot?

Thanks,

Nick

Answers

  • Mayur.1739Mayur.1739 USMember
    edited April 2017

    Hi, I'm new in Xamarin!

    Finding central solution for background service for Android, iOS and WP, which can be done few things by single code for all platform, i guess Xamarin is build for the same, but i didn't find any proper document/code snippet to archive such thing.

    Thanks,
    Mayur

    xamarin.forms

    background_service

Sign In or Register to comment.