I have a background service in Xamarin Android but the problem is I cannot use it as Async
method, it gives an error.
return type must be 'StartCommandResult' to match overridden member 'Service.OnStartCommand(Intent, StartCommandFlags, int)
The actual overridden method is void
but to use await I have to change it to async Task<T>
and then it produces the error. I searched everywhere but couldn't find a proper solution on this.
The code snippet for entire class is here:
{
[Service(IsolatedProcess = false, Enabled = true, Label = "BackgroundNotificationService")]
class BackgroundNotificationService : Service
{
static readonly string TAG = "X:" + typeof(BackgroundNotificationService).Name;
static readonly int TimerWait = 3600000;
Timer timer;
DateTime startTime;
bool isStarted = false;
public override IBinder OnBind(Intent intent)
{
return null;
}
public override void OnCreate()
{
base.OnCreate();
}
public override void OnDestroy()
{
timer.Dispose();
timer = null;
isStarted = false;
TimeSpan runtime = DateTime.UtcNow.Subtract(startTime);
Log.Info(TAG, $"Simple Service destroyed at {DateTime.UtcNow} after running for {runtime:c}.");
base.OnDestroy();
}
public override async Task<StartCommandResult> OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
StartCommandResult a = StartCommandResult.NotSticky;
Log.Debug(TAG, $"OnStartCommand called at {startTime}, flags={flags}, startid={startId}");
if (isStarted)
{
TimeSpan runtime = DateTime.UtcNow.Subtract(startTime);
Log.Info(TAG, $"This service was already started, it's been running for {runtime:c}.");
await UpdateData();
}
else
{
startTime = DateTime.UtcNow;
Log.Info(TAG, $"Starting the service, at {startTime}.");
timer = new Timer(HandleTimerCallback, startTime, 0, TimerWait);
isStarted = true;
await UpdateData();
}
return a;
}
void HandleTimerCallback(object state)
{
TimeSpan runTime = DateTime.UtcNow.Subtract(startTime);
Log.Info(TAG, $"This service has been running for {runTime:c} (since ${state}).");
}
}
}
As far as I know it should work because I am returning StartCommandResult
in override method. But if I am wrong then is there any method that I am missing? Maybe there is another way to do this and I don't know that.
Update and Solution
I ended up implementing another new IntentService
class to do all the background updating work while the above service only handles the calling of the IntentService
. The service is called with an explicit intent as any other service.
public class CustomIntentService : IntentService
{
public CustomIntentService() : base("CustomIntentService")
{
}
protected override async void OnHandleIntent(Intent intent)
{
// do your work
string servicename = typeof(CustomIntentService).Name;
Log.Info(servicename, "Starting background work");
try
{
await UpdateData();
}
catch (Exception ex)
{
Log.Info(servicename, "Background work returned with errors.\nError:" + ex.Message);
return;
}
Log.Info(servicename, "Background work completed without errors.");
}
}