简体   繁体   English

Windows Phone 8.1运行时-后台任务时间触发器

[英]Windows Phone 8.1 Runtime - Background Task Time Trigger

I am trying to trigger a background task towards the end time of a calendar entry. 我正在尝试在日历项的结束时间触发后台任务。 For eg if the calendar entry is 3pm - 5pm I want the background task to trigger at 5 pm and also I want to have another time trigger setup based on the upcoming calendar entry. 例如,如果日历条目是下午3点-下午5点,则我希望后台任务在下午5点触发,并且我还想根据即将到来的日历条目进行另一个时间触发设置。 At the end of the calendar entry time, I would fetch the details about the next calendar entry by querying the database and have the end time set as the next time trigger. 在日历输入时间结束时,我将通过查询数据库来获取有关下一个日历输入的详细信息,并将结束时间设置为下一次触发。 I am not sure on how to set the time as it going to be different every time. 我不确定如何设置时间,因为每次都会有所不同。 So far this is what I am up to: 到目前为止,这是我要做的:

//Background Task updated for Live Tile
        Windows.Storage.ApplicationDataContainer pageData = Windows.Storage.ApplicationData.Current.LocalSettings;
        pageData.Values["Testing"] = DateTime.Now.ToString();
        bool taskRegistered = false;
        string UpdateTile = "UpdateTile";
        // check if task is already registered
        foreach (var task in BackgroundTaskRegistration.AllTasks)
        {
            if (task.Value.Name == UpdateTile)
            {
                await (new MessageDialog("Task already registered")).ShowAsync();
                taskRegistered = true;
                break;
            }
        }            
        // register a new task
        var builder = new BackgroundTaskBuilder();
        builder.TaskEntryPoint = "TileUpdaterTask.UpdateTile";
        builder.SetTrigger(new TimeTrigger(30, false));
        // Windows Phone app must call this to use trigger types (see MSDN)
        await BackgroundExecutionManager.RequestAccessAsync();
        BackgroundTaskRegistration theTask = builder.Register();

Here is the Windows Runtime Component class to update the live tile: 这是用于更新实时磁贴的Windows运行时组件类:

public sealed class UpdateTile : IBackgroundTask //XamlRenderingBackgroundTask
{
    Windows.Storage.ApplicationDataContainer pageData = Windows.Storage.ApplicationData.Current.LocalSettings;
    public void Run(IBackgroundTaskInstance taskInstance)
    {
        BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
        ITileSquare150x150Text01 tileContent = TileContentFactory.CreateTileSquare150x150Text01();
        tileContent.TextHeading.Text = "Hello!";
        tileContent.TextBody1.Text = pageData.Values["Testing"].ToString();//"One";
        tileContent.TextBody2.Text = "Two";
        tileContent.TextBody3.Text = "Three";
        TileUpdateManager.CreateTileUpdaterForApplication().Update(tileContent.CreateNotification());
        _deferral.Complete();
    }
}

Please advise. 请指教。

Starting from the beginning: 从头开始:

  1. Create a New Windows Phone RT App Solution 创建新的Windows Phone RT App解决方案
  2. Add a new Windows RT Component Project to the Solution 将新的Windows RT组件项目添加到解决方案
  3. Put the below code in the main class in the Background Task. 将以下代码放在“后台任务”的主类中。 This code is designed to 'do something' approximately every n minutes (multiples of 30 minutes) (a little different to what you asked for, but you should get the idea). 这段代码旨在大约每n分钟(30分钟的倍数)“执行某项操作”(与您要求的内容稍有不同,但是您应该明白这一点)。 It reads two values from Local Settings - time stamp, and gap time in minutes. 它从“本地设置”中读取两个值-时间戳和以分钟为单位的间隔时间。 These values are set in the main app. 这些值在主应用程序中设置。

Code: 码:

using System;
using System.Globalization;
using Windows.ApplicationModel.Background;
using Windows.Storage;

namespace WindowsRuntimeComponent1
{
    public sealed class MyBackgroundClass : IBackgroundTask
    {
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            // Get a deferral, to prevent the task from closing prematurely if asynchronous code is still running.
            BackgroundTaskDeferral deferral = taskInstance.GetDeferral();

            // GET THIS INFO
            ApplicationDataContainer LocalSettings = ApplicationData.Current.LocalSettings;
            double elapsed = (DateTime.Now - Convert.ToDateTime(LocalSettings.Values["time stamp"], CultureInfo.InvariantCulture)).TotalMinutes;
            double remainingMinutes = (int) LocalSettings.Values["gap time minutes"] - elapsed;

            // SEE IF WE CAN DO IT NOW
            if (remainingMinutes > 15)
            {
                // do something, otherwise, wait for the next one
            }

            // FINISH UP
            deferral.Complete();
        }
    }
}
  1. In the main app go to the Package.appxmanifest file 在主应用中,转到Package.appxmanifest文件
  2. In the declarations tab add 'Background Task' of type 'Timer' 在“声明”选项卡中,添加“计时器”类型的“背景任务”
  3. The entrypoint should be 'WindowsRuntimeComponent1.MyBackgroundClass' 入口点应为“ WindowsRuntimeComponent1.MyBackgroundClass”
  4. In the Mainpage.xaml.cs for the main app, insert the below code into the constructor. 在主应用程序的Mainpage.xaml.cs中,将以下代码插入构造函数。

Code: 码:

// UNREGISTER THE EXISTING TASK IF IT EXISTS
var myTask = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault(iTask => iTask.Name == "DoSomethingBackground");
if (myTask != null) myTask.Unregister(true);

// REGISTER NEW TASK TO EXECUTE EVERY 30 MINUTES
BackgroundTaskBuilder myTaskBuilder = new BackgroundTaskBuilder() { Name = "DoSomethingBackground", TaskEntryPoint = "WindowsRuntimeComponent1.MyBackgroundClass" };
myTaskBuilder.SetTrigger(new TimeTrigger(30, false));
myTaskBuilder.Register();

// CREATE/RESET THESE VARIABLES
ApplicationData.Current.LocalSettings.Values["gap time minutes"] = 60;
ApplicationData.Current.LocalSettings.Values["time stamp"] = DateTime.Now.ToString(CultureInfo.InvariantCulture);
  1. Build the project for the Background task in debug mode and add the reference ...WindowsRuntimeComponent1\\bin\\Debug\\WindowsRuntimeComponent1.winmd to the main app. 在调试模式下为“后台”任务构建项目,然后将引用... WindowsRuntimeComponent1 \\ bin \\ Debug \\ WindowsRuntimeComponent1.winmd添加到主应用程序。
  2. Run the Main app in Debug . 在Debug中运行Main应用程序。 From Lifecycle Events in the top menu, select 'DoSomethingBackground' and run it. 在顶部菜单的“生命周期事件”中,选择“ DoSomethingBackground”并运行它。 Put a breakpoint in the MyBackgroundClass.cs to see if it execute correctly. 在MyBackgroundClass.cs中放置一个断点,以查看其是否正确执行。

You'll probably encounter the situation where when you try and run 'DoSomethingBackground' from Lifecycle Events the program just ends abruptly. 您可能会遇到一种情况,当您尝试从Lifecycle Events运行'DoSomethingBackground'时,程序突然结束。 If this happen, delete the bin and obj files for the main app, rebuild everything, and reattach the .winmd file. 如果发生这种情况,请删除主应用程序的bin和obj文件,重建所有内容,然后重新附加.winmd文件。 This should get it to work again. 这应该使其重新工作。 Also, it's good advice to use Debug.WriteLine() a lot in the Background Task, so when you execute it you can track in the output window what your code is up to. 另外,在后台任务中大量使用Debug.WriteLine()是一个很好的建议,因此当您执行它时,您可以在输出窗口中跟踪代码的作用。 Finally, be careful using datetime formats, and I'd recommend you use CultureInfo.InvariantCulture when storing dates, due to differing global formats. 最后,请小心使用日期时间格式,由于全局格式不同,建议您在存储日期时使用CultureInfo.InvariantCulture。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM