Hi Everyone,
I'm pretty new to Xamarin Development.
And my work is to track the user's location for every X minutes between User Sign in and Sign out. So, I opted for the Foreground service. And in few of mobiles, it is running fine. But, In few mobiles the Foreground service is getting stopped automatically.
And have selected the Battery optimization as NO RESTRICTIONS. Still it is getting stopped automatically.
Any other conditions I can for this reason?
Here is my Foreground Service Code
[Service]
public class AndroidLocationService : Service
{
CancellationTokenSource _cts;
public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
System.Timers.Timer aTimer;
public static event EventHandler<string> onNotificationRaised;
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);
LocationTrackBL trackBL = new LocationTrackBL();
var freq = trackBL.GetTrackFrequency();
Utilities.Log("Foreground Created: " + freq);
aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(GetLocation);
aTimer.Interval = freq * 60000;
aTimer.Enabled = true;
aTimer.Start();
Utilities.Log("Timer Started");
return StartCommandResult.Sticky;
}
public async void GetLocation(object source, ElapsedEventArgs e)
{
Utilities.Log("Location Fired");
LocationTrackBL trackBL = new LocationTrackBL();
try
{
bool signout = trackBL.IsManualSignOutHappened_Valid();
if (signout)
{
aTimer.Enabled = false;
aTimer.Stop();
return;
}
bool signin = trackBL.IsManualSignInHappened_Valid();
var freq = trackBL.GetTrackFrequency();
DateTime tomorrow = DateTime.Now.Date.AddDays(1);
TimeSpan difference = tomorrow - DateTime.Now;
Utilities.Log("Time Difference: " + difference.TotalMinutes);
if (difference.TotalMinutes < freq || !signin)
{
Utilities.Log("Timer stopped!!" + freq + " ||" + signin.ToString());
aTimer.Enabled = false;
aTimer.Stop();
//stop the Foreground service
var actname = CrossCurrentActivity.Current.Activity.LocalClassName;
if (actname.Contains("SignInActivity"))
{
(CrossCurrentActivity.Current.Activity as SignInActivity).StopService_ForFG();
}
return;
}
bool gpsStatus = DependencyService.Get<ILocSettings>().isGpsAvailable();
if (!gpsStatus)
{
LocationTrack log = new LocationTrack();
log.TrackDate = DateTime.Now;
log.IsManual = false;
log.Latitude = "0.0";
log.Longitude = "0.0";
log.IsSync = false;
log.DayInOut = false;
log.Image = "";
log.InOut = 0;
log.LocationName = "";
log.LocationCode = "";
log.LocationName = "";
log.LocationType = 0;
log.OffsiteReason = "GPS is not Enabled.";
log.SignType = 0;
trackBL.SaveLocationTrack(log);
Utilities.Log("GPS not available");
onNotificationRaised?.Invoke(null, "Enable GPS to track the Location%SignIn");
return;
}
var request = new GeolocationRequest(GeolocationAccuracy.High, TimeSpan.FromSeconds(1));
var cts = new CancellationTokenSource();
var location = await Geolocation.GetLocationAsync(request, cts.Token);
if (location == null)
{
var locator = CrossGeolocator.Current;
var position = await locator.GetPositionAsync(TimeSpan.FromSeconds(5), null, true);
if (position != null)
{
location = new Xamarin.Essentials.Location();
location.Accuracy = position.Accuracy;
location.Latitude = position.Latitude;
location.Longitude = position.Longitude;
location.Altitude = position.Altitude;
}
}
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 = "";
var currentloc = trackBL.SaveBackgroundLocationTrack(log, location.Accuracy ?? 0);
trackBL.SyncPendingTracks();
Device.BeginInvokeOnMainThread(() =>
{
MessagingCenter.Send<object, string>(this, "CurrentLocation", currentloc + "$^$" + location.Latitude + ", " + location.Longitude);
});
Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
Utilities.Log("CurrentLocation" + currentloc);
}
else
{
LocationTrack log = new LocationTrack();
log.TrackDate = DateTime.Now;
log.IsManual = false;
log.Latitude = "0.0";
log.Longitude = "0.0";
log.IsSync = false;
log.DayInOut = false;
log.Image = "";
log.InOut = 0;
log.LocationName = "";
log.LocationCode = "";
log.LocationName = "";
log.LocationType = 0;
log.OffsiteReason = "GPS is not Enabled for Always.";
log.SignType = 0;
trackBL.SaveLocationTrack(log);
Utilities.Log("Location Null");
}
}
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)
{
LocationTrack log = new LocationTrack();
log.TrackDate = DateTime.Now;
log.IsManual = false;
log.Latitude = "0.0";
log.Longitude = "0.0";
log.IsSync = false;
log.DayInOut = false;
log.Image = "";
log.InOut = 0;
log.LocationName = "";
log.LocationCode = "";
log.LocationName = "";
log.LocationType = 0;
log.OffsiteReason = "GPS is not Enabled for Always.";
log.SignType = 0;
trackBL.SaveLocationTrack(log);
Utilities.Log("Location Null");
Utilities.Log("FG Destroyed4");
Utilities.Log(ex.ToString());
// Unable to get location
}
}
public override void OnDestroy()
{
Utilities.Log("FG Destroyed");
if (_cts != null)
{
_cts.Token.ThrowIfCancellationRequested();
_cts.Cancel();
}
base.OnDestroy();
}
}
Is there any way how to check whether the Service is running or not?
Thanks in Advance.