How to create a foreground service for Android below Oreo 8.0?

ASolute_devASolute_dev Member ✭✭
edited January 16 in Xamarin.Forms

I have created a foreground service using the following code which is in the override method OnStartCommand inside a service class called DemoIntentService.cs.
`base.OnStartCommand(intent,flags,startId);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
Intent notificationIntent = new Intent(this, Java.Lang.Class.FromType(typeof(DemoIntentService)));
PendingIntent pendingIntent = PendingIntent.GetActivity(this, 0, notificationIntent, 0);

            Notification.Builder notificationBuilder = new Notification.Builder(this, "Example_Service_Channel")
            .SetSmallIcon(Resource.Drawable.AlertLightFrame)
            .SetContentTitle(Resources.GetString(Resource.String.DialogAlertTitle))
            .SetContentText(Resources.GetString(Resource.String.SelectTextMode))
            .SetContentIntent(pendingIntent);

            Notification notificationAfterBuild = notificationBuilder.Build();

            StartForeground(123, notificationAfterBuild);

            InitializeAlarmManager();
            setAlarm();
 }

return StartCommandResult.RedeliverIntent;

Obviously, the code above is only for Android Oreo 8.0 and above, the service works fine and the notification will not be cleared even though I close the app manually. (That's good, that's what I want !). However, when I use the above code to test on Android Nougat 7.1.1, it would not work.

Firstly, I have researched online they said there is no need to create a notification channel for Android below 8.0, so I remove the "Example_Service_Channel" which is the channelID. The app was deployed successfully, but the notification gone when I kill the app. Second thing, when I removed the channelID, Xamarin throw me a warning said "Notification.Builder.Builder(Context) is obsolete : deprecated" and the line has turn yellow. I ignore the error and deploy the app. The service did run as it is visible in the running service inside the developer options. But when I killed the app, the service and notification gone together. Is there any other way to create a foreground notification service that will never end for Android below 8.0? Thanks for any comment and idea.

Answers

  • JarvanJarvan Member, Xamarin Team Xamurai
    edited 7:12AM

    Try to use StartForegroundService to start the service instead.

    Application.Context.StartForegroundService(context,intent)
    

    Tutorial:
    https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/services/foreground-services#registering-as-a-foreground-service

  • ASolute_devASolute_dev Member ✭✭

    @Jarvan The StartForegroundService can only accept one parameter which is intent. So I put StartForegroundService(new Intent(this, typeof(DemoIntentService)) and it throw me the error Java.Lang.IncompatibleClassChangeError.

  • JarvanJarvan Member, Xamarin Team Xamurai
    edited 8:09AM

    Please check the code, I've tested a basic demo on Android 6.0 and it works fine.

    [Service]
    public class TimestampService : Service
    {
        bool isStarted;
        Handler handler;
        Action runnable;
    
        int count = 1001;
    
        public override void OnCreate()
        {
            base.OnCreate();
            handler = new Handler();
    
            runnable = new Action(() =>
            {
    
                if (isStarted)
                {
                    DispatchNotification("Notification running, ID:" + count);
                    handler.PostDelayed(runnable, 5000);
                }
            });
        }
    
        void RegisterForegroundService()
        {
            var notification = new Notification.Builder(this)
                .SetContentTitle(Resources.GetString(Resource.String.app_name))
                .SetContentText(Resources.GetString(Resource.String.notification_text))
                .SetSmallIcon(Resource.Drawable.ic_stat_name)
                .SetContentIntent(BuildIntentToShowMainActivity())
                .SetOngoing(true)
                .AddAction(BuildRestartTimerAction())
                .AddAction(BuildStopServiceAction())
                .Build();
    
    
            // Enlist this instance of the service as a foreground service
            StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notification);
        }
    
        void DispatchNotification(string message)
        {
            var intent = new Intent(this, typeof(MainActivity));
            intent.AddFlags(ActivityFlags.ClearTop);
            var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
    
            Notification.Builder notificationBuilder = new Notification.Builder(this)
                .SetSmallIcon(Resource.Drawable.ic_stat_name)
                .SetContentTitle("Alarm")
                .SetContentText(message)
                .SetAutoCancel(true)
                .SetContentIntent(pendingIntent);
    
            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.Notify(count++, notificationBuilder.Build());
        }
    }
    

Sign In or Register to comment.