MAUI: Android: Foreground service is not running

Sreejith Sreenivasan 1,001 Reputation points
2025-04-30T15:32:33.49+00:00

I have integrated foreground service like below in my MAUI application.

MyForegroundService.cs under Platforms.Android

// MyForegroundService.cs
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using AndroidX.Core.App;
using System.Threading.Tasks;
using Resource = Microsoft.Maui.Resource;

[Service(ForegroundServiceType = ForegroundService.TypeLocation)]
public class MyForegroundService : Service
{
    private const int ServiceRunningNotificationId = 10000;
    private bool isRunning = true;

    public override void OnCreate()
    {
        base.OnCreate();
        System.Diagnostics.Debug.WriteLine("MyForegroundService: OnCreate");
        StartForeground(ServiceRunningNotificationId, BuildNotification());
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        System.Diagnostics.Debug.WriteLine("MyForegroundService: OnStartCommand");
        Task.Run(async () =>
        {
            try
            {
                while (isRunning)
                {
                    System.Diagnostics.Debug.WriteLine("MyForegroundService: Timer Tick");
                    await Task.Delay(10000);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("MyForegroundService crashed: " + ex.Message);
            }
        });
        return StartCommandResult.Sticky;
    }

    public override IBinder OnBind(Intent intent) => null;

    public override void OnDestroy()
    {
        isRunning = false;
        base.OnDestroy();
    }

    Notification BuildNotification()
    {
        var channelId = "foreground_service_channel";
        var channelName = "Background Timer";
        var manager = (NotificationManager)GetSystemService(NotificationService);

        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            var channel = new NotificationChannel(channelId, channelName, NotificationImportance.Default);
            manager.CreateNotificationChannel(channel);
        }

        var notification = new NotificationCompat.Builder(this, channelId)
            .SetContentTitle("Background Task Running")
            .SetContentText("Your timer is active every 10 seconds.")
            .SetSmallIcon(Resource.Drawable.ic_notification) // Replace with your icon
            .SetOngoing(true)
            .Build();

        return notification;
    }
}

BackgroundService.cs under Platforms.Android

using AlertBuddies.Service;
using Android.Content;
using Android.OS;
using Microsoft.Maui.Controls;
using Android.App;
using Application = Android.App.Application;
using Android.Content.PM;

[assembly: Dependency(typeof(AlertBuddies.Platforms.Android.BackgroundService))]
namespace AlertBuddies.Platforms.Android
{
    public class BackgroundService : IBackgroundService
    {
        public void Start()
        {
            System.Diagnostics.Debug.WriteLine("BackgroundService.Start() called");

            var context = Application.Context;

            var intent = new Intent(context, Java.Lang.Class.FromType(typeof(MyForegroundService)));

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
                context.StartForegroundService(intent);
            else
                context.StartService(intent);
        }

        public void Stop()
        {
            var context = Application.Context;
            var intent = new Intent(context, Java.Lang.Class.FromType(typeof(MyForegroundService)));
            context.StopService(intent);
        }
    }
}

Created an Interface IBackgroundService in Single Solution:

public interface IBackgroundService
{
    void Start();
    void Stop();
}

Added permission in AndroidManifest.xml

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

//added under application tag
<service
    android:name=".MyForegroundService"
    android:foregroundServiceType="location"
    android:enabled="true"
    android:exported="false" />

Finally I started the service from main project like below:

DependencyService.Get<IBackgroundService>()?.Start();

After running the project nothing is happening. I have added a debugger in BackgroundService and that is also not showing in output box.

System.Diagnostics.Debug.WriteLine("BackgroundService.Start() called");

what I am missing here?

My Requirement: I am running a timer in every 10 seconds and sending the location details to MQTT. But when the app is in background the timer stops. I want to run the timer and send the location details when the app is in foreground, background and even if the device is locked(app is in foreground or background). For implementing it I am trying to use the foreground services in android.

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
4,090 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Sreejith Sreenivasan 1,001 Reputation points
    2025-05-01T09:50:58.0766667+00:00

    I refereed this answer and created the foreground service like below:

    ForegroundServiceDemo.cs

    using Android.App;
    using Android.Content;
    using Android.OS;
    using AndroidX.Core.App; // Make sure you have Xamarin.AndroidX.Core NuGet package
    using Resource = Microsoft.Maui.Resource;
    
    namespace ProjectName.Platforms.Android
    {
        [Service(Exported = true, Name = "com.ProjectName.ForegroundServiceDemo")]
        public class ForegroundServiceDemo : Service
        {
            private const string NOTIFICATION_CHANNEL_ID = "1000";
            private const int NOTIFICATION_ID = 1;
            private const string NOTIFICATION_CHANNEL_NAME = "notification";
    
            public override void OnCreate()
            {
                base.OnCreate();
            }
    
            private void StartForegroundServiceCompat()
            {
                var notificationManager = GetSystemService(NotificationService) as NotificationManager;
    
                if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
                {
                    CreateNotificationChannel(notificationManager);
                }
    
                var notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                    .SetAutoCancel(false)
                    .SetOngoing(true)
                    .SetSmallIcon(Resource.Drawable.ic_notification) // make sure appicon exists
                    .SetContentTitle("Foreground Service")
                    .SetContentText("Foreground service is running");
    
    				if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
    				{
    				    StartForeground(NOTIFICATION_ID, notification, ForegroundService.TypeLocation);
    				}
    				else
    				{
    				    StartForeground(NOTIFICATION_ID, notification);
    				}
            }
    
            private void CreateNotificationChannel(NotificationManager notificationManager)
            {
                if (notificationManager == null) return;
    
                var channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME,
                    NotificationImportance.Low)
                {
                    Description = "Foreground service notification"
                };
    
                notificationManager.CreateNotificationChannel(channel);
            }
    
            public override IBinder OnBind(Intent intent)
            {
                return null; // Not a bound service
            }
    
            public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
            {
                StartForegroundServiceCompat();
                return StartCommandResult.NotSticky;
            }
        }
    }
    

    Calling it from a ContentPage:

    #if ANDROID
        using Android.Content;
        using Android.OS;
        using ProjectName.Platforms.Android; // Replace with the actual namespace containing ForegroundServiceDemo
    #endif
    
    #if ANDROID
        var intent = new Intent(Android.App.Application.Context, typeof(ForegroundServiceDemo));
        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            Android.App.Application.Context.StartForegroundService(intent);
        }
        else
        {
            Android.App.Application.Context.StartService(intent);
        }
    #endif
    
    

    AndroidManifest:

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
    <application 
        ---------
        <service 
            android:name="com.ProjectName.ForegroundServiceDemo"
            android:exported="true"
            android:foregroundServiceType="location" />
    </application>
    

    Important:

    Set the Name in the Service Attribute of class which must be the same android:name in AndroidManifest.xml.

    <service android:name="com.ProjectName.ForegroundServiceDemo"

    [Service(Exported = true, Name = "com.AlertBuddies.ForegroundServiceDemo")]

    Otherwise you will face below exception:

    Java.Lang.IllegalArgumentException: 'foregroundServiceType 0x00000008 is not a subset of foregroundServiceType attribute 0x00000000 in service element of manifest file'

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.