Start new Xamarin service with IsolatedProcess = true

Issue

I have two problems I would like to solve.

First when I set IsolatedProcess true OnStartCommand never trigger

Second problem is when I start my notification I get $projectname$ in my notification for some reason.

Here is my service code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace Comic.Viewer.Droid.Services
{
    [Service(IsolatedProcess  true, Label  "ComicViewer.ChapterNotifier.Service")]
    public class ChapterNotifier : Android.App.Service
    {
        public override IBinder OnBind(Intent intent)
        {
            throw new NotImplementedException();
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            var NotificationHelper  new NotificationHelper(MainActivity.CurrentActivity);


            intent.AddFlags(ActivityFlags.ClearTop);



            while (true)
            {
                var favs  DataStore.Db.GetFavorits(DataStore.AppSettings.CurrentUser.Id);

                foreach (var item in favs)
                {
                    var update  item.Translator  Modols.Translator.W_World_Translator ?
                                 DataStore.Wuxiaworld.SerieUpdates(item.Query) : (item.Translator  Modols.Translator.Boxnovel ?
                                 DataStore.Boxnovel.SerieUpdates(item.Query) : DataStore.NovelOver.SerieUpdates(item.Query));

                    var message  "";
                    if (update.NewChapters > 0)
                    {
                        message + $"{item.SerieName} Has {update.NewChapters} new chapter";

                        var NotificationId  Helper.GetRandomId();
                        var pendingIntent  PendingIntent.GetActivity(MainActivity.CurrentActivity, NotificationId, intent, PendingIntentFlags.Immutable);
                        var nb  NotificationHelper.GetNotification1(GetString(Resource.String.ApplicationName), message, pendingIntent);
                        if (Build.VERSION.SdkInt > BuildVersionCodes.O) StartForeground(NotificationId, nb.Build());
                        NotificationHelper.Notify(NotificationId, nb);
                    }
                }
                Thread.Sleep(18000000);
            }

        }
    }
}

and here is how I start my service

public void StartService()
        {

            var intent  new Intent(_context, typeof(ChapterNotifier));
            if (Build.VERSION.SdkInt > BuildVersionCodes.O)
                _context.StartForegroundService(intent);
            else
                _context.StartService(intent);
        }

Solution

To fix your issue with the Service freezing your App when starting it, you could do a couple of different things.

One of them being starting a Task instead of blocking the main thread.

So encapsulate your logic in a method like:

private async Task ReadFavorites(CancellationToken token  default)
{
    while(!token.IsCancellationRequested)
    {
        // your database and notification logic here...
        await Task.Delay(18000000, token);
    }
}

Then in OnStartCommand you can kick it off with:

_  Task.Run(() > ReadFavorites());

If you at some point want to stop this service and cancel the task, you can create a CancellationTokenSource and pass along a CancellationToken from that into the method:

var cts  new CancellationTokenSource();

var token  cts.Token;

Then pass along this token into the started task:

_  Task.Run(() > ReadFavorites(token), token);

This way you can call cts.Cancel() to cancel any tasks you don’t want to run anymore.

However, something like this would probably be better done by using the JobScheduler API in Android, since you are waiting for so long between your checks anyways. This way you won’t need a foreground service running all the time and showing a notification for it.

Answered By – Cheesebaron

Leave a Comment