Foreground service is stopping when clear the cache in Android

Aravapalli Manikishore 21 Reputation points
2021-04-16T08:00:47.167+00:00

Hi Everyone,

I'm using Foreground service for fetching the location and is working when the App is in foreground / Background / Killed.
But, when I cleared cache, the Foreground service is getting killed too.

How can we prevent it to stopping even when the user cleared cache and how to restart the service after phone restarts.

I Googled it so much time but I didn't get any suitable solution. Almost all solutions are matching with my code.

Here is the code for Foreground service:

[Service]
public class AndroidLocationService : Service
{
    CancellationTokenSource _cts;
    public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        _cts = new CancellationTokenSource();

        Notification notif = DependencyService.Get<INotification>().ReturnNotif();
        StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notif);


        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += new ElapsedEventHandler(GetLocation);
        aTimer.Interval = 10000;
        aTimer.Enabled = true;


        return StartCommandResult.Sticky;
    }


    public async void GetLocation(object source, ElapsedEventArgs e)
    {
        try
        {
            var request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(1));
            var cts = new CancellationTokenSource();
            var location = await Geolocation.GetLocationAsync(request, cts.Token);

            if (location != null)
            {
                LocationTrack log = new LocationTrack();
                log.TrackDate = DateTime.Now;
                log.IsManual = false;
                log.Latitude = location.Latitude.ToString();
                log.Longitude = location.Longitude.ToString();
                log.IsSync = false;
                log.DayInOut = false;
                log.Image = "";
                log.InOut = 0;
                log.LocationName = "";

                LocationTrackBL trackBL = new LocationTrackBL();
                bool signout = trackBL.IsManualSignOutHappened();

                var currentloc = trackBL.SaveBackgroundLocationTrack(log);

                Device.BeginInvokeOnMainThread(() =>
                {
                    MessagingCenter.Send<object, string>(this, "CurrentLocation", currentloc + "$^$" + location.Latitude + ", " + location.Longitude);
                });

                Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
            }
        }
        catch (FeatureNotSupportedException fnsEx)
        {
            Utilities.Log("FG Destroyed 1");
            // Handle not supported on device exception
        }
        catch (FeatureNotEnabledException fneEx)
        {
            Utilities.Log("FG Destroyed2");
            // Handle not enabled on device exception
        }
        catch (PermissionException pEx)
        {
            Utilities.Log("FG Destroyed3");
            // Handle permission exception
        }
        catch (Exception ex)
        {
            Utilities.Log("FG Destroyed4");
            // Unable to get location
        }
    }

    public override void OnDestroy()
    {
        Utilities.Log("FG Destroyed");
        if (_cts != null)
        {
            _cts.Token.ThrowIfCancellationRequested();
            _cts.Cancel();
        }
        base.OnDestroy();
    }
}

Code for Notification

internal class NotificationHelper : INotification
{
    private static string foregroundChannelId = "9001";
    private static Context context = global::Android.App.Application.Context;


    public Notification ReturnNotif()
    {
        var intent = new Intent(context, typeof(SignInActivity));
        intent.AddFlags(ActivityFlags.SingleTop);
        intent.PutExtra("Title", "Message");

        var pendingIntent = PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.UpdateCurrent);

        var notifBuilder = new NotificationCompat.Builder(context, foregroundChannelId)
            .SetContentTitle("Location Track")
            .SetContentText("")
            .SetSmallIcon(Resource.Mipmap.readywire)
            .SetOngoing(true)
            .SetContentIntent(pendingIntent).SetVisibility(0);

        if (global::Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            NotificationChannel notificationChannel = new NotificationChannel(foregroundChannelId, "Title", NotificationImportance.High);
            notificationChannel.Importance = NotificationImportance.High;
            notificationChannel.EnableLights(true);
            notificationChannel.EnableVibration(true);
            notificationChannel.SetShowBadge(true);
            notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300 });

            var notifManager = context.GetSystemService(Context.NotificationService) as NotificationManager;
            if (notifManager != null)
            {
                notifBuilder.SetChannelId(foregroundChannelId);
                notifManager.CreateNotificationChannel(notificationChannel);
            }
        }

        return notifBuilder.Build();
    }
}

Code to Start the Service

    void StartService_ForFG()
    {
        Utilities.Log("Fired foreground service");
        if (!IsServiceRunning(typeof(AndroidLocationService)))
        {
            BL.LocationTrackBL trackBL = new BL.LocationTrackBL();
            bool isSignedIn = trackBL.IsManualSignInHappened();
            Utilities.Log("Is Signed In: " + isSignedIn.ToString());
            if (isSignedIn)
            {
                if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
                {
                   Application.Context.StartForegroundService(serviceIntent);
                }
                else
                {
                    Application.Context.StartService(serviceIntent);
                }
            }
        }
    }

Thanks in Advance

Developer technologies | .NET | Xamarin
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Anonymous
    2021-04-16T11:01:41.307+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    How can we prevent it to stopping even when the user cleared cache

    It cannot be achieved, due to the android system limitation, If user clear cache, your application will be removed from running task, so your foreground service will be stopped.

    how to restart the service after phone restarts.

    You can use broadcastrecevier to monitor the ActionBootCompleted, when your android device restart, this BroadcastReceiver will be receiver.

       [BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true)]  
       [IntentFilter(new string[] { Intent.ActionBootCompleted, Intent.ActionLockedBootCompleted, "android.intent.action.QUICKBOOT_POWERON", "com.htc.intent.action.QUICKBOOT_POWERON" })]  
       public class BootReceiver : BroadcastReceiver  
       {  
           public override void OnReceive(Context context, Intent intent)  
           {  
               //Do what you want here, for example, start a service.  
         
               Intent i = new Intent(context, typeof(SimpleService));  
               i.SetAction("My.Action");  
               context.StartService(i);  
           }  
       }  
    

    Do not forget to add <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> permission in your AndroidManifest.xml
    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


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.