我希望我的进程内后台任务在应用程序被杀死时运行。这是为了不断跟踪用户的位置变化。不是地理围栏。那么,有没有办法在UWP中做到这一点?以下是我的代码,它会在应用程序被杀死时被杀死。在Android(Sticky后台服务)上只需几分钟即可完成此操作。 iOS版。使用带有进程外任务的WindowsRuntimeComponent是不可能的,因为我有很多代码可以从我的Xamarin Forms PCL中引用。 相当于我正在寻找的是Android Sticky Background Service。
private async void RegisterBackgroundTask()
{
var backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
if (backgroundAccessStatus == BackgroundAccessStatus.AllowedSubjectToSystemPolicy)
{
UnregisterTask(TaskName);
RegisterTask(TaskName);
}
}
private async void RegisterTask(string taskName)
{
BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder
{
Name = taskName,
};
var trigger = new ApplicationTrigger();
taskBuilder.SetTrigger(trigger);
var registration = taskBuilder.Register();
await trigger.RequestAsync();
}
protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
Debug.WriteLine("Background " + args.TaskInstance.Task.Name + " Starting...");
SendToast("Hi this is background Task");
//
// Query BackgroundWorkCost
// Guidance: If BackgroundWorkCost is high, then perform only the minimum amount
// of work in the background task and return immediately.
//
var cost = BackgroundWorkCost.CurrentBackgroundWorkCost;
var settings = ApplicationData.Current.LocalSettings;
settings.Values["BackgroundWorkCost"] = cost.ToString();
//
// Associate a cancellation handler with the background task.
//
args.TaskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
//
// Get the deferral object from the task instance, and take a reference to the taskInstance;
//
_deferral = args.TaskInstance.GetDeferral();
_taskInstance = args.TaskInstance;
_periodicTimer = ThreadPoolTimer.CreatePeriodicTimer(new TimerElapsedHandler(PeriodicTimerCallback), TimeSpan.FromSeconds(1));
}
private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
//
// Indicate that the background task is canceled.
//
_cancelRequested = true;
_cancelReason = reason;
SendToast("Background " + sender.Task.Name + " Cancel Requested...");
}
private void PeriodicTimerCallback(ThreadPoolTimer timer)
{
if ((_cancelRequested == false) && (_progress < 100))
{
_progress += 10;
_taskInstance.Progress = _progress;
SendToast("Timer Went Off!!");
}
else
{
_periodicTimer.Cancel();
var key = _taskInstance.Task.Name;
//
// Record that this background task ran.
//
String taskStatus = (_progress < 100) ? "Canceled with reason: " + _cancelReason.ToString() : "Completed";
var settings = ApplicationData.Current.LocalSettings;
settings.Values[key] = taskStatus;
Debug.WriteLine("Background " + _taskInstance.Task.Name + settings.Values[key]);
SendToast(taskStatus);
//
// Indicate that the background task has completed.
//
_deferral.Complete();
}
}
public static void SendToast(string message)
{
var template = ToastTemplateType.ToastText01;
var xml = ToastNotificationManager.GetTemplateContent(template);
var elements = xml.GetElementsByTagName("text");
var text = xml.CreateTextNode(message);
elements[0].AppendChild(text);
var toast = new ToastNotification(xml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}