Я нашел решение!
Мне пришлось использовать BackgroundServices от Xamarin.Forms.
Это решение для других:
В Android Основная активность:
void WireUpLongRunningTask()
{
MessagingCenter.Subscribe<StartTimerTaskMessage>(this, "StartTimerTaskMessage", message => {
var intent = new Intent(this, typeof(TimerService));
intent.PutExtra("time", message.Time);
StartService(intent);
});
MessagingCenter.Subscribe<StopTimerTaskMessage>(this, "StopTimerTaskMessage", message => {
var intent = new Intent(this, typeof(TimerService));
StopService(intent);
});
}
Метод вызова в OnCreate ();
Создание службы:
[Service]
public class TimerService : Service
{
CancellationTokenSource _cts;
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
_cts = new CancellationTokenSource();
Task.Run(() => {
try
{
var time = intent.GetIntExtra("time", 30);
var timer = new CountdownTimer();
timer.RunCounter(time, _cts.Token).Wait();
_cts.Cancel();
}
catch (Exception)
{
}
finally
{
if (_cts.IsCancellationRequested)
{
var message = new CancelledMessage();
Device.BeginInvokeOnMainThread(
() => MessagingCenter.Send(message, "CancelledMessage")
);
}
}
}, _cts.Token);
return StartCommandResult.Sticky;
}
public override void OnDestroy()
{
if (_cts != null)
{
_cts.Token.ThrowIfCancellationRequested();
_cts.Cancel();
}
base.OnDestroy();
}
}
IN PL C библиотека
ViewModel со счетчиком:
MessagingCenter.Subscribe<TimerMessage>(this, "TickedMessage", message => {
Device.BeginInvokeOnMainThread(() =>
{
Time = message.Time;
});
});
MessagingCenter.Subscribe<CancelledMessage>(this, "CancelledMessage", message => {
Device.BeginInvokeOnMainThread(() => {
Time = SelectedTime;
IsCounting = false;
});
});
internal void StartCountdown()
{
var message = new StartTimerTaskMessage(Time);
MessagingCenter.Send(message, "StartTimerTaskMessage");
}
internal static void StopCountdown()
{
var message = new StopTimerTaskMessage();
MessagingCenter.Send(message, "StopTimerTaskMessage");
}
{
public async Task RunCounter(int time, CancellationToken token)
{
await Task.Run(async () =>
{
for (int i = time; i >= 0; i--)
{
if (i != time)
{
await Task.Delay(1000).ConfigureAwait(false);
}
token.ThrowIfCancellationRequested();
var message = new TimerMessage(i);
Device.BeginInvokeOnMainThread(() => {
MessagingCenter.Send<TimerMessage>(message, "TickedMessage");
});
if (i == 0)
{
try
{
var duration = TimeSpan.FromSeconds(1);
Vibration.Vibrate(duration);
}
catch (FeatureNotSupportedException)
{
return;
}
}
}
}, token).ConfigureAwait(false);
}
}
и классы для обмена сообщениямиCenter
public class StopTimerTaskMessage
{
}
public class StartTimerTaskMessage
{
public int Time { get; set; }
public StartTimerTaskMessage(int time)
{
Time = time;
}
}
public class CancelledMessage
{
}
public class TimerMessage
{
public int Time { get; set; }
public TimerMessage(int time)
{
Time = time;
}
}