question

AravapalliManikishore-1338 avatar image
0 Votes"
AravapalliManikishore-1338 asked AmyPeng1-MSFT edited

Foreground service is stopping when clear the cache in Android

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

dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

LeonLu-MSFT avatar image
0 Votes"
LeonLu-MSFT answered LeonLu-MSFT commented

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.



· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks for the reply @LeonLu-MSFT .

At least can we have fire ant event when the foreground service is stopped by Android system. So that we can restart the service?

0 Votes 0 ·
LeonLu-MSFT avatar image LeonLu-MSFT AravapalliManikishore-1338 ·

If you can fire an event(I cannot find these kind of event), but your application removed running task, you cannot restart service, and in Above code, I do not recommend you start service directly, Open the application, then start foreground service is a better choose.

0 Votes 0 ·